/*Header file of the CVRPInstance class

Implementation can be found in CVRPInstance.cpp.

Declares the class CVRPInstanceGenerationSettings

*/

#ifndef _CVRPINSTANCE_H
#define _CVRPINSTANCE_H

#include <vector>
#include <iostream>
#include <sstream>
#include <fstream>
#include "RandomEngine.h"

//Class used to represent the settings used to generate a random CVRPInstance
class CVRPInstanceGenerationSettings{
public:

	//Number of customers
	short int NumberOfCustomers;
	//Type of customer Generation
	//1: Uniformly in a square with the depot in the center
	short int CustomerGenerationType;
	//When CustomerGenerationType=1, define the length of the square
	double CG1SquareSide;

	//Type of traveling costs:
	//1: Euclidean distance rounded to two decimal places
	short int TravelCostType;

	//Vehicle capacity
	double VehicleCapacity;

	//Demand generation settings:
	//Demand distribution
	//1 - Uniform rounded up
	short int DemandDistribution;

	//Lower and upper bound of the uniform distribution
	double DemandUniformLB;
	double DemandUniformUB;

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

	//Default constructor, creates empty settings
	CVRPInstanceGenerationSettings();

	//Basic Constructor 1:
	//Generates an instance in a square with the depot in the center, with euclidean
	//travel cosrs. The demand is drawn from a uniform distribution and rounded up to the nearest integer.
	//Input the number of customers, vehicle capacity, DemandUniformLB and DemandUniformUB.
	CVRPInstanceGenerationSettings(short int newNumberOfCustomers, double newVehicleCapacity, double newDemandUniformLB, double newDemandUniformUB);

};

//====================================================================================

//Class used to represent an instance of the CVRP
class CVRPInstance{
public:
	//Number of customers not including the depot
	short int NumberOfCustomers;

	//Vehicle Capacity
	double VehicleCapacity;

	//Indicator indicating whether the number of vehicles is fixed
	bool NumberOfVehiclesIsFixed;

	//The fixed number of vehicles, in case NumberOfVehicles=true.
	short int FixedNumberOfVehicles;

	//Coordinates of customers
	//CoordinatesLocations[i][j] is the x/y coordinate of location i for j=0/1.
	//The index 0 provides the depot.
	double **LocationCoordinates;

	//Demand
	//Demand[i] is the demand of customer i.
	//The index 0 provides customer 1.
	double *Demand;

	//Travel costs
	//TravelCosts[i][j] are the traveling costs from i to j.
	//The index 0 provides the depot.
	double **TravelCosts;

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

	//Default constructor, creates an empty instance
	CVRPInstance();

	//Copy constructor of CVRPInstance
	CVRPInstance(const CVRPInstance &OriginalCVRPInstance);

	//Construct an instance based on CVRPInstanceGenerationSettings
	CVRPInstance(CVRPInstanceGenerationSettings IGS);

	//Load an instance from a .txt file, the format can be deduced from the implementation
	CVRPInstance(const char* FileName);

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

	//= operator of CVRPInstance
	CVRPInstance operator=(CVRPInstance OriginalCVRPInstance);

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

	//Default destructor
	~CVRPInstance();

	//Converter functions
	//------------------------------------------------------------------------------------

	//Convert CVRP E with coordinates to a CVRP instance
	//Read an E coordinates instance and write a CVRPInstance.
	//The costs per arc are rounded to the nearest number with DecimalPlaces decimal places.
	void ConvertECoordinatesToCVRPInstance(const char* EFileName, const char* ConvertedFileName, short int NewFixedNumberOfVehicles, short int DecimalPlaces);

	//Convert CVRP E with edge costs to  a CVRP instance
	//Read an E edge instance and write a CVRPInstance.
	void ConvertEEdgeToCVRPInstance(const char* EFileName, const char* ConvertedFileName, short int NewFixedNumberOfVehicles);

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

	//Function to write the CVRP instance to file. The format can be deduced from the implementation.
	void Write(const char* FileName);

private:
	//Auxiliary functions
	//------------------------------------------------------------------------------------

	//Empty all entries
	void EmptyInstance();

	//Copy all entries
	//IMPORTANT: it is assumed that the current instance is empty!
	//It is also assumed that NumberOfCustomers corresponds to the array lengths
	void CopyEmptyAssumed(const CVRPInstance &OriginalCVRPInstance);

	//Generate location coordinates according to type 1
	//Uniformly in a square with the depot at the center.
	//Coordinates are rounded to 4 decimal places.
	void GenerateLocationCoordinates1(double SquareSide);

	//Generate demand according to structure 1
	//Uniformly distributed rounded up to the nearest integer.
	void GenerateDemand1(CVRPInstanceGenerationSettings IGS);

	//Generate fixed travel costs according to type 1
	//Euclidean distance
	void GenerateTravelCosts1();

};

#endif