/*Implementation of PStep_PricingProblem

*/

#include "PStep_PricingProblem.h"

//PStep_PricingProblem:
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

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

//Copy Constructor
PStep_PricingProblem::PStep_PricingProblem(const PStep_PricingProblem &OriginalPStep_PricingProblem)
	: NumberOfLocations(OriginalPStep_PricingProblem.NumberOfLocations),
	NumberOfCustomers(OriginalPStep_PricingProblem.NumberOfCustomers),
	MaxNumberOfArcs(OriginalPStep_PricingProblem.MaxNumberOfArcs),
	Source(OriginalPStep_PricingProblem.Source),
	Sink(OriginalPStep_PricingProblem.Sink),
	Capacity(OriginalPStep_PricingProblem.Capacity),
	OutArcs(OriginalPStep_PricingProblem.OutArcs),
	InArcs(OriginalPStep_PricingProblem.InArcs),
	AllowedToReachSinkEarly(OriginalPStep_PricingProblem.AllowedToReachSinkEarly),
	ReducedCostConstant(OriginalPStep_PricingProblem.ReducedCostConstant),
	CandidateLabels(OriginalPStep_PricingProblem.CandidateLabels),
	CandidatePSteps(OriginalPStep_PricingProblem.CandidatePSteps),
	CandidateMergeLabels(OriginalPStep_PricingProblem.CandidateMergeLabels),
	NumberOfForwardLayers(OriginalPStep_PricingProblem.NumberOfForwardLayers),
	NumberOfBackwardLayers(OriginalPStep_PricingProblem.NumberOfBackwardLayers),
	CurrentTreeNodeOutArcs(OriginalPStep_PricingProblem.CurrentTreeNodeOutArcs),
	CurrentTreeNodeInArcs(OriginalPStep_PricingProblem.CurrentTreeNodeInArcs),
	CurrentTreeNodeLimitedOutArcs(OriginalPStep_PricingProblem.CurrentTreeNodeLimitedOutArcs),
	CurrentTreeNodeLimitedInArcs(OriginalPStep_PricingProblem.CurrentTreeNodeLimitedInArcs),
	MaxNumberOfForwardArcs(OriginalPStep_PricingProblem.MaxNumberOfForwardArcs),
	MaxNumberOfBackwardArcs(OriginalPStep_PricingProblem.MaxNumberOfBackwardArcs),
	OldDSSRNeighbourhoods(OriginalPStep_PricingProblem.OldDSSRNeighbourhoods),
	CurrentDSSRNeighbourhoods(OriginalPStep_PricingProblem.CurrentDSSRNeighbourhoods),
	ForbiddenCycleFound(OriginalPStep_PricingProblem.ForbiddenCycleFound),
	RerunRequired(OriginalPStep_PricingProblem.RerunRequired)
{
	//copy demand
	if (OriginalPStep_PricingProblem.Demand != 0){
		Demand = new double[NumberOfCustomers];
		for (short int i = 0; i < NumberOfCustomers;++i){
			Demand[i] = OriginalPStep_PricingProblem.Demand[i];
		}
	}
	else{
		Demand = 0;
	}
	//Copy reachable
	if (OriginalPStep_PricingProblem.Reachable != 0){
		Reachable = new bool[NumberOfCustomers];
		for (short int i = 0; i < NumberOfCustomers; ++i){
			Reachable[i] = OriginalPStep_PricingProblem.Reachable[i];
		}
	}
	else{
		Reachable = 0;
	}
	//Copy ArcIsRelevant
	if (OriginalPStep_PricingProblem.ArcIsRelevant != 0){
		ArcIsRelevant = new bool*[NumberOfLocations];
		for (short int i = 0; i < NumberOfLocations; ++i){
			ArcIsRelevant[i] = new bool[NumberOfLocations];
			for (short int j = 0; j < NumberOfLocations; ++j){
				ArcIsRelevant[i][j] = OriginalPStep_PricingProblem.ArcIsRelevant[i][j];
			}
		}
	}
	else{
		ArcIsRelevant = 0;
	}
	//Copy LayeredLabels
	if (OriginalPStep_PricingProblem.LayeredLabels != 0){
		LayeredLabels = new std::list<Label>*[MaxNumberOfArcs];
		LayeredLabels[0] = new std::list<Label>[1];
		LayeredLabels[0][0] = OriginalPStep_PricingProblem.LayeredLabels[0][0];
		for (short int i = 1; i < MaxNumberOfArcs;++i){
			LayeredLabels[i] = new std::list<Label>[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				LayeredLabels[i][j] = OriginalPStep_PricingProblem.LayeredLabels[i][j];
			}
		}
	}
	else{
		LayeredLabels = 0;
	}
	//Copy DoubleLayeredLabels
	if (OriginalPStep_PricingProblem.LayeredLabels != 0){
		int IntegerCapacity = int(OriginalPStep_PricingProblem.Capacity);
		DoubleLayeredLabels = new std::list<Label>**[IntegerCapacity+1];
		DoubleLayeredLabels[0] = new std::list<Label>*[1];
		DoubleLayeredLabels[0][0] = new std::list<Label>[1];
		DoubleLayeredLabels[0][0][0] = OriginalPStep_PricingProblem.DoubleLayeredLabels[0][0][0];
		for (int q = 1; q <= IntegerCapacity; ++q){
			if (OriginalPStep_PricingProblem.DoubleLayeredLabels[q] != 0){
				DoubleLayeredLabels[q] = new std::list<Label>*[MaxNumberOfArcs];
				for (short int i = 0; i < MaxNumberOfArcs; ++i){
					DoubleLayeredLabels[q][i] = new std::list<Label>[NumberOfCustomers];
					for (short int j = 0; j < NumberOfCustomers; ++j){
						DoubleLayeredLabels[q][i][j] = OriginalPStep_PricingProblem.LayeredLabels[i][j];
					}
				}
			}
			else{
				DoubleLayeredLabels[q] = 0;
			}
		}
	}
	else{
		DoubleLayeredLabels = 0;
	}
	//Copy LayeredForwardLabels
	if (OriginalPStep_PricingProblem.LayeredForwardLabels != 0){
		LayeredForwardLabels = new std::list<ForwardLabel>*[NumberOfForwardLayers];
		LayeredForwardLabels[0] = new std::list<ForwardLabel>[1];
		LayeredForwardLabels[0][0] = OriginalPStep_PricingProblem.LayeredForwardLabels[0][0];
		for (short int i = 1; i < NumberOfForwardLayers; ++i){
			LayeredForwardLabels[i] = new std::list<ForwardLabel>[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				LayeredForwardLabels[i][j] = OriginalPStep_PricingProblem.LayeredForwardLabels[i][j];
			}
		}
	}
	else{
		LayeredForwardLabels = 0;
	}
	//Copy LayeredBackwardLabels
	if (OriginalPStep_PricingProblem.LayeredBackwardLabels != 0){
		LayeredBackwardLabels = new std::list<BackwardLabel>*[NumberOfBackwardLayers];
		LayeredBackwardLabels[0] = new std::list<BackwardLabel>[1];
		LayeredBackwardLabels[0][0] = OriginalPStep_PricingProblem.LayeredBackwardLabels[0][0];
		for (short int i = 1; i < NumberOfBackwardLayers; ++i){
			LayeredBackwardLabels[i] = new std::list<BackwardLabel>[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				LayeredBackwardLabels[i][j] = OriginalPStep_PricingProblem.LayeredBackwardLabels[i][j];
			}
		}
	}
	else{
		LayeredBackwardLabels = 0;
	}
	//Copy ReducedArcCosts
	if (OriginalPStep_PricingProblem.ReducedArcCosts != 0){
		ReducedArcCosts = new double*[NumberOfLocations];
		for (short int i = 0; i < NumberOfLocations; ++i){
			ReducedArcCosts[i] = new double[NumberOfLocations];
			for (short int j = 0; j < NumberOfLocations; ++j){
				ReducedArcCosts[i][j] = OriginalPStep_PricingProblem.ReducedArcCosts[i][j];
			}
		}
	}
	else{
		ReducedArcCosts = 0;
	}
	//Copy CurrentTreeNodeArcIsRelevant
	if (OriginalPStep_PricingProblem.CurrentTreeNodeArcIsRelevant != 0){
		CurrentTreeNodeArcIsRelevant = new bool*[NumberOfLocations];
		for (short int i = 0; i < NumberOfLocations; ++i){
			CurrentTreeNodeArcIsRelevant[i] = new bool[NumberOfLocations];
			for (short int j = 0; j < NumberOfLocations; ++j){
				CurrentTreeNodeArcIsRelevant[i][j] = OriginalPStep_PricingProblem.CurrentTreeNodeArcIsRelevant[i][j];
			}
		}
	}
	else{
		CurrentTreeNodeArcIsRelevant = 0;
	}
	//Copy ForwardCompletionBounds
	if (OriginalPStep_PricingProblem.ForwardCompletionBounds != 0){
		ForwardCompletionBounds = new double*[NumberOfForwardLayers];
		for (short int i = 1; i < NumberOfForwardLayers; ++i){
			ForwardCompletionBounds[i] = new double[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				ForwardCompletionBounds[i][j] = OriginalPStep_PricingProblem.ForwardCompletionBounds[i][j];
			}
		}
	}
	else{
		ForwardCompletionBounds = 0;
	}
	//Copy BackwardCompletionBounds
	if (OriginalPStep_PricingProblem.BackwardCompletionBounds != 0){
		BackwardCompletionBounds = new double*[NumberOfBackwardLayers];
		for (short int i = 1; i < NumberOfBackwardLayers; ++i){
			BackwardCompletionBounds[i] = new double[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				BackwardCompletionBounds[i][j] = OriginalPStep_PricingProblem.BackwardCompletionBounds[i][j];
			}
		}
	}
	else{
		BackwardCompletionBounds = 0;
	}
	//Copy OldDSSRNotInNeighbourhood
	if (OriginalPStep_PricingProblem.OldDSSRNotInNeighbourhood != 0){
		OldDSSRNotInNeighbourhood = new bool*[NumberOfCustomers];
		for (short int i = 0; i < NumberOfCustomers; ++i){
			OldDSSRNotInNeighbourhood[i] = new bool[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				OldDSSRNotInNeighbourhood[i][j] = OriginalPStep_PricingProblem.OldDSSRNotInNeighbourhood[i][j];
			}
		}
	}
	else{
		OldDSSRNotInNeighbourhood = 0;
	}
	//Copy CurrentDSSRNotInNeighbourhood
	if (OriginalPStep_PricingProblem.CurrentDSSRNotInNeighbourhood != 0){
		CurrentDSSRNotInNeighbourhood = new bool*[NumberOfCustomers];
		for (short int i = 0; i < NumberOfCustomers; ++i){
			CurrentDSSRNotInNeighbourhood[i] = new bool[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				CurrentDSSRNotInNeighbourhood[i][j] = OriginalPStep_PricingProblem.CurrentDSSRNotInNeighbourhood[i][j];
			}
		}
	}
	else{
		CurrentDSSRNotInNeighbourhood = 0;
	}
	//Copy ToAdd
	if (OriginalPStep_PricingProblem.ToAdd != 0){
		ToAdd = new bool*[NumberOfCustomers];
		for (short int i = 0; i < NumberOfCustomers; ++i){
			ToAdd[i] = new bool[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				ToAdd[i][j] = OriginalPStep_PricingProblem.ToAdd[i][j];
			}
		}
	}
	else{
		ToAdd = 0;
	}
}

