/*****************************************************************//**
 * /file   main.cpp
 * /brief  The main function that calls the Branch and Price framework with a specific instance and the specific Restricted Master Problem, Pricing Problem, Search Strategy and Branching Strategy.
 * 
 * /author talmefta
 * /date   May 2022
 *********************************************************************/

#include "KEPsolver.h"
#include "HalfCycleFormulation.h"
#include "Picef.h"
#include "Hpief.h"

int Exchange::lastId = 0;

int main(int argc, char** argv) {

	//path_folder = path to the folder where the instances are located
	//name = name of the instance
	//isMedicalBenefit must be set to true for the instances where the objective function is the maximisation of the medical benefit, 
	//							   to false  for the instances where the objective function is the maximisation of the number of transplants
	//isBPC = true to run the BPC algorithm presented in the paper
	//isHpief = true to run the solver on the Hpief formulation by
	//isPicef = true to run the solver on the Picef formulation by
	//time_limit = time limit for the run

	string path_folder = "C:\\Users\\mogier\\Desktop\\Research\\Code\\KEP_IIKEP\\Instances\\KEP\\Pansart\\";
	string name = "KEP_p50_n3_k3_l3_0";
	bool isMedicalBenefit = true;
	bool isHpief = true;
	bool isPicef = false;
	bool isBPC = false;
	double time_limit = 3600.0;

	::instanceName = name;
	//Create directory for results
	::solutionPath = "solutions_" + ::thread + "/";
	if (_mkdir(::solutionPath.c_str()) == 0) {
		cout << "Solution folder created\n";
	}
	else {
		cout << "Solution folder NOT created:\t" << ::solutionPath << endl;
	}

	int ngSetSize = 5;
	bool arePathsPriced = true;
	bool areCyclesPriced = true;
	Instance instance(path_folder, name, isMedicalBenefit);
	instance.processData(ngSetSize);
	cout << "Instance Read" << endl;

	cout << "---Instance" << endl;
	cout << instance.toString(true) << endl;

	if (isPicef) {
		//Picef
		int aux = instance.getExchangesPerVertexInitialisation();
		int maxint = ::OMEGA * 10;
		instance.set_exchangesPerVertexInitialisation(maxint);
		clock_t start_cycles = clock();
		Exchange::restartIds();
		CyclesInitializer cycles(instance);
		vector<Exchange> all_cycles = cycles.initialize("WHATEVER");
		clock_t end_cycles = clock();
		double duration = (double)(end_cycles - start_cycles) / CLOCKS_PER_SEC;
		instance.set_exchangesPerVertexInitialisation(aux);

		Picef picef = Picef(instance, name, all_cycles, time_limit);
		picef.solve(duration);
		cout << picef.toString() << endl;

	}

	if (isHpief) {
		//Hpief
		Hpief hpief = Hpief(instance, name, time_limit);
		hpief.solve();
		cout << hpief.toString() << endl;

	}

	if (isBPC) {
		KEPsolver kepSolver = KEPsolver(&instance, name, "KEP");
		kepSolver.solve(arePathsPriced, areCyclesPriced, time_limit);
	}

	
	return 0;

}