RunData.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. #include "pch.h"
  2. #include "RunData.h"
  3. #include <QDebug>
  4. #include <QString>
  5. #include <regex>
  6. RunData::RunData()
  7. {
  8. }
  9. RunData::RunData(std::string filePath): fileStream(filePath)
  10. {
  11. if (!fileStream.is_open())
  12. {
  13. //Cant open file
  14. badFileFlag = true;
  15. return;
  16. }
  17. /* Start extracting */
  18. while (fileStream.peek() != EOF) {
  19. std::string buffer;
  20. getLine(buffer);
  21. SolutionPointData sol;
  22. std::regex regexIter("i:([\\+\\-]?\\d+)");
  23. std::regex regexObjectiveFunction("of:([\\+\\-]?\\d+\\.\\d+(?:E[\\+\\-]\\d+)?)");
  24. std::smatch match;
  25. if (!std::regex_search(buffer, match, regexIter)) {
  26. qDebug() << "Bad formatatted Line[" << actualLine << "].";
  27. qDebug() << "Failed to matched:";
  28. qDebug() << QString::fromStdString(buffer);
  29. return;
  30. }
  31. sol.iteration = std::stoi(match[1]);
  32. if (!std::regex_search(buffer, match, regexObjectiveFunction)) {
  33. qDebug() << "Bad formatatted Line[" << actualLine << "].";
  34. qDebug() << "Failed to matched:";
  35. qDebug() << QString::fromStdString(buffer);
  36. return;
  37. }
  38. sol.objectiveFunction = std::stod(match[1]);
  39. std::regex regexParticleNumber("pN:([\\+\\-]?\\d+)");
  40. if (!std::regex_search(buffer, match, regexParticleNumber)) {
  41. qDebug() << "Bad formatatted Line[" << actualLine << "].";
  42. qDebug() << "Failed to matched:";
  43. qDebug() << QString::fromStdString(buffer);
  44. return;
  45. }
  46. sol.particleNumber = std::stoi(match[1]);
  47. std::regex regexBitVec("b:([01]+)");
  48. if(!std::regex_search(buffer, match, regexBitVec)) {
  49. qDebug() << "Bad formatatted Line[" << actualLine << "].";
  50. qDebug() << "Failed to matched:";
  51. qDebug() << QString::fromStdString(buffer);
  52. return;
  53. }
  54. sol.bitVec.resize(match[1].length());
  55. int count = 0;
  56. std::string str = match[1];
  57. for (std::string::size_type i = 0; i < str.size(); ++i) {
  58. sol.bitVec[i] = (str[i] == '1');
  59. }
  60. solutionVec.push_back(sol);
  61. }
  62. fileStream.close();
  63. calculateBestAndAverageIter();
  64. calculateParticleSolution();
  65. calculateDotsForDistribution();
  66. generateRandomBitFieldData();
  67. }
  68. void RunData::getLine(std::string& bufferString)
  69. {
  70. std::getline(fileStream, bufferString);
  71. actualLine++;
  72. }
  73. void RunData::calculateBestAndAverageIter()
  74. {
  75. if (solutionVec.empty()) {
  76. return;
  77. }
  78. double minObjectiveFunctionInIter = solutionVec[0].objectiveFunction;
  79. double maxObjectiveFunctionInIter = solutionVec[0].objectiveFunction;
  80. double bestObjectiveFunctionFound = solutionVec[0].objectiveFunction;
  81. double actualIterObjectiveFunctionAggregate = solutionVec[0].objectiveFunction;
  82. int actualIter = solutionVec[0].iteration;
  83. int foundSolutionInIteration = 1;
  84. for(int i = 1; i < solutionVec.size(); i++) {
  85. SolutionPointData nextData = solutionVec[i];
  86. if (nextData.iteration != actualIter) {
  87. //save last
  88. bestSolutionPerIteration.push_back(GraphDataPoint((double)actualIter, bestObjectiveFunctionFound));
  89. averageSolutionPerItertion.push_back(GraphDataPoint((double)actualIter, actualIterObjectiveFunctionAggregate / (double)foundSolutionInIteration));
  90. minSolutionPerItertion.push_back(GraphDataPoint((double)actualIter, minObjectiveFunctionInIter));
  91. maxSolutionPerItertion.push_back(GraphDataPoint((double)actualIter, maxObjectiveFunctionInIter));
  92. //init new iteration
  93. actualIter = nextData.iteration;
  94. foundSolutionInIteration = 1;
  95. actualIterObjectiveFunctionAggregate = nextData.objectiveFunction;
  96. minObjectiveFunctionInIter = nextData.objectiveFunction;
  97. maxObjectiveFunctionInIter = nextData.objectiveFunction;
  98. }
  99. else {
  100. //increae aggregate
  101. foundSolutionInIteration++;
  102. actualIterObjectiveFunctionAggregate += nextData.objectiveFunction;
  103. }
  104. //update best min and max if better
  105. if (nextData.objectiveFunction < bestObjectiveFunctionFound) {
  106. bestObjectiveFunctionFound = nextData.objectiveFunction;
  107. }
  108. if (nextData.objectiveFunction < minObjectiveFunctionInIter) {
  109. minObjectiveFunctionInIter = nextData.objectiveFunction;
  110. }
  111. if (nextData.objectiveFunction > maxObjectiveFunctionInIter) {
  112. maxObjectiveFunctionInIter = nextData.objectiveFunction;
  113. }
  114. }
  115. //save last iteration
  116. bestSolutionPerIteration.push_back(GraphDataPoint((double)actualIter, bestObjectiveFunctionFound));
  117. averageSolutionPerItertion.push_back(GraphDataPoint((double)actualIter, actualIterObjectiveFunctionAggregate / (double)foundSolutionInIteration));
  118. minSolutionPerItertion.push_back(GraphDataPoint((double)actualIter, minObjectiveFunctionInIter));
  119. maxSolutionPerItertion.push_back(GraphDataPoint((double)actualIter, maxObjectiveFunctionInIter));
  120. }
  121. void RunData::calculateParticleSolution()
  122. {
  123. for (SolutionPointData sol : solutionVec) {
  124. GraphDataPoint point(sol.iteration, sol.objectiveFunction, &sol);
  125. auto iter = particleMap.find(sol.particleNumber);
  126. if (iter == particleMap.end()) {
  127. //create new Entry
  128. std::vector<GraphDataPoint> vec;
  129. vec.push_back(point);
  130. particleMap.insert({ sol.particleNumber, vec});
  131. }
  132. else {
  133. //append to vector in Entry
  134. iter->second.push_back(point);
  135. }
  136. }
  137. }
  138. void RunData::calculateDotsForDistribution()
  139. {
  140. for (SolutionPointData sol : solutionVec) {
  141. dotsForDistribution.push_back(GraphDataPoint((double)sol.iteration, sol.objectiveFunction, &sol));
  142. }
  143. }
  144. int binominalIndex(const int n, const int k)
  145. {
  146. return n * (n + 1) / 2 + k;
  147. }
  148. boost::multiprecision::cpp_int positionInPermutation2(std::vector<boost::multiprecision::cpp_int>& pascalTriangleVec, std::vector<bool>::iterator begin, std::vector<bool>::iterator end, int amountOfSetBits)
  149. {
  150. int amountOfBits = end - begin;
  151. //recursion base
  152. if (amountOfSetBits == 0) return 1;
  153. std::vector<bool>::iterator indexIter = std::find(begin, end, true);
  154. int index = indexIter - begin;
  155. int amountOfBitsAfterIndex = amountOfBits - 1 - index;
  156. //recursion base
  157. if (amountOfSetBits == 1) return amountOfBits - index;
  158. //Step 1 the amount of permutations with the rest amountOfBitsAfterIndex
  159. boost::multiprecision::cpp_int before = pascalTriangleVec[binominalIndex(amountOfBitsAfterIndex, amountOfSetBits)];
  160. //Step 2 teh actual position of the rest
  161. boost::multiprecision::cpp_int after = positionInPermutation2(pascalTriangleVec, ++indexIter, end, amountOfSetBits - 1);
  162. //setp 3 add Step 1 and Step 2
  163. return before + after;
  164. }
  165. void RunData::generateRandomBitFieldData()
  166. {
  167. std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
  168. int amountOfBits = solutionVec[0].bitVec.size();
  169. //for (SolutionPointData sol : solutionVec) {
  170. // int amountOfSetBits = std::count(sol.bitVec.begin(), sol.bitVec.end(), true);
  171. // boost::multiprecision::cpp_dec_float_100 position(positionInPermutation(sol.bitVec.begin(), sol.bitVec.end(), amountOfSetBits) - 1);
  172. // boost::multiprecision::cpp_dec_float_100 maxAmountOfPermutaions (binominal(amountOfBits, amountOfSetBits) - 1);
  173. // testForBitField.push_back(GraphDataPoint((position / maxAmountOfPermutaions).convert_to<double>(), amountOfSetBits));
  174. //}
  175. //std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
  176. //std::chrono::milliseconds time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
  177. //qDebug() << "BitField: " << time.count() << "ms";
  178. int lines = amountOfBits + 1;
  179. std::vector<boost::multiprecision::cpp_int> pascalTriangleVec((lines * (lines + 1)) / 2);
  180. for (int line = 0; line < lines; line++) {
  181. for (int number = 0; number < line + 1; number++) {
  182. if (number == 0 || number == line) {
  183. pascalTriangleVec[binominalIndex(line, number)] = 1;
  184. }
  185. else {
  186. pascalTriangleVec[binominalIndex(line, number)] = pascalTriangleVec[binominalIndex(line - 1, number)] + pascalTriangleVec[binominalIndex(line - 1, number - 1)];
  187. }
  188. }
  189. }
  190. std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
  191. std::chrono::milliseconds time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
  192. qDebug() << "PascalTriangle: " << time.count() << "ms";
  193. for (SolutionPointData sol : solutionVec) {
  194. int amountOfSetBits = std::count(sol.bitVec.begin(), sol.bitVec.end(), true);
  195. boost::multiprecision::cpp_dec_float_100 position(positionInPermutation2(pascalTriangleVec, sol.bitVec.begin(), sol.bitVec.end(), amountOfSetBits) - 1);
  196. boost::multiprecision::cpp_dec_float_100 maxAmountOfPermutaions (pascalTriangleVec[binominalIndex(amountOfBits, amountOfSetBits)] - 1);
  197. testForBitField.push_back(GraphDataPoint((position / maxAmountOfPermutaions).convert_to<double>(), amountOfSetBits));
  198. }
  199. std::chrono::high_resolution_clock::time_point end2 = std::chrono::high_resolution_clock::now();
  200. time = std::chrono::duration_cast<std::chrono::milliseconds>(end2 - end);
  201. qDebug() << "PascalTriangle: " << time.count() << "ms";
  202. }
  203. boost::multiprecision::cpp_int RunData::binominal(const int n,int k)
  204. {
  205. boost::multiprecision::cpp_int value(1);
  206. if (k > n / 2) k = n - k;
  207. for (int i = 0; i < k; i++) {
  208. value *= boost::multiprecision::cpp_int(n - i);
  209. value /= boost::multiprecision::cpp_int(i + 1);
  210. }
  211. return value;
  212. }
  213. boost::multiprecision::cpp_int RunData::positionInPermutation(std::vector<bool>::iterator begin, std::vector<bool>::iterator end, int amountOfSetBits)
  214. {
  215. int amountOfBits = end - begin;
  216. //recursion base
  217. if (amountOfSetBits == 0) return 1;
  218. std::vector<bool>::iterator indexIter = std::find(begin, end, true);
  219. int index = indexIter - begin;
  220. int amountOfBitsAfterIndex = amountOfBits - 1 - index;
  221. //recursion base
  222. if (amountOfSetBits == 1) return amountOfBits - index;
  223. //Step 1 the amount of permutations with the rest amountOfBitsAfterIndex
  224. boost::multiprecision::cpp_int before = binominal(amountOfBitsAfterIndex, amountOfSetBits);
  225. //Step 2 teh actual position of the rest
  226. boost::multiprecision::cpp_int after = positionInPermutation(++indexIter, end, amountOfSetBits - 1);
  227. //setp 3 add Step 1 and Step 2
  228. return before + after;
  229. }