//Operator functions:
//------------------------------------------------------------------------------------

//Assignment operator
PStep_PricingProblem PStep_PricingProblem::operator =(PStep_PricingProblem OriginalPStep_PricingProblem){

	//Delete Demand
	delete[]Demand;

	//Delete Reachable;
	delete[]Reachable;

	//Delete ArcIsRelevant
	if (!(NumberOfLocations == 0 || ArcIsRelevant == 0)){
		for (short int i = 0; i < NumberOfLocations; ++i){
			delete[]ArcIsRelevant[i];
		}
		delete[]ArcIsRelevant;
	}
	else{
		ArcIsRelevant = 0;
	}

	//Delete ReducedArcCosts
	if (!(NumberOfLocations == 0 || ReducedArcCosts == 0)){
		for (short int i = 0; i < NumberOfLocations; ++i){
			delete[]ReducedArcCosts[i];
		}
		delete[]ReducedArcCosts;
	}
	else{
		ReducedArcCosts = 0;
	}

	//Delete LayeredLabels
	if (MaxNumberOfArcs>0 && !(LayeredLabels == 0)){
		//Go over all customers
		for (short int i = 0; i<MaxNumberOfArcs; i++){
			delete[]LayeredLabels[i];
		}
		delete[]LayeredLabels;
		LayeredLabels = 0;
	}
	//Delete DoubleLayeredLabels
	int IntegerCapacity = int(Capacity);
	if (IntegerCapacity>0 && !(DoubleLayeredLabels == 0)){
		delete[] DoubleLayeredLabels[0][0];
		delete[] DoubleLayeredLabels[0];
		for (int q = 1; q <= IntegerCapacity; ++q){
			//Check whether the current load is in use
			if (DoubleLayeredLabels[q] != 0){
				//Go over all customers
				for (short int i = 0; i < MaxNumberOfArcs; i++){
					delete[]DoubleLayeredLabels[q][i];
				}
				delete[]DoubleLayeredLabels[q];
			}
		}
		delete[]DoubleLayeredLabels;
		DoubleLayeredLabels = 0;
	}
	//Delete LayeredForwardLabels
	if (!(LayeredForwardLabels == 0)){
		//Go over all customers
		for (short int i = 0; i < NumberOfForwardLayers; i++){
			delete[]LayeredForwardLabels[i];
		}
		delete[]LayeredForwardLabels;
		LayeredForwardLabels = 0;
	}
	//Delete LayeredBackwardLabels
	if (!(LayeredBackwardLabels == 0)){
		//Go over all customers
		for (short int i = 0; i < NumberOfBackwardLayers; i++){
			delete[]LayeredBackwardLabels[i];
		}
		delete[]LayeredBackwardLabels;
		LayeredBackwardLabels = 0;
	}
	//Delete CurrentTreeNodeArcIsRelevant
	if (!(NumberOfLocations == 0 || CurrentTreeNodeArcIsRelevant == 0)){
		for (short int i = 0; i < NumberOfLocations; ++i){
			delete[]CurrentTreeNodeArcIsRelevant[i];
		}
		delete[]CurrentTreeNodeArcIsRelevant;
	}
	else{
		CurrentTreeNodeArcIsRelevant = 0;
	}
	//Delete ForwardCompletionBounds
	if (!(ForwardCompletionBounds == 0)){
		//Go over all customers
		for (short int i = 1; i < NumberOfForwardLayers; i++){
			delete[]ForwardCompletionBounds[i];
		}
		delete[]ForwardCompletionBounds;
		ForwardCompletionBounds = 0;
	}
	//Delete BackwardCompletionBounds
	if (!(BackwardCompletionBounds == 0)){
		//Go over all customers
		for (short int i = 1; i < NumberOfBackwardLayers; i++){
			delete[]BackwardCompletionBounds[i];
		}
		delete[]BackwardCompletionBounds;
		BackwardCompletionBounds = 0;
	}
	//Delete OldDSSRNotInNeighbourhood
	if (!(NumberOfCustomers == 0 || OldDSSRNotInNeighbourhood == 0)){
		for (short int i = 0; i < NumberOfCustomers; ++i){
			delete[]OldDSSRNotInNeighbourhood[i];
		}
		delete[]OldDSSRNotInNeighbourhood;
	}
	else{
		OldDSSRNotInNeighbourhood = 0;
	}
	//Delete CurrentDSSRNotInNeighbourhood
	if (!(NumberOfCustomers == 0 || CurrentDSSRNotInNeighbourhood == 0)){
		for (short int i = 0; i < NumberOfCustomers; ++i){
			delete[]CurrentDSSRNotInNeighbourhood[i];
		}
		delete[]CurrentDSSRNotInNeighbourhood;
	}
	else{
		CurrentDSSRNotInNeighbourhood = 0;
	}
	//Delete ToAdd
	if (!(NumberOfCustomers == 0 || ToAdd == 0)){
		for (short int i = 0; i < NumberOfCustomers; ++i){
			delete[]ToAdd[i];
		}
		delete[]ToAdd;
	}
	else{
		ToAdd = 0;
	}

	//Copy
	NumberOfLocations = OriginalPStep_PricingProblem.NumberOfLocations;
	NumberOfCustomers = OriginalPStep_PricingProblem.NumberOfCustomers;
	MaxNumberOfArcs = OriginalPStep_PricingProblem.MaxNumberOfArcs;
	Source = OriginalPStep_PricingProblem.Source;
	Sink = OriginalPStep_PricingProblem.Sink;
	Capacity = OriginalPStep_PricingProblem.Capacity;
	OutArcs = OriginalPStep_PricingProblem.OutArcs;
	InArcs = OriginalPStep_PricingProblem.InArcs;
	AllowedToReachSinkEarly = OriginalPStep_PricingProblem.AllowedToReachSinkEarly;
	ReducedCostConstant = OriginalPStep_PricingProblem.ReducedCostConstant;
	CandidateLabels = OriginalPStep_PricingProblem.CandidateLabels;
	CandidatePSteps = OriginalPStep_PricingProblem.CandidatePSteps;
	CandidateMergeLabels = OriginalPStep_PricingProblem.CandidateMergeLabels;
	NumberOfForwardLayers = OriginalPStep_PricingProblem.NumberOfForwardLayers;
	NumberOfBackwardLayers = OriginalPStep_PricingProblem.NumberOfBackwardLayers;
	CurrentTreeNodeOutArcs = OriginalPStep_PricingProblem.CurrentTreeNodeOutArcs;
	CurrentTreeNodeInArcs = OriginalPStep_PricingProblem.CurrentTreeNodeInArcs;
	MaxNumberOfForwardArcs = OriginalPStep_PricingProblem.MaxNumberOfForwardArcs;
	MaxNumberOfBackwardArcs = OriginalPStep_PricingProblem.MaxNumberOfBackwardArcs;
	OldDSSRNeighbourhoods = OriginalPStep_PricingProblem.OldDSSRNeighbourhoods;
	CurrentDSSRNeighbourhoods = OriginalPStep_PricingProblem.CurrentDSSRNeighbourhoods;
	ForbiddenCycleFound = OriginalPStep_PricingProblem.ForbiddenCycleFound;
	RerunRequired = OriginalPStep_PricingProblem.RerunRequired;

	//copy demand
	if (OriginalPStep_PricingProblem.Demand != 0){
		Demand = new double[NumberOfCustomers];
		for (short int i = 0; i < NumberOfCustomers;++i){
			Demand[i] = OriginalPStep_PricingProblem.Demand[i];
		}
	}
	else{
		Demand = 0;
	}
	//Copy reachable
	if (OriginalPStep_PricingProblem.Reachable != 0){
		Reachable = new bool[NumberOfCustomers];
		for (short int i = 0; i < NumberOfCustomers; ++i){
			Reachable[i] = OriginalPStep_PricingProblem.Reachable[i];
		}
	}
	else{
		Reachable = 0;
	}
	//Copy ArcIsRelevant
	if (OriginalPStep_PricingProblem.ArcIsRelevant != 0){
		ArcIsRelevant = new bool*[NumberOfLocations];
		for (short int i = 0; i < NumberOfLocations; ++i){
			ArcIsRelevant[i] = new bool[NumberOfLocations];
			for (short int j = 0; j < NumberOfLocations; ++j){
				ArcIsRelevant[i][j] = OriginalPStep_PricingProblem.ArcIsRelevant[i][j];
			}
		}
	}
	else{
		ArcIsRelevant = 0;
	}
	//Copy LayeredLabels
	if (OriginalPStep_PricingProblem.LayeredLabels != 0){
		LayeredLabels = new std::list<Label>*[MaxNumberOfArcs];
		LayeredLabels[0] = new std::list<Label>[1];
		LayeredLabels[0][0] = OriginalPStep_PricingProblem.LayeredLabels[0][0];
		for (short int i = 1; i < MaxNumberOfArcs; ++i){
			LayeredLabels[i] = new std::list<Label>[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				LayeredLabels[i][j] = OriginalPStep_PricingProblem.LayeredLabels[i][j];
			}
		}
	}
	else{
		LayeredLabels = 0;
	}
	//Copy DoubleLayeredLabels
	if (OriginalPStep_PricingProblem.LayeredLabels != 0){
		int IntegerCapacity = int(OriginalPStep_PricingProblem.Capacity);
		DoubleLayeredLabels = new std::list<Label>**[IntegerCapacity+1];
		DoubleLayeredLabels[0] = new std::list<Label>*[1];
		DoubleLayeredLabels[0][0]=new std::list<Label>[1];
		DoubleLayeredLabels[0][0][0] = OriginalPStep_PricingProblem.DoubleLayeredLabels[0][0][0];
		for (int q = 1; q <= IntegerCapacity; ++q){
			if (OriginalPStep_PricingProblem.DoubleLayeredLabels[q] != 0){
				DoubleLayeredLabels[q] = new std::list<Label>*[MaxNumberOfArcs];
				for (short int i = 0; i < MaxNumberOfArcs; ++i){
					DoubleLayeredLabels[q][i] = new std::list<Label>[NumberOfCustomers];
					for (short int j = 0; j < NumberOfCustomers; ++j){
						DoubleLayeredLabels[q][i][j] = OriginalPStep_PricingProblem.LayeredLabels[i][j];
					}
				}
			}
			else{
				DoubleLayeredLabels[q] = 0;
			}
		}
	}
	else{
		DoubleLayeredLabels = 0;
	}
	//Copy LayeredForwardLabels
	if (OriginalPStep_PricingProblem.LayeredForwardLabels != 0){
		LayeredForwardLabels = new std::list<ForwardLabel>*[NumberOfForwardLayers];
		LayeredForwardLabels[0] = new std::list<ForwardLabel>[1];
		LayeredForwardLabels[0][0] = OriginalPStep_PricingProblem.LayeredForwardLabels[0][0];
		for (short int i = 1; i < NumberOfForwardLayers; ++i){
			LayeredForwardLabels[i] = new std::list<ForwardLabel>[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				LayeredForwardLabels[i][j] = OriginalPStep_PricingProblem.LayeredForwardLabels[i][j];
			}
		}
	}
	else{
		LayeredForwardLabels = 0;
	}
	//Copy LayeredBackwardLabels
	if (OriginalPStep_PricingProblem.LayeredBackwardLabels != 0){
		LayeredBackwardLabels = new std::list<BackwardLabel>*[NumberOfBackwardLayers];
		LayeredBackwardLabels[0] = new std::list<BackwardLabel>[1];
		LayeredBackwardLabels[0][0] = OriginalPStep_PricingProblem.LayeredBackwardLabels[0][0];
		for (short int i = 1; i < NumberOfBackwardLayers; ++i){
			LayeredBackwardLabels[i] = new std::list<BackwardLabel>[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				LayeredBackwardLabels[i][j] = OriginalPStep_PricingProblem.LayeredBackwardLabels[i][j];
			}
		}
	}
	else{
		LayeredBackwardLabels = 0;
	}
	//Copy ReducedArcCosts
	if (OriginalPStep_PricingProblem.ReducedArcCosts != 0){
		ReducedArcCosts = new double*[NumberOfLocations];
		for (short int i = 0; i < NumberOfLocations; ++i){
			ReducedArcCosts[i] = new double[NumberOfLocations];
			for (short int j = 0; j < NumberOfLocations; ++j){
				ReducedArcCosts[i][j] = OriginalPStep_PricingProblem.ReducedArcCosts[i][j];
			}
		}
	}
	else{
		ReducedArcCosts = 0;
	}
	//Copy CurrentTreeNodeArcIsRelevant
	if (OriginalPStep_PricingProblem.CurrentTreeNodeArcIsRelevant != 0){
		CurrentTreeNodeArcIsRelevant = new bool*[NumberOfLocations];
		for (short int i = 0; i < NumberOfLocations; ++i){
			CurrentTreeNodeArcIsRelevant[i] = new bool[NumberOfLocations];
			for (short int j = 0; j < NumberOfLocations; ++j){
				CurrentTreeNodeArcIsRelevant[i][j] = OriginalPStep_PricingProblem.CurrentTreeNodeArcIsRelevant[i][j];
			}
		}
	}
	else{
		CurrentTreeNodeArcIsRelevant = 0;
	}
	//Copy ForwardCompletionBounds
	if (OriginalPStep_PricingProblem.ForwardCompletionBounds != 0){
		ForwardCompletionBounds = new double*[NumberOfForwardLayers];
		for (short int i = 1; i < NumberOfForwardLayers; ++i){
			ForwardCompletionBounds[i] = new double[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				ForwardCompletionBounds[i][j] = OriginalPStep_PricingProblem.ForwardCompletionBounds[i][j];
			}
		}
	}
	else{
		ForwardCompletionBounds = 0;
	}
	//Copy BackwardCompletionBounds
	if (OriginalPStep_PricingProblem.BackwardCompletionBounds != 0){
		BackwardCompletionBounds = new double*[NumberOfBackwardLayers];
		for (short int i = 1; i < NumberOfBackwardLayers; ++i){
			BackwardCompletionBounds[i] = new double[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				BackwardCompletionBounds[i][j] = OriginalPStep_PricingProblem.BackwardCompletionBounds[i][j];
			}
		}
	}
	else{
		BackwardCompletionBounds = 0;
	}
	//Copy OldDSSRNotInNeighbourhood
	if (OriginalPStep_PricingProblem.OldDSSRNotInNeighbourhood != 0){
		OldDSSRNotInNeighbourhood = new bool*[NumberOfCustomers];
		for (short int i = 0; i < NumberOfCustomers; ++i){
			OldDSSRNotInNeighbourhood[i] = new bool[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				OldDSSRNotInNeighbourhood[i][j] = OriginalPStep_PricingProblem.OldDSSRNotInNeighbourhood[i][j];
			}
		}
	}
	else{
		OldDSSRNotInNeighbourhood = 0;
	}
	//Copy CurrentDSSRNotInNeighbourhood
	if (OriginalPStep_PricingProblem.CurrentDSSRNotInNeighbourhood != 0){
		CurrentDSSRNotInNeighbourhood = new bool*[NumberOfCustomers];
		for (short int i = 0; i < NumberOfCustomers; ++i){
			CurrentDSSRNotInNeighbourhood[i] = new bool[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				CurrentDSSRNotInNeighbourhood[i][j] = OriginalPStep_PricingProblem.CurrentDSSRNotInNeighbourhood[i][j];
			}
		}
	}
	else{
		CurrentDSSRNotInNeighbourhood = 0;
	}
	//Copy ToAdd
	if (OriginalPStep_PricingProblem.ToAdd != 0){
		ToAdd = new bool*[NumberOfCustomers];
		for (short int i = 0; i < NumberOfCustomers; ++i){
			ToAdd[i] = new bool[NumberOfCustomers];
			for (short int j = 0; j < NumberOfCustomers; ++j){
				ToAdd[i][j] = OriginalPStep_PricingProblem.ToAdd[i][j];
			}
		}
	}
	else{
		ToAdd = 0;
	}

	return *this;

}

