#include "POSeqSel.h"
#define taskNum 50 
#define n 500 
#define probabilityNum 60 
#define constraint 5

float probabilityMatrice[taskNum][n][probabilityNum];

void ReadData()
{
	for (int t = 0; t < taskNum; t++)
	{
		string finalPath = "../Data/accomplishTaskInstance_" + to_string(t + 1) + ".txt";
		ifstream dataFile(finalPath);
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < probabilityNum; j++)
			{
				dataFile >> probabilityMatrice[t][i][j];
			}
		}
		dataFile.close();
	}
}

void OutputResult(vector<Individual> result)
{
	string finalPath ="../Result/accomplishTaskResult.txt";
	ofstream outFile(finalPath);
	for (unsigned int i = 0; i < result.size(); i++)
	{
		outFile << result[i].fitness << '\n';
		for (unsigned int j = 0; j < result[i].itemString.size(); j++)
		{
			outFile << result[i].itemString[j] + 1 << ' ';
		}
		outFile << '\n';
	}
	outFile << '\n';
}
float POSeqSel::EvaluateObjective(vector<int> itemString)
{
	unsigned int actionSize = itemString.size();
	if (actionSize > 2 * constraint)
	{
		return 0;
	}
	float finalObjective = 0, *objective = new float[taskNum];
	for (int i = 0; i < taskNum; i++)
	{
		objective[i] = 1.0;
	}
	for (int i = 0; i < taskNum; i++)
	{
		for (int j = 0; j < actionSize; j++)
		{
			objective[i] = objective[i] * (1.0 - probabilityMatrice[i][itemString[j]][j]);
		}
	}
	for (int i = 0; i < taskNum; i++)
	{
		finalObjective = finalObjective + (1.0 - objective[i]);
	}
	delete[] objective;
	return finalObjective*1.0 / taskNum;
}


int main()
{
	srand((unsigned)time(NULL));
	//input the data
	ReadData();

	//Set parameters.
	POSeqSel algorithm = POSeqSel();
	algorithm.SetConstraint(constraint);
	algorithm.SetSize(n);
	long iterationTime = 2 * exp(1)*constraint*constraint*(constraint + 1) * n;
	algorithm.SetIterationTime(iterationTime);
	algorithm.SetIsRepetition(true);//allow the same action in the action string.

	//Do the algorithm.
	algorithm.DOPOSeqSel();

	//Output the result. Get one result every constraint*n iterations.
	vector<Individual> result = algorithm.ReturnResult();
	OutputResult(result);
	return 0;
}
