//---------------------------------------------------------------------------

#ifndef HeurCoverH
#define HeurCoverH
//---------------------------------------------------------------------------

class HeurCover {
	private:
		const CovMatrix *CM;
		list<unsigned int> *solution;

		unsigned int rownum;			// # current of rows
		unsigned int colnum;			// # current of columns
		list<unsigned int> rows;		// list of current rows
		list<unsigned int> columns;		// list of current columns

			// for LCMC, MCLC, Contrib
		bool autocontrib;					// true, if contributions should be always recomputed (by adding/removing columns/rows)
		vector<unsigned int> colcontrib;	// column contributions (# of rows covered by the column)
		vector<unsigned int> rowcontrib;	// row contributions (# of columns covering the row)
		bool validcontrib;					// are the contributions valid?
		bool considercost;					// column costs are considered

		vector<unsigned int *> colptrs;
		vector<unsigned int *> colptrs2;

		bool ColDominanceRemoval(void);		// solves the column dominance
		bool RowDominanceRemoval(void);		// solves the row dominance
		bool Essentials(void);	// moves essential columns to the solution
		list<unsigned int>::iterator MoveToSolution( list<unsigned int>::iterator col_it );
		list<unsigned int>::iterator DeleteRow( list<unsigned int>::iterator row_it );
		list<unsigned int>::iterator DeleteColumn( list<unsigned int>::iterator col_it );
		void ComputeContributions(void);   // computes row and column contributions for the whole matrix
		void RecomputeContributions(void); // Computes row and column contributions for active (non-removed) rows and columns only

			// Column selection heuristics
		void Random_SelectColumn(void);			// randomly select one column
		void LCMC_SelectColumn(void);			// select one column by the LCMC heuristic
		void MCLC_SelectColumn(void);			// select one column by the MCLC heuristic
		void Contrib_SelectColumn(void);		// select one column by the combined contribution heuristic

	public:
		HeurCover( const CovMatrix *_matrix );
		//~HeurCover(void);

		list<unsigned int> *Run(void);			// Returns a pointer to a list of selected columns. !! Must be manually deallocated afterwar 

};

#endif