//Print functions
//------------------------------------------------------------------------------------

//Print OutArcs
void PStep_PricingProblem::PrintOutArcs(){

	short int LocationIndex = 0;
	for (auto i = OutArcs.begin(); i != OutArcs.end(); ++i){
		std::cout << LocationIndex << ":";
		for (auto j = i->begin(); j != i->end(); ++j){
			std::cout << " (" << j->StartNode << "," << j->EndNode << ")";
		}
		std::cout << std::endl;
		++LocationIndex;
	}

}

//Print InArcs
void PStep_PricingProblem::PrintInArcs(){

	short int LocationIndex = 0;
	for (auto i = InArcs.begin(); i != InArcs.end(); ++i){
		std::cout << LocationIndex << ":";
		for (auto j = i->begin(); j != i->end(); ++j){
			std::cout << " (" << j->StartNode << "," << j->EndNode << ")";
		}
		std::cout << std::endl;
		++LocationIndex;
	}

}

//Print Reachable Customers
void PStep_PricingProblem::PrintReachableCustomers(){

	for (short int i = 0; i < NumberOfCustomers; ++i){
		std::cout << i + 1 << ": " << Reachable[i] << std::endl;
	}

}

//Print ArcIsRelevant
void PStep_PricingProblem::PrintArcIsRelevant(){

	for (short int i = 0; i < NumberOfLocations; ++i){
		for (short int j = 0; j < NumberOfLocations; ++j){
			std::cout << ArcIsRelevant[i][j] << " ";
		}
		std::cout << std::endl;
	}

}

