#include "pch.h" #include "RunData.h" #include #include #include RunData::RunData() { } RunData::RunData(std::string filePath): fileStream(filePath) { if (!fileStream.is_open()) { //Cant open file badFileFlag = true; return; } /* Start extracting */ while (fileStream.peek() != EOF) { std::string buffer; getLine(buffer); SolutionPointData sol; std::regex regexIter("i:([\\+\\-]?\\d+)"); std::regex regexObjectiveFunction("of:([\\+\\-]?\\d+\\.\\d+(?:E[\\+\\-]\\d+)?)"); std::smatch match; if (!std::regex_search(buffer, match, regexIter)) { qDebug() << "Bad formatatted Line[" << actualLine << "]."; qDebug() << "Failed to matched:"; qDebug() << QString::fromStdString(buffer); return; } sol.iteration = std::stoi(match[1]); if (!std::regex_search(buffer, match, regexObjectiveFunction)) { qDebug() << "Bad formatatted Line[" << actualLine << "]."; qDebug() << "Failed to matched:"; qDebug() << QString::fromStdString(buffer); return; } sol.objectiveFunction = std::stod(match[1]); std::regex regexParticleNumber("pN:([\\+\\-]?\\d+)"); if (!std::regex_search(buffer, match, regexParticleNumber)) { qDebug() << "Bad formatatted Line[" << actualLine << "]."; qDebug() << "Failed to matched:"; qDebug() << QString::fromStdString(buffer); return; } sol.particleNumber = std::stoi(match[1]); std::regex regexBitVec("b:([01]+)"); if(!std::regex_search(buffer, match, regexBitVec)) { qDebug() << "Bad formatatted Line[" << actualLine << "]."; qDebug() << "Failed to matched:"; qDebug() << QString::fromStdString(buffer); return; } sol.bitVec.resize(match[1].length()); int count = 0; std::string str = match[1]; for (std::string::size_type i = 0; i < str.size(); ++i) { sol.bitVec[i] = (str[i] == '1'); } solutionVec.push_back(sol); } fileStream.close(); calculateBestAndAverageIter(); calculateParticleSolution(); calculateDotsForDistribution(); generateRandomBitFieldData(); } void RunData::getLine(std::string& bufferString) { std::getline(fileStream, bufferString); actualLine++; } void RunData::calculateBestAndAverageIter() { if (solutionVec.empty()) { return; } double minObjectiveFunctionInIter = solutionVec[0].objectiveFunction; double maxObjectiveFunctionInIter = solutionVec[0].objectiveFunction; double bestObjectiveFunctionFound = solutionVec[0].objectiveFunction; double actualIterObjectiveFunctionAggregate = solutionVec[0].objectiveFunction; int actualIter = solutionVec[0].iteration; int foundSolutionInIteration = 1; for(int i = 1; i < solutionVec.size(); i++) { SolutionPointData nextData = solutionVec[i]; if (nextData.iteration != actualIter) { //save last bestSolutionPerIteration.push_back(GraphDataPoint((double)actualIter, bestObjectiveFunctionFound)); averageSolutionPerItertion.push_back(GraphDataPoint((double)actualIter, actualIterObjectiveFunctionAggregate / (double)foundSolutionInIteration)); minSolutionPerItertion.push_back(GraphDataPoint((double)actualIter, minObjectiveFunctionInIter)); maxSolutionPerItertion.push_back(GraphDataPoint((double)actualIter, maxObjectiveFunctionInIter)); //init new iteration actualIter = nextData.iteration; foundSolutionInIteration = 1; actualIterObjectiveFunctionAggregate = nextData.objectiveFunction; minObjectiveFunctionInIter = nextData.objectiveFunction; maxObjectiveFunctionInIter = nextData.objectiveFunction; } else { //increae aggregate foundSolutionInIteration++; actualIterObjectiveFunctionAggregate += nextData.objectiveFunction; } //update best min and max if better if (nextData.objectiveFunction < bestObjectiveFunctionFound) { bestObjectiveFunctionFound = nextData.objectiveFunction; } if (nextData.objectiveFunction < minObjectiveFunctionInIter) { minObjectiveFunctionInIter = nextData.objectiveFunction; } if (nextData.objectiveFunction > maxObjectiveFunctionInIter) { maxObjectiveFunctionInIter = nextData.objectiveFunction; } } //save last iteration bestSolutionPerIteration.push_back(GraphDataPoint((double)actualIter, bestObjectiveFunctionFound)); averageSolutionPerItertion.push_back(GraphDataPoint((double)actualIter, actualIterObjectiveFunctionAggregate / (double)foundSolutionInIteration)); minSolutionPerItertion.push_back(GraphDataPoint((double)actualIter, minObjectiveFunctionInIter)); maxSolutionPerItertion.push_back(GraphDataPoint((double)actualIter, maxObjectiveFunctionInIter)); } void RunData::calculateParticleSolution() { for (SolutionPointData sol : solutionVec) { GraphDataPoint point(sol.iteration, sol.objectiveFunction, &sol); auto iter = particleMap.find(sol.particleNumber); if (iter == particleMap.end()) { //create new Entry std::vector vec; vec.push_back(point); particleMap.insert({ sol.particleNumber, vec}); } else { //append to vector in Entry iter->second.push_back(point); } } } void RunData::calculateDotsForDistribution() { for (SolutionPointData sol : solutionVec) { dotsForDistribution.push_back(GraphDataPoint((double)sol.iteration, sol.objectiveFunction, &sol)); } } int binominalIndex(const int n, const int k) { return n * (n + 1) / 2 + k; } boost::multiprecision::cpp_int positionInPermutation2(std::vector& pascalTriangleVec, std::vector::iterator begin, std::vector::iterator end, int amountOfSetBits) { int amountOfBits = end - begin; //recursion base if (amountOfSetBits == 0) return 1; std::vector::iterator indexIter = std::find(begin, end, true); int index = indexIter - begin; int amountOfBitsAfterIndex = amountOfBits - 1 - index; //recursion base if (amountOfSetBits == 1) return amountOfBits - index; //Step 1 the amount of permutations with the rest amountOfBitsAfterIndex boost::multiprecision::cpp_int before = pascalTriangleVec[binominalIndex(amountOfBitsAfterIndex, amountOfSetBits)]; //Step 2 teh actual position of the rest boost::multiprecision::cpp_int after = positionInPermutation2(pascalTriangleVec, ++indexIter, end, amountOfSetBits - 1); //setp 3 add Step 1 and Step 2 return before + after; } void RunData::generateRandomBitFieldData() { std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now(); int amountOfBits = solutionVec[0].bitVec.size(); //for (SolutionPointData sol : solutionVec) { // int amountOfSetBits = std::count(sol.bitVec.begin(), sol.bitVec.end(), true); // boost::multiprecision::cpp_dec_float_100 position(positionInPermutation(sol.bitVec.begin(), sol.bitVec.end(), amountOfSetBits) - 1); // boost::multiprecision::cpp_dec_float_100 maxAmountOfPermutaions (binominal(amountOfBits, amountOfSetBits) - 1); // testForBitField.push_back(GraphDataPoint((position / maxAmountOfPermutaions).convert_to(), amountOfSetBits)); //} //std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); //std::chrono::milliseconds time = std::chrono::duration_cast(end - start); //qDebug() << "BitField: " << time.count() << "ms"; int lines = amountOfBits + 1; std::vector pascalTriangleVec((lines * (lines + 1)) / 2); for (int line = 0; line < lines; line++) { for (int number = 0; number < line + 1; number++) { if (number == 0 || number == line) { pascalTriangleVec[binominalIndex(line, number)] = 1; } else { pascalTriangleVec[binominalIndex(line, number)] = pascalTriangleVec[binominalIndex(line - 1, number)] + pascalTriangleVec[binominalIndex(line - 1, number - 1)]; } } } std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); std::chrono::milliseconds time = std::chrono::duration_cast(end - start); qDebug() << "PascalTriangle: " << time.count() << "ms"; for (SolutionPointData sol : solutionVec) { int amountOfSetBits = std::count(sol.bitVec.begin(), sol.bitVec.end(), true); boost::multiprecision::cpp_dec_float_100 position(positionInPermutation2(pascalTriangleVec, sol.bitVec.begin(), sol.bitVec.end(), amountOfSetBits) - 1); boost::multiprecision::cpp_dec_float_100 maxAmountOfPermutaions (pascalTriangleVec[binominalIndex(amountOfBits, amountOfSetBits)] - 1); testForBitField.push_back(GraphDataPoint((position / maxAmountOfPermutaions).convert_to(), amountOfSetBits)); } std::chrono::high_resolution_clock::time_point end2 = std::chrono::high_resolution_clock::now(); time = std::chrono::duration_cast(end2 - end); qDebug() << "PascalTriangle: " << time.count() << "ms"; } boost::multiprecision::cpp_int RunData::binominal(const int n,int k) { boost::multiprecision::cpp_int value(1); if (k > n / 2) k = n - k; for (int i = 0; i < k; i++) { value *= boost::multiprecision::cpp_int(n - i); value /= boost::multiprecision::cpp_int(i + 1); } return value; } boost::multiprecision::cpp_int RunData::positionInPermutation(std::vector::iterator begin, std::vector::iterator end, int amountOfSetBits) { int amountOfBits = end - begin; //recursion base if (amountOfSetBits == 0) return 1; std::vector::iterator indexIter = std::find(begin, end, true); int index = indexIter - begin; int amountOfBitsAfterIndex = amountOfBits - 1 - index; //recursion base if (amountOfSetBits == 1) return amountOfBits - index; //Step 1 the amount of permutations with the rest amountOfBitsAfterIndex boost::multiprecision::cpp_int before = binominal(amountOfBitsAfterIndex, amountOfSetBits); //Step 2 teh actual position of the rest boost::multiprecision::cpp_int after = positionInPermutation(++indexIter, end, amountOfSetBits - 1); //setp 3 add Step 1 and Step 2 return before + after; }