/*Header file of the PStep_Adder class

Implementation can be found in PStep_Adder.cpp

This class represents a function for adding p-steps created by backtracking labels.

This file also includes derived classes of PStep_Adder.

NOTE: PStep are added at the fornt of the list.

*/

#ifndef _PSTEP_ADDER_H
#define _PSTEP_ADDER_H

#include "PStep_FinalLabel.h"
#include "PStep_AlgorithmMembers.h"
#include <forward_list>
#include "PStep_CG1_DSSRPricingProblemProgress.h"

//Class used to represent a function for adding p-steps created by backtracking labels.
class PStep_Adder{
public:

	//Algorithm members
	PStep_AlgorithmMembers& AlgorithmMembers;

	//Decremental state-space relaxation members:
	//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

	//Indicator indicating whether decremental state space relaxation should be applied
	bool* ApplyDSSR;

	//Pointer to indicator indicating whether it is necessary to rerun the pricing algorithms.
	bool* RerunRequired;

	//Constructor functions
	//------------------------------------------------------------------------------------

	//Basic constructor
	PStep_Adder(PStep_AlgorithmMembers& InitAlgorithmMembers)
		:AlgorithmMembers(InitAlgorithmMembers)
	{};

	//Add p-steps function
	//------------------------------------------------------------------------------------

	//Create p-steps by backtracking labels in FinalLabels and adding them to
	//the front of AlgorithmMembers.PSteps and AlgorithmMembers.CurrentPSteps.
	virtual void Add(std::forward_list<PStep_FinalLabel>& FinalLabels)=0;

	//Create p-steps by backtracking labels found in CandidateLabels of in AlgorithmMembers.PricingProblems
	//and adding them to the front of AlgorithmMembers.PSteps and AlgorithmMembers.CurrentPSteps.
	//It is particularly designed for the case in which multiple pricing problems are considered.
	virtual void AddMultiplePPCandidateLabels(std::forward_list<PStep_PricingProblem*> &SolvedPricingProblems) = 0;

	//Add p-steps in the list to the front of AlgorithmMembers.PSteps
	//and AlgorithmMembers.CurrentPSteps.
	virtual void Add(std::forward_list<PStep> &PStepLists) = 0;

	//Add all p-steps to the front of AlgorithmMembers.PSteps and
	//AlgorithmMembers.CurrentPSteps.
	//It is particularly designed for the case in which multiple pricing problems are considered.
	virtual void AddMultiplePPCandidatePSteps(std::forward_list<PStep_PricingProblem*> &SolvedPricingProblems) = 0;

	//Create p-steps by merging and backtracking the CandidateMergeLabels of the pricing problems in the
	//list SolvedPricingProblems. Add all these p-steps to the front of AlgorithmMembers.PSteps and
	//AlgorithmMembers.CurrentPSteps.
	//It is particularly designed for the case in which multiple pricing problems are considered.
	virtual void AddMultiplePPCandidateMergeLabels(std::forward_list<PStep_PricingProblem*> &SolvedPricingProblems) = 0;

	//Backtrack function:
	//------------------------------------------------------------------------------------

	//Backtrack FinalLabel and add the resulting pstep to AlgorithmMembers.PSteps
	//and AlgorithmMembers.CurrentPSteps.
	void Backtrack(PStep_FinalLabel& FinalLabel);

	//Backtrack and merge MergeLabel and add the resulting pstep to AlgorithmMembers.PSteps
	//and AlgorithmMembers.CurrentPSteps.
	void Backtrack(PStep_MergeLabel& MergeLabel);

};

//Class used to add all p-steps.
class PStep_AllPStepsAdder : public PStep_Adder{
public:

	//Constructor functions
	//------------------------------------------------------------------------------------

	//Basic constructor
	PStep_AllPStepsAdder(PStep_AlgorithmMembers& InitAlgorithmMembers)
		: PStep_Adder(InitAlgorithmMembers)
	{};

	//Add p-steps function
	//------------------------------------------------------------------------------------

	//Create p-steps by backtracking every label in FinalLabels and add ALL of them to
	//the front of AlgorithmMembers.PSteps and AlgorithmMembers.CurrentPSteps.
	virtual void Add(std::forward_list<PStep_FinalLabel>& FinalLabels);

	//Create p-steps by backtracking labels found in CandidateLabels of in AlgorithmMembers.PricingProblems
	//and adding them to the front of AlgorithmMembers.PSteps and AlgorithmMembers.CurrentPSteps.
	//It is particularly designed for the case in which multiple pricing problems are considered.
	virtual void AddMultiplePPCandidateLabels(std::forward_list<PStep_PricingProblem*> &SolvedPricingProblems);

	//Add All p-steps in the list to the front of AlgorithmMembers.PSteps
	//and AlgorithmMembers.CurrentPSteps.
	virtual void Add(std::forward_list<PStep> &PStepList);

	//Add All p-steps to the front of AlgorithmMembers.PSteps and
	//AlgorithmMembers.CurrentPSteps.
	//It is particularly designed for the case in which multiple pricing problems are considered.
	virtual void AddMultiplePPCandidatePSteps(std::forward_list<PStep_PricingProblem*> &SolvedPricingProblems);

	//Create p-steps by merging and backtracking every label in MergeLabels and add ALL of them to
	//the front of AlgorithmMembers.PSteps and AlgorithmMembers.CurrentPSteps.
	virtual void Add(std::forward_list<PStep_MergeLabel>& MergeLabels);

	//Create p-steps by merging and backtracking the CandidateMergeLabels of the pricing problems in the
	//list SolvedPricingProblems. Add all these p-steps to the front of AlgorithmMembers.PSteps and
	//AlgorithmMembers.CurrentPSteps.
	//It is particularly designed for the case in which multiple pricing problems are considered.
	virtual void AddMultiplePPCandidateMergeLabels(std::forward_list<PStep_PricingProblem*> &SolvedPricingProblems);

	//Decremental state space relaxation functions:
	//------------------------------------------------------------------------------------

	//Create p-steps by backtracking labels found in CandidateLabels of in AlgorithmMembers.PricingProblems.
	//For these p-steps it is checked whether they are feasible ng-paths.
	//If not, the neighborhoods of the corresponding pricing problem are updated.
	//When only negative reduced cost p-steps which are not feasible ng-paths are found.
	//RerunRequired is set to true. Otherwise (so if at least one negative reduced cost feasible
	//ng-path is found, or no CandidateLabels were generated), it is set to false.
	void DSSRAddMultiplePPCandidateLabels(std::forward_list<PStep_PricingProblem*> &SolvedPricingProblems);

	//Create p-steps by merging and backtracking labels found in CandidateMergeLabels of
	//AlgorithmMembers.PricingProblems.
	//For these p-steps it is checked whether they are feasible ng-paths.
	//If not, the neighborhoods of the corresponding pricing problem are updated.
	//When only negative reduced cost p-steps which are not feasible ng-paths are found.
	//RerunRequired is set to true. Otherwise (so if at least one negative reduced cost feasible
	//ng-path is found, or no CandidateMergeLabels were generated), it is set to false.
	void DSSRAddMultiplePPCandidateMergeLabels(std::forward_list<PStep_PricingProblem*> &SolvedPricingProblems);

};

#endif