//Print Reduced ArcCosts
void PStep_PricingProblem::PrintReducedArcCosts(){
	
	for (short int i = 0; i < NumberOfLocations; ++i){
		std::cout << i << ":";
		std::cout << std::fixed;
		std::cout.precision(4);
		for (short int j = 0; j < NumberOfLocations; ++j){
			if (i == j){
				std::cout << " ------";
			}
			else{
				std::cout << " " << ReducedArcCosts[i][j];
			}
		}
		std::cout << std::endl;
	}

}

//Print CurrentTreeNodeOutArcs
void PStep_PricingProblem::PrintCurrentTreeNodeOutArcs(){

	short int LocationIndex = 0;
	for (auto i = CurrentTreeNodeOutArcs.begin(); i != CurrentTreeNodeOutArcs.end(); ++i){
		std::cout << LocationIndex << ":";
		for (auto j = i->begin(); j != i->end(); ++j){
			std::cout << " (" << j->StartNode << "," << j->EndNode << ")";
		}
		std::cout << std::endl;
		++LocationIndex;
	}

}

//Print CurrentTreeNodeInArcs
void PStep_PricingProblem::PrintCurrentTreeNodeInArcs(){

	short int LocationIndex = 0;
	for (auto i = CurrentTreeNodeInArcs.begin(); i != CurrentTreeNodeInArcs.end(); ++i){
		std::cout << LocationIndex << ":";
		for (auto j = i->begin(); j != i->end(); ++j){
			std::cout << " (" << j->StartNode << "," << j->EndNode << ")";
		}
		std::cout << std::endl;
		++LocationIndex;
	}

}

//Print CurrentTreeNodeArcIsRelevant
void PStep_PricingProblem::PrintCurrentTreeArcIsRelevant(){

	for (short int i = 0; i < NumberOfLocations; ++i){
		for (short int j = 0; j < NumberOfLocations; ++j){
			std::cout << CurrentTreeNodeArcIsRelevant[i][j] << " ";
		}
		std::cout << std::endl;
	}

}

