/*Implementation of PStep_CG1PreprocessedPricingInfo.h

It contains the member functions of PStep_CG1PreprocessedPricingInfo

*/
/*
#include "PStep_CG1PreprocessedPricingInfo.h"

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

//Copy Constructor
PStep_CG1PreprocessedPricingInfo::PStep_CG1PreprocessedPricingInfo(const PStep_CG1PreprocessedPricingInfo &OriginalPStep_CG1PreprocessedPricingInfo)
	: LocationOne(OriginalPStep_CG1PreprocessedPricingInfo.LocationOne), LocationTwo(OriginalPStep_CG1PreprocessedPricingInfo.LocationTwo), Capacity(OriginalPStep_CG1PreprocessedPricingInfo.Capacity), MaxNumberOfArcs(OriginalPStep_CG1PreprocessedPricingInfo.MaxNumberOfArcs), NumberOfCustomers(OriginalPStep_CG1PreprocessedPricingInfo.NumberOfCustomers), CurrentArcs(OriginalPStep_CG1PreprocessedPricingInfo.CurrentArcs), CurrentLimitedArcs(OriginalPStep_CG1PreprocessedPricingInfo.CurrentLimitedArcs)
{

	if (!(OriginalPStep_CG1PreprocessedPricingInfo.Reachable == 0 || NumberOfCustomers == 0)){
		Reachable = new bool[NumberOfCustomers];
		for (int i = 0; i<NumberOfCustomers; i++){
			Reachable[i] = OriginalPStep_CG1PreprocessedPricingInfo.Reachable[i];
		}
	}
	else{
		Reachable = 0;
	}
	if (!(OriginalPStep_CG1PreprocessedPricingInfo.ArcIsRelevant == 0 || NumberOfCustomers == 0)){
		int NumberOfLocations = NumberOfCustomers + 1;
		ArcIsRelevant = new bool*[NumberOfLocations];
		for (int i = 0; i<NumberOfLocations; i++){
			ArcIsRelevant[i] = new bool[NumberOfLocations];
			for (int j = 0; j < NumberOfLocations; ++j){
				ArcIsRelevant[i][j] = OriginalPStep_CG1PreprocessedPricingInfo.ArcIsRelevant[i][j];
			}
		}
	}
	else{
		ArcIsRelevant = 0;
	}

}

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

//Assignment operator
PStep_CG1PreprocessedPricingInfo& PStep_CG1PreprocessedPricingInfo::operator =(const PStep_CG1PreprocessedPricingInfo& OriginalPStep_CG1PreprocessedPricingInfo){

	//Copy
	LocationOne = OriginalPStep_CG1PreprocessedPricingInfo.LocationOne;
	LocationTwo = OriginalPStep_CG1PreprocessedPricingInfo.LocationTwo;
	Capacity = OriginalPStep_CG1PreprocessedPricingInfo.Capacity;
	MaxNumberOfArcs = OriginalPStep_CG1PreprocessedPricingInfo.MaxNumberOfArcs;
	NumberOfCustomers = OriginalPStep_CG1PreprocessedPricingInfo.NumberOfCustomers;
	delete[]Reachable;
	if (!(OriginalPStep_CG1PreprocessedPricingInfo.Reachable == 0 || NumberOfCustomers == 0)){
		Reachable = new bool[NumberOfCustomers];
		for (int i = 0; i<NumberOfCustomers; i++){
			Reachable[i] = OriginalPStep_CG1PreprocessedPricingInfo.Reachable[i];
		}
	}
	else{
		Reachable = 0;
	}
	delete[]ArcIsRelevant;
	if (!(OriginalPStep_CG1PreprocessedPricingInfo.ArcIsRelevant == 0 || NumberOfCustomers == 0)){
		int NumberOfLocations = NumberOfCustomers + 1;
		ArcIsRelevant = new bool*[NumberOfLocations];
		for (int i = 0; i<NumberOfLocations; i++){
			ArcIsRelevant[i] = new bool[NumberOfLocations];
			for (int j = 0; j < NumberOfLocations; ++j){
				ArcIsRelevant[i][j] = OriginalPStep_CG1PreprocessedPricingInfo.ArcIsRelevant[i][j];
			}
		}
	}
	else{
		ArcIsRelevant = 0;
	}
	CurrentArcs = OriginalPStep_CG1PreprocessedPricingInfo.CurrentArcs;
	CurrentLimitedArcs = OriginalPStep_CG1PreprocessedPricingInfo.CurrentLimitedArcs;

	return *this;

}

//Arc setting functions:
//------------------------------------------------------------------------------------

//Filter all relevant arcs from the input Arcs, that is, filter out the 
//irrelevant arcs. The resulting relevant arcs are copied and stored in CurrentArcs.
void PStep_CG1PreprocessedPricingInfo::FilterRelevantArcs(std::forward_list<std::forward_list<PStep_Arc>>& Arcs, std::forward_list<std::forward_list<PStep_Arc>>& RelevantArcs){

	//Initialize the new arc list of the first location.
	auto NewList = RelevantArcs.begin();

	//Go over lists of arcs
	for (auto CurrentArcList = Arcs.begin(); CurrentArcList != Arcs.end();++CurrentArcList){
		//Empty the new list
		NewList->clear();
		//Go over all arcs in the current list
		for (auto Arc = CurrentArcList->begin(); Arc != CurrentArcList->end(); ++Arc){
			//Check whether the arc is relevant
			if (ArcIsRelevant[Arc->StartNode][Arc->EndNode]){
				//The arc is relevant, add a copy to the new list
				NewList->push_front(*Arc);
			}
		}
		//Update the new list
		++NewList;
	}

	//Select RelevantArcs
	SelectedArcs = &RelevantArcs;

}

//Neighborhood functions:
//------------------------------------------------------------------------------------

//Reset DSSN attributes
void PStep_CG1PreprocessedPricingInfo::ResetDSSRNeighbourhoods(){
	
	//Clear Neighbourhood information
	CurrentDSSRNeighbourhoods.clear();
	CurrentDSSRNotInNeighbourhood.clear();

	//Initialize template neighbourhood
	std::vector<int> NeighbourhoodTemplate;
	//Initialize template NotInNeighbourhood
	std::vector<bool> NotInNeighbourhoodTemplate;
	//As a default, set NotInNeighbourhoodTemplate as true for all customers
	for (int i = 0; i < NumberOfCustomers; ++i){
		NotInNeighbourhoodTemplate.push_back(true);
	}

	//Go over all customers
	for (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.push_back(NotInNeighbourhoodTemplate);
	}

}

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

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

	delete[]Reachable;

}

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

//Print info
void PStep_CG1PreprocessedPricingInfo::PrintInfo(){

	//Print
	std::cout << "Location one:           " << LocationOne << std::endl;
	std::cout << "Location two:           " << LocationTwo << std::endl;
	std::cout << "Capacity:               " << Capacity << std::endl;
	std::cout << "Maximum number of arcs: " << MaxNumberOfArcs << std::endl;
	std::cout << "Location recources: " << std::endl;
	for (int i = 0; i<NumberOfCustomers; i++){
		std::cout << i + 1 << " " << Reachable[i] << std::endl;
	}
	std::cout << "Relevant arcs:" << std::endl;
	for (int i = 0; i < NumberOfCustomers + 1; ++i){
		for (int j = 0; j < NumberOfCustomers + 1; ++j){
			std::cout << ArcIsRelevant[i][j] << " ";
		}
		std::cout << std::endl;
	}

}*/