/*Header file of the PStep_ColumnManager class

This file also includes derived classes of PStep_ColumnManager.

Implementation of PStep_ColumnManagerX can be found in PStep_ColumnManagerX.cpp.

This class represents a column manager.

*/

#ifndef _PSTEP_PSTEPCOLUMNMANAGER_H
#define _PSTEP_PSTEPCOLUMNMANAGER_H

#include "PStep_AlgorithmMembers.h"
#include "PStep_ColumnGenerator.h"
#include <ilcplex/ilocplex.h>
#include <set>

//Class used to represent a column manager.
//No column management is applied.
class PStep_ColumnManager{

public:

	//Remove functions
	//------------------------------------------------------------------------------------

	//Remove p-steps included in x from the formulation in PStepLP.
	//Only CurrentPSteps are considered from (and including) FirstCurrentPStep up to (and excluding) LastCurrentPStep.
	//ReducedCosts[CurrentPStepsxIndex[i]] should correspond to CurrentPSteps[i] and x[CurrentPSteps[i]].
	virtual void Remove(std::list<std::list<PStep>::iterator>::iterator FirstCurrentPStep, std::list<std::list<PStep>::iterator>::iterator LastCurrentPStep, IloNumVarArray& x, IloNumArray& ReducedCosts, IloEnv& env){};

	//Search Shortlist functions
	//------------------------------------------------------------------------------------

	//Search the shortlist for p-steps with negative reduced costs.
	//It outputs true if negative reduced cost p-steps have been identified.
	//NOTE: The column generator is not really needed, but that is where currently the duals are stored.
	//		At the time of coding this I did not feel like reorganizing.
	virtual bool SearchShortList(PStep_ColumnGenerator& CurrentColumnGenerator){ return false; };

};

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

//Class used to represent a column manager.
//When removing, all columns with reduced costs higher than a threshold are removed.
class PStep_ColumnManager1 : public PStep_ColumnManager{

protected:
	//Algorithm members
	PStep_AlgorithmMembers& AlgorithmMembers;

	//Threshold of reduced costs for removal of a p-step
	double Threshold;

	//Constructor functions
	//------------------------------------------------------------------------------------
public:
	//Basic constructor
	PStep_ColumnManager1(PStep_AlgorithmMembers& InitAlgorithmMembers)
		:AlgorithmMembers(InitAlgorithmMembers), Threshold(InitAlgorithmMembers.AlgorithmSettings.CMThreshold)
	{};

	//Remove functions
	//------------------------------------------------------------------------------------

	//Remove p-steps included in x from the formulation in PStepLP.
	//All columns with reduced costs higher than Threshold are removed.
	//Only CurrentPSteps are considered from (and including) FirstCurrentPStep up to (and excluding) LastCurrentPStep.
	//ReducedCosts[CurrentPStepsxIndex[i]] should correspond to CurrentPSteps[i] and x[CurrentPSteps[i]].
	virtual void Remove(std::list<std::list<PStep>::iterator>::iterator FirstCurrentPStep, std::list<std::list<PStep>::iterator>::iterator LastCurrentPStep, IloNumVarArray& x, IloNumArray& ReducedCosts, IloEnv& env);

};

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

//Class used to represent a column manager.
//When removing, all columns with reduced costs higher than a threshold are removed.
//When searching the short list, all p-steps with negative reduced costs are added.
class PStep_ColumnManager2 : public PStep_ColumnManager1{

protected:

	//Pointers to duals
	double* Lambda;
	double* Mu;
	double* Nu;
	double* Pi;

	//Limit on the remaining number of columns when removing (when equal or less than this limit, no more columns are removed.)
	int NumberOfColumnsLimit;

	//Constructor functions
	//------------------------------------------------------------------------------------
public:
	//Basic constructor
	PStep_ColumnManager2(PStep_AlgorithmMembers& InitAlgorithmMembers)
		:PStep_ColumnManager1(InitAlgorithmMembers), NumberOfColumnsLimit(AlgorithmMembers.AlgorithmSettings.CMNumberOfColumnsLimit)
	{};

	//Remove functions
	//------------------------------------------------------------------------------------

	//Remove p-steps included in x from the formulation in PStepLP.
	//All columns with reduced costs higher than Threshold are removed, as long as there are more than NumberOfColumnsLimit columns.
	//Only CurrentPSteps are considered from (and including) FirstCurrentPStep up to (and excluding) LastCurrentPStep.
	//ReducedCosts[CurrentPStepsxIndex[i]] should correspond to CurrentPSteps[i] and x[CurrentPSteps[i]].
	virtual void Remove(std::list<std::list<PStep>::iterator>::iterator FirstCurrentPStep, std::list<std::list<PStep>::iterator>::iterator LastCurrentPStep, IloNumVarArray& x, IloNumArray& ReducedCosts, IloEnv& env);

	//Search Shortlist functions
	//------------------------------------------------------------------------------------

	//Search the shortlist for p-steps with negative reduced costs.
	//All p-steps with negative reduced costs are added.
	//It outputs true if negative reduced cost p-steps have been identified,
	//NOTE: The column generator is not really needed, but that is where currently the duals are stored.
	//		At the time of coding this I did not feel like reorganizing.
	virtual bool SearchShortList(PStep_ColumnGenerator& CurrentColumnGenerator);

protected:
	//Compute the reduced costs of a p-step.
	double ComputeReducedCosts(PStep& CurrentPStep);

};

//Class used by column manager 3 to sort p-steps.
//It contains a pointer to a p-step, pointer to the index in the formulation, and the corresponding reduced costs.
class PStepReducedCostTriple{
public:
	std::list<std::list<PStep>::iterator>::iterator ThisPStep;
	std::list<int>::iterator xIndex;
	double ReducedCosts;
	PStepReducedCostTriple(std::list<std::list<PStep>::iterator>::iterator& NewThisPStep, std::list<int>::iterator& NewxIndex, double NewReducedCosts)
		:ThisPStep(NewThisPStep), xIndex(NewxIndex), ReducedCosts(NewReducedCosts)
	{};
	bool operator<(const PStepReducedCostTriple &OtherTriple) const { return ReducedCosts < OtherTriple.ReducedCosts; }
};

//Class used to represent a column manager.
//When removing, all columns are sorted in terms of reduced costs and the CMNumberOfColumnsLimit
//columns with the lowest reduced costs are maintained. All other columns with
//positive reduced costs are removed.
//When searching the short list, all p-steps with negative reduced costs are added.
class PStep_ColumnManager3 : public PStep_ColumnManager2{

	//Constructor functions
	//------------------------------------------------------------------------------------
public:
	//Basic constructor
	PStep_ColumnManager3(PStep_AlgorithmMembers& InitAlgorithmMembers)
		:PStep_ColumnManager2(InitAlgorithmMembers)
	{};

	//Remove functions
	//------------------------------------------------------------------------------------

	//Remove p-steps included in x from the formulation in PStepLP.
	//All columns are sorted in terms of reduced costs and the CMNumberOfColumnsLimit
	//columns with the lowest reduced costs are maintained. All other columns with
	//positive reduced costs are removed.
	//Only CurrentPSteps are considered from (and including) FirstCurrentPStep up to (and excluding) LastCurrentPStep.
	//ReducedCosts[CurrentPStepsxIndex[i]] should correspond to CurrentPSteps[i] and x[CurrentPSteps[i]].
	virtual void Remove(std::list<std::list<PStep>::iterator>::iterator FirstCurrentPStep, std::list<std::list<PStep>::iterator>::iterator LastCurrentPStep, IloNumVarArray& x, IloNumArray& ReducedCosts, IloEnv& env);

};

#endif