//Print CurrentTreeNodeLimitedOutArcs
void PStep_PricingProblem::PrintCurrentTreeNodeLimitedOutArcs(){

	short int LocationIndex = 0;
	for (auto i = CurrentTreeNodeLimitedOutArcs.begin(); i != CurrentTreeNodeLimitedOutArcs.end(); ++i){
		std::cout << LocationIndex << ":";
		for (auto j = i->begin(); j != i->end(); ++j){
			std::cout << " (" << j->StartNode << "," << j->EndNode << ")";
		}
		std::cout << std::endl;
		++LocationIndex;
	}

}

//Print CurrentTreeNodeLimitedInArcs
void PStep_PricingProblem::PrintCurrentTreeNodeLimitedInArcs(){

	short int LocationIndex = 0;
	for (auto i = CurrentTreeNodeLimitedInArcs.begin(); i != CurrentTreeNodeLimitedInArcs.end(); ++i){
		std::cout << LocationIndex << ":";
		for (auto j = i->begin(); j != i->end(); ++j){
			std::cout << " (" << j->StartNode << "," << j->EndNode << ")";
		}
		std::cout << std::endl;
		++LocationIndex;
	}

}

//Print ForwardCompletionBounds
void PStep_PricingProblem::PrintForwardCompletionBounds(){

	std::streamsize x = std::cout.precision();
	std::cout.precision(4);
	for (short int l = 1; l < NumberOfForwardLayers; ++l){
		for (short int i = 0; i < NumberOfCustomers; ++i){
			std::cout << ForwardCompletionBounds[l][i] << " ";
		}
		std::cout << std::endl;
	}
	std::cout.precision(x);

}

//Print BackwardCompletionBounds
void PStep_PricingProblem::PrintBackwardCompletionBounds(){

	std::streamsize x = std::cout.precision();
	std::cout.precision(4);
	for (short int l = 1; l < NumberOfBackwardLayers; ++l){
		for (short int i = 0; i < NumberOfCustomers; ++i){
			std::cout << BackwardCompletionBounds[l][i] << " ";
		}
		std::cout << std::endl;
	}
	std::cout.precision(x);

}

//Other functions
//------------------------------------------------------------------------------------

//Reset the members that are used by the Layered Labeling Algorithm members to store the output.
void PStep_PricingProblem::ResetLayeredLabelingAlgorithmMembers(){

	//Reset LayeredLabels
	LayeredLabels[0][0].clear();
	for (short int Layer = 1; Layer < MaxNumberOfArcs; ++Layer){
		for (short int Customer = 0; Customer < NumberOfCustomers; ++Customer){
			LayeredLabels[Layer][Customer].clear();
		}
	}

	//Reset LayeredCandidateLabels
	CandidateLabels.clear();

}

//Reset the members that are used by the Double Layered Labeling Algorithm members to store the output.
void PStep_PricingProblem::ResetDoubleLayeredLabelingAlgorithmMembers(){

	//Reset DoubleLayeredLabels
	int IntegerCapacity = int(Capacity);
	DoubleLayeredLabels[0][0][0].clear();
	for (int q = 1; q < IntegerCapacity+1; ++q){
		if (DoubleLayeredLabels[q] != 0){
			for (short int Layer = 1; Layer < MaxNumberOfArcs; ++Layer){
				delete[]DoubleLayeredLabels[q][Layer];
			}
			delete[]DoubleLayeredLabels[q];
			DoubleLayeredLabels[q] = 0;
		}
	}

	//Reset LayeredCandidateLabels
	CandidateLabels.clear();

}

//Reset the members that are used by the Bi-Directional Layered Labeling Algorithm members to store the output.
void PStep_PricingProblem::ResetBiDirectionalLayeredLabelingAlgorithmMembers(){

	//Reset LayeredLabels
	LayeredForwardLabels[0][0].clear();
	for (short int Layer = 1; Layer <= MaxNumberOfForwardArcs; ++Layer){
		for (short int Customer = 0; Customer < NumberOfCustomers; ++Customer){
			LayeredForwardLabels[Layer][Customer].clear();
		}
	}

	//Reset LayeredBackwardLabels
	LayeredBackwardLabels[0][0].clear();
	for (short int Layer = 1; Layer <= MaxNumberOfBackwardArcs; ++Layer){
		for (short int Customer = 0; Customer < NumberOfCustomers; ++Customer){
			LayeredBackwardLabels[Layer][Customer].clear();
		}
	}

	//Reset CandidateMergeLabels
	CandidateMergeLabels.clear();

}

//Reset the members that are used for completing the bi-directional labeling algorithm members to store the output.
void PStep_PricingProblem::ResetSecondHalfBiDirectionalLayerMembers(){

	//Reset LayeredLabels
	LayeredForwardLabels[0][0].clear();
	for (short int Layer = MaxNumberOfForwardArcs+1; Layer < NumberOfForwardLayers; ++Layer){
		for (short int Customer = 0; Customer < NumberOfCustomers; ++Customer){
			LayeredForwardLabels[Layer][Customer].clear();
		}
	}

	//Reset LayeredBackwardLabels
	LayeredBackwardLabels[0][0].clear();
	for (short int Layer = MaxNumberOfBackwardArcs+1; Layer < NumberOfBackwardLayers; ++Layer){
		for (short int Customer = 0; Customer < NumberOfCustomers; ++Customer){
			LayeredBackwardLabels[Layer][Customer].clear();
		}
	}

}

//Reset the DSSR neighbourhoods
void PStep_PricingProblem::ResetDSSRNeighbourhoods(){

	//Clear Neighbourhood information
	CurrentDSSRNeighbourhoods.clear();
	if (!(NumberOfCustomers == 0 || CurrentDSSRNotInNeighbourhood == 0)){
		for (short int i = 0; i < NumberOfCustomers; ++i){
			delete[]CurrentDSSRNotInNeighbourhood[i];
		}
		delete[]CurrentDSSRNotInNeighbourhood;
	}
	else{
		CurrentDSSRNotInNeighbourhood = 0;
	}

	//Initialize template neighbourhood
	std::vector<short int > NeighbourhoodTemplate;
	//Initialize template NotInNeighbourhood
	CurrentDSSRNotInNeighbourhood = new bool*[NumberOfCustomers];

	//Go over all customers
	for (short int i = 0; i < NumberOfCustomers; i++){
		//Initialize the neighbourhood of the current customer.
		CurrentDSSRNeighbourhoods.push_back(NeighbourhoodTemplate);
		//Initialize the not in Neighbourhood of the current customer.
		CurrentDSSRNotInNeighbourhood[i] = new bool[NumberOfCustomers];
		//Go over all customers
		for (short int j = 0; j < NumberOfCustomers; ++j){
			//Initialize to true
			CurrentDSSRNotInNeighbourhood[i][j] = true;
		}
	}
}

//Copy the current DSSRNeighbourhoods to old DSSRNeighbourhoods
//We assume that if OldDSSRNeighbourhoods is initialized, it has the same dimensions
//as CurrentDSSRNotInNeighbourhood.
void PStep_PricingProblem::CopyCurrentDSSRNeighbourhoodsToOld(){

	//Copy current neighbourhoods
	OldDSSRNeighbourhoods = CurrentDSSRNeighbourhoods;

	//Check whether OldDSSRNotInNeighbourhood requires initialization
	if (OldDSSRNotInNeighbourhood == 0){
		//Initialize OldDSSRNotInNeighbourhood
		OldDSSRNotInNeighbourhood = new bool*[NumberOfCustomers];
		//Go over all customers
		for (short int i = 0; i < NumberOfCustomers; i++){
			//Initialize the not in Neighbourhood of the current customer.
			OldDSSRNotInNeighbourhood[i] = new bool[NumberOfCustomers];
		}
	}

	//Copy CurrentDSSRNotInNeighbourhood
	for (short int i = 0; i < NumberOfCustomers; ++i){
		for (short int j = 0; j < NumberOfCustomers; ++j){
			OldDSSRNotInNeighbourhood[i][j] = CurrentDSSRNotInNeighbourhood[i][j];
		}
	}

}

