123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- #include "pch.h"
- #include "RunData.h"
- #include <QDebug>
- #include <QString>
- #include <regex>
- 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<GraphDataPoint> 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<boost::multiprecision::cpp_int>& pascalTriangleVec, std::vector<bool>::iterator begin, std::vector<bool>::iterator end, int amountOfSetBits)
- {
- int amountOfBits = end - begin;
- //recursion base
- if (amountOfSetBits == 0) return 1;
- std::vector<bool>::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<double>(), amountOfSetBits));
- //}
- //std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
- //std::chrono::milliseconds time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
- //qDebug() << "BitField: " << time.count() << "ms";
- int lines = amountOfBits + 1;
- std::vector<boost::multiprecision::cpp_int> 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<std::chrono::milliseconds>(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<double>(), amountOfSetBits));
- }
- std::chrono::high_resolution_clock::time_point end2 = std::chrono::high_resolution_clock::now();
- time = std::chrono::duration_cast<std::chrono::milliseconds>(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<bool>::iterator begin, std::vector<bool>::iterator end, int amountOfSetBits)
- {
- int amountOfBits = end - begin;
- //recursion base
- if (amountOfSetBits == 0) return 1;
- std::vector<bool>::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;
- }
|