/*Implementation of PStep_ColumnGenerator.h

It contains the member functions of PStep_ColumnGenerator14

*/

#include "PStep_ColumnGenerator.h"

//PStep_ColumnGenerator14:
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

//Generate columns
//------------------------------------------------------------------------------------

//The same as column generator 1, but using bi-directional labeling.
void PStep_ColumnGenerator14::GenerateColumns(){

	GenerateColumns14();

}

//The same as column generator 1, but using bi-directional labeling.
void PStep_ColumnGenerator14::GenerateColumns14(){

	//Initialization:
	//*****************************************************************************************

	//Obtain p
	short int p = AlgorithmMembers.AlgorithmSettings.p;
	//Obtain Tolerance
	double Tolerance = AlgorithmMembers.Tolerance;
	//Obtain MaxMergeLabels;
	int MaxMergeLabels = AlgorithmMembers.AlgorithmSettings.MaxMergeLabels;
	//Obtain indicator indicating whether ng-path relaxation is used
	bool UseNGPathRelaxation = AlgorithmMembers.AlgorithmSettings.UseNGPathRelaxation;
	//Obtain neighbourhoods
	std::vector<std::vector<short int >>& Neighbourhoods = AlgorithmMembers.Neighbourhoods;
	//Obtain NotInNeighbourhood
	bool** (&NotInNeighbourhood) = AlgorithmMembers.NotInNeighbourhood;
	//Obtain pricing problems
	PStep_PricingProblem** (&PricingProblems) = AlgorithmMembers.PricingProblems;
	//Obtain lists of relevant pricing problems
	std::list<PStep_PricingProblem*> &RelevantDepotCustomerPricingProblems = AlgorithmMembers.RelevantDepotCustomerPricingProblems;
	std::list<PStep_PricingProblem*> &RelevantCustomerDepotPricingProblems = AlgorithmMembers.RelevantCustomerDepotPricingProblems;
	std::list<PStep_PricingProblem*> &RelevantCustomerCustomerPricingProblems = AlgorithmMembers.RelevantCustomerCustomerPricingProblems;

	//SetReducedCostTemplate
	SetReducedCostTemplate();

	//Initialize list of bi-directional layered labeling algorithms
	std::forward_list<PStep_BiDirectionalLayeredLabelingAlgorithm> LabelingAlgorithms;

	//Initialize list of solved pricing problems
	//This list gets updated after a succesful run of PStep_BiDirectionalLayeredLabelingAlgorithm
	std::forward_list<PStep_PricingProblem*> SolvedPricingProblems;

	//Initialize reachability setters:
	//********************************
	//Initialize Container for PStep_ReachabilitySetter
	std::forward_list<PStep_ReachabilitySetter> ReachabilitySetters;
	//Initialize Container for PStep_NGReachabilitySetter
	std::forward_list<PStep_NGReachabilitySetter> NGReachabilitySetters;
	//Initialize pointer to a current reachability setter
	PStep_ReachabilitySetter* CurrentReachabilitySetter;

	//Initialize extenders:
	//*********************
	//Initialize Container for PStep_StandardExtenders
	std::forward_list<PStep_StandardExtender> StandardExtenders;
	//Initialize bogus PStep_FinalExtender
	PStep_FinalExtender BogusFinalExtender = PStep_FinalExtender(0, 0, 0);

	//Initialize dominators:
	//**********************
	//Initialize Dominator
	PStep_ReachabilityDominator Dominator(Tolerance);
	//Initialize load dominator
	PStep_LoadDominator LoadDominator(Tolerance);
	//Initialize ng-path dominator
	PStep_NGReachabilityDominator NGDominator(Tolerance, Neighbourhoods);
	//Initialize pointer to the current dominator
	PStep_Dominator* CurrentDominator;
	//Check which dominator should be used
	if (DoNotCheckReachability){
		CurrentDominator = &LoadDominator;
	}
	else if (UseNGPathRelaxation){
		CurrentDominator = &NGDominator;
	}
	else{
		CurrentDominator = &Dominator;
	}
	//Initialize Container for PStep_NGReachabilityDominator, to be used
	//if dynamic state space relaxation is applied.
	std::forward_list<PStep_NGReachabilityDominator> DSSRNGReachabilityDominators;

	//Initialize mergers:
	//*******************
	//Initialize Container for PStep_ZeroLoadMergers
	std::forward_list<PStep_ZeroLoadMerger> ZeroLoadMergers;
	//Initialize Container for PStep_MaxLoadMerger
	std::forward_list<PStep_MaxLoadMerger> MaxLoadMergers;
	//Initialize Container for PStep_NGZeroLoadMergers
	std::forward_list<PStep_NGZeroLoadMerger> NGZeroLoadMergers;
	//Initialize Container for PStep_NGMaxLoadMerger
	std::forward_list<PStep_NGMaxLoadMerger> NGMaxLoadMergers;
	//Initialize pointer to the current merger
	PStep_Merger* CurrentMerger;

	//Initialize algorithm for the pricing problem from depot to depot:
	//*****************************************************************
	//Check whether p is not 1, in which case this pricing problem is nonsense.
	if (p > 1){

		//Obtain pricing problem
		PStep_PricingProblem &CurrentPricingProblem = PricingProblems[0][0];
		
		//Check whether according to DSSR this pricing problem is redundant
		if (!(ApplyDSSR && !(CurrentPricingProblem.RerunRequired))){

			//Obtain demand
			double* Demand = CurrentPricingProblem.Demand;
			//Obtain capacity plus tolerance
			double CapacityPlusTolerance = CurrentPricingProblem.Capacity + Tolerance;

			//Set reduced costs
			SetReducedCosts(CurrentPricingProblem, 0, 0);

			//Check whether dynamic state-space relaxation is applied
			if (ApplyDSSR){
				//Create Reachability setter
				NGReachabilitySetters.emplace_front(Demand, CapacityPlusTolerance, CurrentPricingProblem.CurrentDSSRNotInNeighbourhood);
				//Set current reachability setter
				CurrentReachabilitySetter = &(NGReachabilitySetters.front());
				//Check whether reachability should be checked
				if (!DoNotCheckReachability){
					//Create dominator
					DSSRNGReachabilityDominators.emplace_front(Tolerance, CurrentPricingProblem.CurrentDSSRNeighbourhoods);
					//Set current dominator
					CurrentDominator = &(DSSRNGReachabilityDominators.front());
				}
				//Create merger
				NGZeroLoadMergers.emplace_front(CurrentPricingProblem.Capacity, CapacityPlusTolerance, CurrentPricingProblem.CandidateMergeLabels, CurrentPricingProblem.CurrentDSSRNotInNeighbourhood);
				//Set current merger
				CurrentMerger = &(NGZeroLoadMergers.front());
			}
			else if (UseNGPathRelaxation){
				//Create Reachability setter
				NGReachabilitySetters.emplace_front(Demand, CapacityPlusTolerance, NotInNeighbourhood);
				//Set current reachability setter
				CurrentReachabilitySetter = &(NGReachabilitySetters.front());
				//Create merger
				NGZeroLoadMergers.emplace_front(CurrentPricingProblem.Capacity, CapacityPlusTolerance, CurrentPricingProblem.CandidateMergeLabels, NotInNeighbourhood);
				//Set current merger
				CurrentMerger = &(NGZeroLoadMergers.front());
			}
			else{
				//Create Reachability setter
				ReachabilitySetters.emplace_front(Demand, CapacityPlusTolerance);
				//Set current reachability setter
				CurrentReachabilitySetter = &(ReachabilitySetters.front());
				//Create merger
				ZeroLoadMergers.emplace_front(CurrentPricingProblem.Capacity, CapacityPlusTolerance, CurrentPricingProblem.CandidateMergeLabels);
				//Set current merger
				CurrentMerger = &(ZeroLoadMergers.front());
			}

			//Create standard extender
			StandardExtenders.emplace_front(Demand, CurrentPricingProblem.ReducedArcCosts, *CurrentReachabilitySetter);

			//Create Layered Labeling Algorithm
			LabelingAlgorithms.emplace_front(CurrentPricingProblem, StandardExtenders.front(), BogusFinalExtender, *CurrentDominator, *CurrentMerger, UseLimitedArcs, MaxMergeLabels, SolvedPricingProblems);
		}
	}
	
	//Initialize algorithm for the pricing problems from depot to customers:
	//**********************************************************************
	//Go over all relevant pricing problems from depot to customer
	for (auto RelevantPricingProblem = RelevantDepotCustomerPricingProblems.begin(); RelevantPricingProblem != RelevantDepotCustomerPricingProblems.end(); ++RelevantPricingProblem){

		//Obtain current pricing problem
		PStep_PricingProblem &CurrentPricingProblem = (**RelevantPricingProblem);
		//Check whether according to DSSR this pricing problem is redundant
		if (!(ApplyDSSR && !(CurrentPricingProblem.RerunRequired))){

			//Obtain current sink
			short int jMinusOne = CurrentPricingProblem.Sink - 1;
			//Obtain demand
			double* Demand = CurrentPricingProblem.Demand;
			//Obtain capacity plus tolerance
			double CapacityPlusTolerance = CurrentPricingProblem.Capacity + Tolerance;

			//Set reduced costs
			double ReducedCostConstant = Lambda[jMinusOne] + Mu[jMinusOne];
			SetReducedCosts(CurrentPricingProblem, Nu[jMinusOne], ReducedCostConstant);

			//Check which reachability setter should be used
			if (ApplyDSSR && CurrentPricingProblem.RerunRequired){
				//Create Reachability setter
				NGReachabilitySetters.emplace_front(Demand, CapacityPlusTolerance, CurrentPricingProblem.CurrentDSSRNotInNeighbourhood);
				//Set current reachability setter
				CurrentReachabilitySetter = &(NGReachabilitySetters.front());
				//Check whether reachability should be checked
				if (!DoNotCheckReachability){
					//Create dominator
					DSSRNGReachabilityDominators.emplace_front(Tolerance, CurrentPricingProblem.CurrentDSSRNeighbourhoods);
					//Set current dominator
					CurrentDominator = &(DSSRNGReachabilityDominators.front());
				}
				//Create merger
				NGZeroLoadMergers.emplace_front(CurrentPricingProblem.Capacity, CapacityPlusTolerance, CurrentPricingProblem.CandidateMergeLabels, CurrentPricingProblem.CurrentDSSRNotInNeighbourhood);
				//Set current merger
				CurrentMerger = &(NGZeroLoadMergers.front());
			}
			else if (UseNGPathRelaxation){
				//Create NGReachabilitySetter
				NGReachabilitySetters.emplace_front(Demand, CapacityPlusTolerance, NotInNeighbourhood);
				//Set current reachability setter
				CurrentReachabilitySetter = &(NGReachabilitySetters.front());
				//Create merger
				NGZeroLoadMergers.emplace_front(CurrentPricingProblem.Capacity, CapacityPlusTolerance, CurrentPricingProblem.CandidateMergeLabels, NotInNeighbourhood);
				//Set current merger
				CurrentMerger = &(NGZeroLoadMergers.front());
			}
			else{
				//Create ReachabilitySetter
				ReachabilitySetters.emplace_front(Demand, CapacityPlusTolerance);
				//Set current reachability setter
				CurrentReachabilitySetter = &(ReachabilitySetters.front());
				//Create merger
				ZeroLoadMergers.emplace_front(CurrentPricingProblem.Capacity, CapacityPlusTolerance, CurrentPricingProblem.CandidateMergeLabels);
				//Set current merger
				CurrentMerger = &(ZeroLoadMergers.front());
			}
			//Create standard extender
			StandardExtenders.emplace_front(Demand, CurrentPricingProblem.ReducedArcCosts, *CurrentReachabilitySetter);
			
			//Create Layered Labeling Algorithm
			LabelingAlgorithms.emplace_front(CurrentPricingProblem, StandardExtenders.front(), BogusFinalExtender, *CurrentDominator, *CurrentMerger, UseLimitedArcs, MaxMergeLabels, SolvedPricingProblems);

		}
	}

	//Initialize algorithm for the pricing problems from customer to depot:
	//*********************************************************************
	//Go over all relevant pricing problems from customer to depot
	for (auto RelevantPricingProblem = RelevantCustomerDepotPricingProblems.begin(); RelevantPricingProblem != RelevantCustomerDepotPricingProblems.end(); ++RelevantPricingProblem){

		//Obtain current pricing problem
		PStep_PricingProblem &CurrentPricingProblem = (**RelevantPricingProblem);
		
		//Check whether according to DSSR this pricing problem is redundant
		if (!(ApplyDSSR && !(CurrentPricingProblem.RerunRequired))){

			//Obtain current source
			short int iMinusOne = CurrentPricingProblem.Source - 1;
			//Obtain demand
			double* Demand = CurrentPricingProblem.Demand;
			//Obtain capacity
			double Capacity = CurrentPricingProblem.Capacity;
			//Obtain capacity plus tolerance
			double CapacityPlusTolerance = Capacity + Tolerance;

			//Set reduced costs
			double ReducedCostConstant = -Lambda[iMinusOne] - Mu[iMinusOne] - Nu[iMinusOne] * Capacity;
			SetReducedCosts(CurrentPricingProblem, Nu[iMinusOne], ReducedCostConstant);

			//Check whether dynamic state-space relaxation is applied
			if (ApplyDSSR && CurrentPricingProblem.RerunRequired){
				//Create Reachability setter
				NGReachabilitySetters.emplace_front(Demand, CapacityPlusTolerance, CurrentPricingProblem.CurrentDSSRNotInNeighbourhood);
				//Set current reachability setter
				CurrentReachabilitySetter = &(NGReachabilitySetters.front());
				//Check whether reachability should be checked
				if (!DoNotCheckReachability){
					//Create dominator
					DSSRNGReachabilityDominators.emplace_front(Tolerance, CurrentPricingProblem.CurrentDSSRNeighbourhoods);
					//Set current dominator
					CurrentDominator = &(DSSRNGReachabilityDominators.front());
				}
				//Create merger
				NGMaxLoadMergers.emplace_front(CurrentPricingProblem.Capacity, CapacityPlusTolerance, CurrentPricingProblem.CandidateMergeLabels, CurrentPricingProblem.CurrentDSSRNotInNeighbourhood);
				//Set current merger
				CurrentMerger = &(NGMaxLoadMergers.front());
			}
			else if (UseNGPathRelaxation){
				//Create NGReachabilitySetter
				NGReachabilitySetters.emplace_front(Demand, CapacityPlusTolerance, NotInNeighbourhood);
				//Set current reachability setter
				CurrentReachabilitySetter = &(NGReachabilitySetters.front());
				//Create merger
				NGMaxLoadMergers.emplace_front(CurrentPricingProblem.Capacity, CapacityPlusTolerance, CurrentPricingProblem.CandidateMergeLabels, NotInNeighbourhood);
				//Set current merger
				CurrentMerger = &(NGMaxLoadMergers.front());
			}
			else{
				//Create ReachabilitySetter
				ReachabilitySetters.emplace_front(Demand, CapacityPlusTolerance);
				//Set current reachability setter
				CurrentReachabilitySetter = &(ReachabilitySetters.front());
				//Create merger
				MaxLoadMergers.emplace_front(CurrentPricingProblem.Capacity, CapacityPlusTolerance, CurrentPricingProblem.CandidateMergeLabels);
				//Set current merger
				CurrentMerger = &(MaxLoadMergers.front());
			}
			//Create standard extender
			StandardExtenders.emplace_front(Demand, CurrentPricingProblem.ReducedArcCosts, *CurrentReachabilitySetter);

			//Create Layered Labeling Algorithm
			LabelingAlgorithms.emplace_front(CurrentPricingProblem, StandardExtenders.front(), BogusFinalExtender, *CurrentDominator, *CurrentMerger, UseLimitedArcs, MaxMergeLabels, SolvedPricingProblems);

		}
	}

	//Initialize algorithm for the pricing problems from customer to customers:
	//*************************************************************************
	//Go over all relevant pricing problems from customer to customer
	for (auto RelevantPricingProblem = RelevantCustomerCustomerPricingProblems.begin(); RelevantPricingProblem != RelevantCustomerCustomerPricingProblems.end(); ++RelevantPricingProblem){

		//Obtain current source and sink
		short int i = (*RelevantPricingProblem)->Source;
		short int iMinusOne = i - 1;
		short int j = (*RelevantPricingProblem)->Sink;
		short int jMinusOne = j - 1;

		//Initialize indicators, indicating which customer, i or j, has larger Nu
		short int LargeNuCustomer = iMinusOne;
		short int SmallNuCustomer = jMinusOne;
		//Set indictors to the right value
		if (Nu[LargeNuCustomer] < Nu[SmallNuCustomer]){
			LargeNuCustomer = jMinusOne;
			SmallNuCustomer = iMinusOne;
		}

		//Check whether the p-step from LargeNuCustomer to SmallNuCustomer has a cost
		//lower or equal to the cost of the same p-step reversed.
		//Keep in mind that with strict inequality, the starting load of 'Large to Small' is set to the maximum,
		//while the reverse has starting load 0. In case equality, this is irrelevant.
		if (2 * (Mu[SmallNuCustomer] - Mu[LargeNuCustomer]) - Nu[LargeNuCustomer] * ((*RelevantPricingProblem)->Capacity + (*RelevantPricingProblem)->Demand[LargeNuCustomer]) + Nu[SmallNuCustomer] * ((*RelevantPricingProblem)->Capacity + (*RelevantPricingProblem)->Demand[SmallNuCustomer]) < -Tolerance){
			//A p-step from LargeNuCustomer to SmallNuCustomer has lower cost than its reverse.

			//Obtain current pricing problem
			PStep_PricingProblem* TempPricingProblem;
			if (LargeNuCustomer == iMinusOne){
				TempPricingProblem = *RelevantPricingProblem;
			}
			else{
				TempPricingProblem = &PricingProblems[j][i];
			}
			PStep_PricingProblem &CurrentPricingProblem = *TempPricingProblem;

			//Check whether according to DSSR this pricing problem is redundant
			if (!(ApplyDSSR && !(CurrentPricingProblem.RerunRequired))){

				//Set up the algorithm to generate p-steps with maximum load:

				//Obtain demand
				double* Demand = CurrentPricingProblem.Demand;
				//Obtain capacity
				double Capacity = CurrentPricingProblem.Capacity;
				//Obtain capacity plus tolerance
				double CapacityPlusTolerance = Capacity + Tolerance;

				//Set reduced costs
				double ReducedCostConstant = Lambda[SmallNuCustomer] - Lambda[LargeNuCustomer] + Mu[SmallNuCustomer] - Mu[LargeNuCustomer] + (Nu[SmallNuCustomer] - Nu[LargeNuCustomer]) * Capacity;
				SetReducedCosts(CurrentPricingProblem, Nu[LargeNuCustomer], ReducedCostConstant);

				//Check which reachability setter should be used
				if (ApplyDSSR && CurrentPricingProblem.RerunRequired){
					//Create Reachability setter
					NGReachabilitySetters.emplace_front(Demand, CapacityPlusTolerance, CurrentPricingProblem.CurrentDSSRNotInNeighbourhood);
					//Set current reachability setter
					CurrentReachabilitySetter = &(NGReachabilitySetters.front());
					//Check whether reachability should be checked
					if (!DoNotCheckReachability){
						//Create dominator
						DSSRNGReachabilityDominators.emplace_front(Tolerance, CurrentPricingProblem.CurrentDSSRNeighbourhoods);
						//Set current dominator
						CurrentDominator = &(DSSRNGReachabilityDominators.front());
					}
					//Create merger
					NGMaxLoadMergers.emplace_front(CurrentPricingProblem.Capacity, CapacityPlusTolerance, CurrentPricingProblem.CandidateMergeLabels, CurrentPricingProblem.CurrentDSSRNotInNeighbourhood);
					//Set current merger
					CurrentMerger = &(NGMaxLoadMergers.front());
				}
				else if (UseNGPathRelaxation){
					//Create NGReachabilitySetter
					NGReachabilitySetters.emplace_front(Demand, CapacityPlusTolerance, NotInNeighbourhood);
					//Set current reachability setter
					CurrentReachabilitySetter = &(NGReachabilitySetters.front());
					//Create merger
					NGMaxLoadMergers.emplace_front(CurrentPricingProblem.Capacity, CapacityPlusTolerance, CurrentPricingProblem.CandidateMergeLabels, NotInNeighbourhood);
					//Set current merger
					CurrentMerger = &(NGMaxLoadMergers.front());
				}
				else{
					//Create ReachabilitySetter
					ReachabilitySetters.emplace_front(Demand, CapacityPlusTolerance);
					//Set current reachability setter
					CurrentReachabilitySetter = &(ReachabilitySetters.front());
					//Create merger
					MaxLoadMergers.emplace_front(CurrentPricingProblem.Capacity, CapacityPlusTolerance, CurrentPricingProblem.CandidateMergeLabels);
					//Set current merger
					CurrentMerger = &(MaxLoadMergers.front());
				}
				//Create standard extender
				StandardExtenders.emplace_front(Demand, CurrentPricingProblem.ReducedArcCosts, *CurrentReachabilitySetter);

				//Create Layered Labeling Algorithm
				LabelingAlgorithms.emplace_front(CurrentPricingProblem, StandardExtenders.front(), BogusFinalExtender, *CurrentDominator, *CurrentMerger, UseLimitedArcs, MaxMergeLabels, SolvedPricingProblems);

			}
		}
		else{
			//A p-step from SmallNuCustomer to LargeNuCustomer has lower or equal cost compared to the reverse.

			//Obtain current pricing problem
			PStep_PricingProblem* TempPricingProblem;
			if (SmallNuCustomer == iMinusOne){
				TempPricingProblem = *RelevantPricingProblem;
			}
			else{
				TempPricingProblem = &PricingProblems[j][i];
			}
			PStep_PricingProblem &CurrentPricingProblem = *TempPricingProblem;

			//Check whether according to DSSR this pricing problem is redundant
			if (!(ApplyDSSR && !(CurrentPricingProblem.RerunRequired))){

				//Set up the algorithm to generate p-steps with zero load:

				//Obtain demand
				double* Demand = CurrentPricingProblem.Demand;
				//Obtain capacity
				double Capacity = CurrentPricingProblem.Capacity;
				//Obtain capacity plus tolerance
				double CapacityPlusTolerance = Capacity + Tolerance;

				//Set reduced costs
				double ReducedCostConstant = Lambda[LargeNuCustomer] - Lambda[SmallNuCustomer] + Mu[LargeNuCustomer] - Mu[SmallNuCustomer] + (Nu[LargeNuCustomer] - Nu[SmallNuCustomer])*Demand[SmallNuCustomer];
				SetReducedCosts(CurrentPricingProblem, Nu[LargeNuCustomer], ReducedCostConstant);

				//Check which reachability setter should be used
				if (ApplyDSSR && CurrentPricingProblem.RerunRequired){
					//Create Reachability setter
					NGReachabilitySetters.emplace_front(Demand, CapacityPlusTolerance, CurrentPricingProblem.CurrentDSSRNotInNeighbourhood);
					//Set current reachability setter
					CurrentReachabilitySetter = &(NGReachabilitySetters.front());
					//Check whether reachability should be checked
					if (!DoNotCheckReachability){
						//Create dominator
						DSSRNGReachabilityDominators.emplace_front(Tolerance, CurrentPricingProblem.CurrentDSSRNeighbourhoods);
						//Set current dominator
						CurrentDominator = &(DSSRNGReachabilityDominators.front());
					}
					//Create merger
					NGZeroLoadMergers.emplace_front(CurrentPricingProblem.Capacity, CapacityPlusTolerance, CurrentPricingProblem.CandidateMergeLabels, CurrentPricingProblem.CurrentDSSRNotInNeighbourhood);
					//Set current merger
					CurrentMerger = &(NGZeroLoadMergers.front());
				}
				else if (UseNGPathRelaxation){
					//Create NGReachabilitySetter
					NGReachabilitySetters.emplace_front(Demand, CapacityPlusTolerance, NotInNeighbourhood);
					//Set current reachability setter
					CurrentReachabilitySetter = &(NGReachabilitySetters.front());
					//Create merger
					NGZeroLoadMergers.emplace_front(CurrentPricingProblem.Capacity, CapacityPlusTolerance, CurrentPricingProblem.CandidateMergeLabels, NotInNeighbourhood);
					//Set current merger
					CurrentMerger = &(NGZeroLoadMergers.front());
				}
				else{
					//Create ReachabilitySetter
					ReachabilitySetters.emplace_front(Demand, CapacityPlusTolerance);
					//Set current reachability setter
					CurrentReachabilitySetter = &(ReachabilitySetters.front());
					//Create merger
					ZeroLoadMergers.emplace_front(CurrentPricingProblem.Capacity, CapacityPlusTolerance, CurrentPricingProblem.CandidateMergeLabels);
					//Set current merger
					CurrentMerger = &(ZeroLoadMergers.front());
				}
				//Create standard extender
				StandardExtenders.emplace_front(Demand, CurrentPricingProblem.ReducedArcCosts, *CurrentReachabilitySetter);

				//Create Layered Labeling Algorithm
				LabelingAlgorithms.emplace_front(CurrentPricingProblem, StandardExtenders.front(), BogusFinalExtender, *CurrentDominator, *CurrentMerger, UseLimitedArcs, MaxMergeLabels, SolvedPricingProblems);

			}
		}

	}

	//Solve pricing problems:
	//*****************************************************************************************

	//Make a list of pointers to the shortest path algorithms which refer to the Layered Labeling Algorithms
	std::forward_list<PStep_ShortestPathAlgorithm*> TempList;
	for (auto CurrentLA = LabelingAlgorithms.begin(); CurrentLA != LabelingAlgorithms.end(); ++CurrentLA){
		TempList.push_front(&(*CurrentLA));
	}

	//Solve
	Solver.Solve(TempList);

	//Add p-steps:
	//*****************************************************************************************

	//Add
	Adder.AddMultiplePPCandidateMergeLabels(SolvedPricingProblems);

}