//Obtain the "second" half of the completion bounds, based on LayeredForwardLabels and LayeredBackwardLabels.
//That is, obtain the values of ForwardCompletionBounds[l][i], for all customers i and
//layers l such that MaxNumberOfForwardArcs < l < NumberOfForwardLayers.
//Furthermore, obtain the values of BackwardCompletionBounds[l][i] for all customers i
//and layers l such that MaxNumberOfBackwardArcs < l < NumberOfBackwardLayers.
//NOTE: It is assumed that ForwardLabels and BackwardLabels are sorted from lowest reduced costs
//		to highest.
void PStep_PricingProblem::ObtainSecondHalfOfCompletionBounds(double MinusTolerance){

	//Initialize Forward and Backward Layer indicator
	short int BackwardLayer;
	short int ForwardLayer;

	//Check whether it is allowed to reach the sink early
	if (AllowedToReachSinkEarly){
		//It is allowed to reach the sink early

		//Initialize best completion bound for the current customer
		double CurrentBestCompletionBound;
		//Initialize indicator, indicating whether current best is not found yet
		bool CurrentBestCompletionBoundNotFound;

		//Obtain the bounds for the forward labels (based on current backward labels):
		//Go over all customers
		for (short int CurrentCustomer = 0; CurrentCustomer < NumberOfCustomers; ++CurrentCustomer){
			
			//Set indicator indicating whether a current best completion bound is not found yet
			CurrentBestCompletionBoundNotFound = true;
			
			//Initialize forward layer
			ForwardLayer = NumberOfForwardLayers;
			//Go over all layers for the current customer
			for (BackwardLayer = 1; BackwardLayer < MaxNumberOfBackwardArcs+1; ++BackwardLayer){
				//Update forward layer
				--ForwardLayer;
				//Check whether the BackwardLabels container is empty
				if (LayeredBackwardLabels[BackwardLayer][CurrentCustomer].empty()){
					//Check whether a current best completion bound is not yet found
					if (CurrentBestCompletionBoundNotFound){
						//Extending a forward label will not result in a feasible path

						//TODO
						//This completion bound might never be used.
						//Any value is correct.
						//If the value is guaranteed to be lower than the reduced cost of a forward label,
						//any forward label is never extend, which is desirable.
						ForwardCompletionBounds[ForwardLayer][CurrentCustomer] = -999999;

					}
					else{
						//Use the current best completion bound as the new one
						ForwardCompletionBounds[ForwardLayer][CurrentCustomer] = CurrentBestCompletionBound;
					}
				}
				else{
					//Use the lowest reduced cost as completion bound

					//Obtain the current completion bound
					double CurrentCompletionBound = MinusTolerance - LayeredBackwardLabels[BackwardLayer][CurrentCustomer].front().Cost;
					
					//Check whether the current reduced cost is lower than the current best (if in use at all)
					if (CurrentBestCompletionBoundNotFound){
						//Set the current completion bound as the new one and the new best
						CurrentBestCompletionBoundNotFound = false;
						CurrentBestCompletionBound = CurrentCompletionBound;
						ForwardCompletionBounds[ForwardLayer][CurrentCustomer] = CurrentCompletionBound;
					}
					//There exists a current best, check whether the current is better than the current best
					else if (CurrentCompletionBound > CurrentBestCompletionBound){
						//Set the current completion bound as the new one and the new best
						CurrentBestCompletionBound = CurrentCompletionBound;
						ForwardCompletionBounds[ForwardLayer][CurrentCustomer] = CurrentCompletionBound;
					}
					else{
						//Set the current best completion bound as completion bound
						ForwardCompletionBounds[ForwardLayer][CurrentCustomer] = CurrentBestCompletionBound;
					}

				}
			}//end go over all layers
		}//end go over all customers

		//Obtain the bounds for the backward labels (based on current forward labels):
		//Go over all customers
		for (short int CurrentCustomer = 0; CurrentCustomer < NumberOfCustomers; ++CurrentCustomer){

			//Set indicator indicating whether a current best completion bound is not found yet
			CurrentBestCompletionBoundNotFound = true;

			//Initialize backward layer
			BackwardLayer = NumberOfBackwardLayers;
			//Go over all layers for the current customer
			for (ForwardLayer = 1; ForwardLayer < MaxNumberOfForwardArcs+1; ++ForwardLayer){
				//Update backward layer
				--BackwardLayer;
				//Check whether the ForwardLabels container is empty
				if (LayeredForwardLabels[ForwardLayer][CurrentCustomer].empty()){
					//Check whether a current best completion bound is not yet found
					if (CurrentBestCompletionBoundNotFound){
						//Extending a forward label will not result in a feasible path

						//TODO
						//This completion bound might never be used.
						//Any value is correct.
						//If the value is guaranteed to be lower than the reduced cost of a forward label,
						//any forward label is never extend, which is desirable.
						BackwardCompletionBounds[BackwardLayer][CurrentCustomer] = -999999;

					}
					else{
						//Use the current best completion bound as the new one
						BackwardCompletionBounds[BackwardLayer][CurrentCustomer] = CurrentBestCompletionBound;
					}
				}
				else{
					//Use the lowest reduced cost as completion bound

					//Obtain the current completion bound
					double CurrentCompletionBound = MinusTolerance - LayeredForwardLabels[ForwardLayer][CurrentCustomer].front().Cost;

					//Check whether the current reduced cost is lower than the current best (if in use at all)
					if (CurrentBestCompletionBoundNotFound){
						//Set the current completion bound as the new one and the new best
						CurrentBestCompletionBoundNotFound = false;
						CurrentBestCompletionBound = CurrentCompletionBound;
						BackwardCompletionBounds[BackwardLayer][CurrentCustomer] = CurrentCompletionBound;
					}
					//There exists a current best, check whether the current is better than the current best
					else if (CurrentCompletionBound > CurrentBestCompletionBound){
						//Set the current completion bound as the new one and the new best
						CurrentBestCompletionBound = CurrentCompletionBound;
						BackwardCompletionBounds[BackwardLayer][CurrentCustomer] = CurrentCompletionBound;
					}
					else{
						//Set the current best completion bound as completion bound
						BackwardCompletionBounds[BackwardLayer][CurrentCustomer] = CurrentBestCompletionBound;
					}

				}
			}//end go over all layers
		}//end go over all customers

	}
	else{
		//It is not allowed to reach the sink early

		//Obtain the bounds for the forward labels (based on current backward labels):
		//Initialize backward layer
		BackwardLayer = MaxNumberOfBackwardArcs;
		//Go over all forwardlayers
		for (ForwardLayer = MaxNumberOfForwardArcs + 1; ForwardLayer < NumberOfForwardLayers; ++ForwardLayer){
			//For the current layer, go over all customers
			for (short int CurrentCustomer = 0; CurrentCustomer < NumberOfCustomers; ++CurrentCustomer){
				//Check whether the BackwardLabels container is empty
				if (LayeredBackwardLabels[BackwardLayer][CurrentCustomer].empty()){
					//Extending a forward label will not result in a feasible path

					//TODO
					//This completion bound might never be used.
					//Any value is correct.
					//If the value is guaranteed to be lower than the reduced cost of a forward label,
					//any forward label is never extend, which is desirable.
					ForwardCompletionBounds[ForwardLayer][CurrentCustomer] = -999999;

				}
				else{
					//Use the lowest reduced cost as completion bound
					ForwardCompletionBounds[ForwardLayer][CurrentCustomer] = MinusTolerance - LayeredBackwardLabels[BackwardLayer][CurrentCustomer].front().Cost;
				}
			}//end go over all customers

			//Update backward layer
			--BackwardLayer;

		}//end go over all forward layers

		//Obtain the bounds for the backward labels (based on current forward labels):
		//Initialize ForwardLayer
		ForwardLayer = MaxNumberOfForwardArcs;
		//Go over all backward layers
		for (BackwardLayer = MaxNumberOfBackwardArcs + 1; BackwardLayer < NumberOfBackwardLayers; ++BackwardLayer){
			//For the current layer, go over all customers
			for (short int CurrentCustomer = 0; CurrentCustomer < NumberOfCustomers; ++CurrentCustomer){
				//Check whether the ForwardLabels container is empty
				if (LayeredForwardLabels[ForwardLayer][CurrentCustomer].empty()){
					//Extending a backward label will not result in a feasible path

					//TODO
					//This completion bound might never be used.
					//Any value is correct.
					//If the value is guaranteed to be lower than the reduced cost of a backward label,
					//any backward label is never extend, which is desirable.
					BackwardCompletionBounds[BackwardLayer][CurrentCustomer] = -999999;

				}
				else{
					//Use the lowest reduced cost as completion bound
					BackwardCompletionBounds[BackwardLayer][CurrentCustomer] = MinusTolerance - LayeredForwardLabels[ForwardLayer][CurrentCustomer].front().Cost;
				}
			}//end go over all customers

			//Update Forward layer
			--ForwardLayer;

		}//end go over all backward layers

	}//end else it is not allowed to reach the sink early

}

//Obtain the "first" half of the completion bounds, based on LayeredForwardLabels and LayeredBackwardLabels.
//That is, obtain the values of ForwardCompletionBounds[l][i], for all customers i and
//layers l such that 0 < l <= MaxNumberOfForwardArcs.
//Furthermore, obtain the values of ForwardCompletionBounds[l][i] for all customers i
//and layers l such that 0 < l <= MaxNumberOfBackwardArcs.
//NOTE: It is assumed that ForwardLabels and BackwardLabels are sorted from lowest reduced costs
//		to highest.
void PStep_PricingProblem::ObtainFirstHalfOfCompletionBounds(double MinusTolerance){

	//Initialize Forward and Backward Layer indicator
	short int BackwardLayer;
	short int ForwardLayer;

	//Check whether it is allowed to reach the sink early
	if (AllowedToReachSinkEarly){
		//It is allowed to reach the sink early

		//Initialize best completion bound for the current customer
		double CurrentBestCompletionBound;
		//Initialize indicator, indicating whether current best is not found yet
		bool CurrentBestCompletionBoundNotFound;

		//Obtain the bounds for the forward labels (based on current backward labels):
		//Go over all customers
		for (short int CurrentCustomer = 0; CurrentCustomer < NumberOfCustomers; ++CurrentCustomer){

			//Set indicator indicating whether a current best completion bound is not found yet
			CurrentBestCompletionBoundNotFound = true;

			//Initialize forward layer
			ForwardLayer = MaxNumberOfForwardArcs;
			//Go over all layers for the current customer
			for (BackwardLayer = MaxNumberOfBackwardArcs + 1; BackwardLayer < NumberOfBackwardLayers; ++BackwardLayer){
				//Check whether the BackwardLabels container is empty
				if (LayeredBackwardLabels[BackwardLayer][CurrentCustomer].empty()){
					//Check whether a current best completion bound is not yet found
					if (CurrentBestCompletionBoundNotFound){
						//Extending a forward label will not result in a feasible path

						//TODO
						//This completion bound might never be used.
						//Any value is correct.
						//If the value is guaranteed to be lower than the reduced cost of a forward label,
						//any forward label is never extend, which is desirable.
						ForwardCompletionBounds[ForwardLayer][CurrentCustomer] = -999999;

					}
					else{
						//Use the current best completion bound as the new one
						ForwardCompletionBounds[ForwardLayer][CurrentCustomer] = CurrentBestCompletionBound;
					}
				}
				else{
					//Use the lowest reduced cost as completion bound

					//Obtain the current completion bound
					double CurrentCompletionBound = MinusTolerance - LayeredBackwardLabels[BackwardLayer][CurrentCustomer].front().Cost;

					//Check whether the current reduced cost is lower than the current best (if in use at all)
					if (CurrentBestCompletionBoundNotFound){
						//Set the current completion bound as the new one and the new best
						CurrentBestCompletionBoundNotFound = false;
						CurrentBestCompletionBound = CurrentCompletionBound;
						ForwardCompletionBounds[ForwardLayer][CurrentCustomer] = CurrentCompletionBound;
					}
					//There exists a current best, check whether the current is better than the current best
					else if (CurrentCompletionBound > CurrentBestCompletionBound){
						//Set the current completion bound as the new one and the new best
						CurrentBestCompletionBound = CurrentCompletionBound;
						ForwardCompletionBounds[ForwardLayer][CurrentCustomer] = CurrentCompletionBound;
					}
					else{
						//Set the current best completion bound as completion bound
						ForwardCompletionBounds[ForwardLayer][CurrentCustomer] = CurrentBestCompletionBound;
					}

				}
				//Update forward layer
				--ForwardLayer;
			}//end go over all layers
		}//end go over all customers

		//Obtain the bounds for the backward labels (based on current forward labels):
		//Go over all customers
		for (short int CurrentCustomer = 0; CurrentCustomer < NumberOfCustomers; ++CurrentCustomer){

			//Set indicator indicating whether a current best completion bound is not found yet
			CurrentBestCompletionBoundNotFound = true;

			//Initialize backward layer
			BackwardLayer = MaxNumberOfBackwardArcs;
			//Go over all layers for the current customer
			for (ForwardLayer = MaxNumberOfForwardArcs + 1; ForwardLayer < NumberOfForwardLayers; ++ForwardLayer){
				//Check whether the ForwardLabels container is empty
				if (LayeredForwardLabels[ForwardLayer][CurrentCustomer].empty()){
					//Check whether a current best completion bound is not yet found
					if (CurrentBestCompletionBoundNotFound){
						//Extending a forward label will not result in a feasible path

						//TODO
						//This completion bound might never be used.
						//Any value is correct.
						//If the value is guaranteed to be lower than the reduced cost of a forward label,
						//any forward label is never extend, which is desirable.
						BackwardCompletionBounds[BackwardLayer][CurrentCustomer] = -999999;

					}
					else{
						//Use the current best completion bound as the new one
						BackwardCompletionBounds[BackwardLayer][CurrentCustomer] = CurrentBestCompletionBound;
					}
				}
				else{
					//Use the lowest reduced cost as completion bound

					//Obtain the current completion bound
					double CurrentCompletionBound = MinusTolerance - LayeredForwardLabels[ForwardLayer][CurrentCustomer].front().Cost;

					//Check whether the current reduced cost is lower than the current best (if in use at all)
					if (CurrentBestCompletionBoundNotFound){
						//Set the current completion bound as the new one and the new best
						CurrentBestCompletionBoundNotFound = false;
						CurrentBestCompletionBound = CurrentCompletionBound;
						BackwardCompletionBounds[BackwardLayer][CurrentCustomer] = CurrentCompletionBound;
					}
					//There exists a current best, check whether the current is better than the current best
					else if (CurrentCompletionBound > CurrentBestCompletionBound){
						//Set the current completion bound as the new one and the new best
						CurrentBestCompletionBound = CurrentCompletionBound;
						BackwardCompletionBounds[BackwardLayer][CurrentCustomer] = CurrentCompletionBound;
					}
					else{
						//Set the current best completion bound as completion bound
						BackwardCompletionBounds[BackwardLayer][CurrentCustomer] = CurrentBestCompletionBound;
					}

				}
				//Update backward layer
				--BackwardLayer;
			}//end go over all layers
		}//end go over all customers

	}
	else{
		//It is not allowed to reach the sink early

		//Obtain the bounds for the forward labels (based on current backward labels):
		//Initialize backward layer
		BackwardLayer = NumberOfBackwardLayers;
		//Go over all forwardlayers
		for (ForwardLayer = 1; ForwardLayer <= MaxNumberOfForwardArcs; ++ForwardLayer){
			//Update backward layer
			--BackwardLayer;
			//For the current layer, go over all customers
			for (short int CurrentCustomer = 0; CurrentCustomer < NumberOfCustomers; ++CurrentCustomer){
				//Check whether the BackwardLabels container is empty
				if (LayeredBackwardLabels[BackwardLayer][CurrentCustomer].empty()){
					//Extending a forward label will not result in a feasible path

					//TODO
					//This completion bound might never be used.
					//Any value is correct.
					//If the value is guaranteed to be lower than the reduced cost of a forward label,
					//any forward label is never extend, which is desirable.
					ForwardCompletionBounds[ForwardLayer][CurrentCustomer] = -999999;

				}
				else{
					//Use the lowest reduced cost as completion bound
					ForwardCompletionBounds[ForwardLayer][CurrentCustomer] = MinusTolerance - LayeredBackwardLabels[BackwardLayer][CurrentCustomer].front().Cost;
				}
			}//end go over all customers

		}//end go over all forward layers

		//Obtain the bounds for the backward labels (based on current forward labels):
		//Initialize ForwardLayer
		ForwardLayer = NumberOfForwardLayers;
		//Go over all backward layers
		for (BackwardLayer = 1; BackwardLayer <= MaxNumberOfBackwardArcs; ++BackwardLayer){
			//Update Forward layer
			--ForwardLayer;
			//For the current layer, go over all customers
			for (short int CurrentCustomer = 0; CurrentCustomer < NumberOfCustomers; ++CurrentCustomer){
				//Check whether the ForwardLabels container is empty
				if (LayeredForwardLabels[ForwardLayer][CurrentCustomer].empty()){
					//Extending a backward label will not result in a feasible path

					//TODO
					//This completion bound might never be used.
					//Any value is correct.
					//If the value is guaranteed to be lower than the reduced cost of a backward label,
					//any backward label is never extend, which is desirable.
					BackwardCompletionBounds[BackwardLayer][CurrentCustomer] = -999999;

				}
				else{
					//Use the lowest reduced cost as completion bound
					BackwardCompletionBounds[BackwardLayer][CurrentCustomer] = MinusTolerance - LayeredForwardLabels[ForwardLayer][CurrentCustomer].front().Cost;
				}
			}//end go over all customers
		}//end go over all backward layers

	}//end else it is not allowed to reach the sink early

}


//Destructor functions
//------------------------------------------------------------------------------------

//Default destructor
PStep_PricingProblem::~PStep_PricingProblem(){

	//Delete Demand
	delete[]Demand;

	//Delete Reachable;
	delete[]Reachable;

	//Delete ArcIsRelevant
	if (!(NumberOfLocations == 0 || ArcIsRelevant == 0)){
		for (short int i = 0; i < NumberOfLocations; ++i){
			delete[]ArcIsRelevant[i];
		}
		delete[]ArcIsRelevant;
	}
	else{
		ArcIsRelevant = 0;
	}

	//Delete ReducedArcCosts
	if (!(NumberOfLocations == 0 || ReducedArcCosts == 0)){
		for (short int i = 0; i < NumberOfLocations; ++i){
			delete[]ReducedArcCosts[i];
		}
		delete[]ReducedArcCosts;
	}
	else{
		ReducedArcCosts = 0;
	}

	//Delete LayeredLabels
	if (MaxNumberOfArcs>0 && !(LayeredLabels == 0)){
		//Go over all customers
		for (short int i = 0; i<MaxNumberOfArcs; i++){
			delete[]LayeredLabels[i];
		}
		delete[]LayeredLabels;
		LayeredLabels = 0;
	}
	//Delete DoubleLayeredLabels
	int IntegerCapacity = int(Capacity);
	if (IntegerCapacity>0 && !(DoubleLayeredLabels == 0)){
		//Go over all loads
		delete[] DoubleLayeredLabels[0][0];
		delete[] DoubleLayeredLabels[0];
		for (int q = 1; q < IntegerCapacity+1; ++q){
			//Check whether the current load is in use
			if (DoubleLayeredLabels[q] != 0){
				//Go over all customers
				for (short int i = 0; i < MaxNumberOfArcs; i++){
					delete[]DoubleLayeredLabels[q][i];
				}
				delete[]DoubleLayeredLabels[q];
			}
		}
		delete[]DoubleLayeredLabels;
		DoubleLayeredLabels = 0;
	}
	//Delete LayeredForwardLabels
	if (!(LayeredForwardLabels == 0)){
		//Go over all customers
		for (short int i = 0; i < NumberOfForwardLayers; i++){
			delete[]LayeredForwardLabels[i];
		}
		delete[]LayeredForwardLabels;
		LayeredForwardLabels = 0;
	}
	//Delete LayeredBackwardLabels
	if (!(LayeredBackwardLabels == 0)){
		//Go over all customers
		for (short int i = 0; i < NumberOfBackwardLayers; i++){
			delete[]LayeredBackwardLabels[i];
		}
		delete[]LayeredBackwardLabels;
		LayeredBackwardLabels = 0;
	}
	//Delete CurrentTreeNodeArcIsRelevant
	if (!(NumberOfLocations == 0 || CurrentTreeNodeArcIsRelevant == 0)){
		for (short int i = 0; i < NumberOfLocations; ++i){
			delete[]CurrentTreeNodeArcIsRelevant[i];
		}
		delete[]CurrentTreeNodeArcIsRelevant;
	}
	else{
		CurrentTreeNodeArcIsRelevant = 0;
	}
	//Delete ForwardCompletionBounds
	if (!(ForwardCompletionBounds == 0)){
		//Go over all customers
		for (short int i = 1; i < NumberOfForwardLayers; i++){
			delete[]ForwardCompletionBounds[i];
		}
		delete[]ForwardCompletionBounds;
		ForwardCompletionBounds = 0;
	}
	//Delete BackwardCompletionBounds
	if (!(BackwardCompletionBounds == 0)){
		//Go over all customers
		for (short int i = 1; i < NumberOfBackwardLayers; i++){
			delete[]BackwardCompletionBounds[i];
		}
		delete[]BackwardCompletionBounds;
		BackwardCompletionBounds = 0;
	}
	//Delete OldDSSRNotInNeighbourhood
	if (!(NumberOfCustomers == 0 || OldDSSRNotInNeighbourhood == 0)){
		for (short int i = 0; i < NumberOfCustomers; ++i){
			delete[]OldDSSRNotInNeighbourhood[i];
		}
		delete[]OldDSSRNotInNeighbourhood;
	}
	else{
		OldDSSRNotInNeighbourhood = 0;
	}
	//Delete CurrentDSSRNotInNeighbourhood
	if (!(NumberOfCustomers == 0 || CurrentDSSRNotInNeighbourhood == 0)){
		for (short int i = 0; i < NumberOfCustomers; ++i){
			delete[]CurrentDSSRNotInNeighbourhood[i];
		}
		delete[]CurrentDSSRNotInNeighbourhood;
	}
	else{
		CurrentDSSRNotInNeighbourhood = 0;
	}
	//Delete ToAdd
	if (!(NumberOfCustomers == 0 || ToAdd == 0)){
		for (short int i = 0; i < NumberOfCustomers; ++i){
			delete[]ToAdd[i];
		}
		delete[]ToAdd;
	}
	else{
		ToAdd = 0;
	}
}
