|
@@ -152,10 +152,100 @@ void RunData::calculateDotsForDistribution()
|
|
dotsForDistribution.push_back(GraphDataPoint((double)sol.iteration, sol.objectiveFunction, &sol));
|
|
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()
|
|
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) {
|
|
for (SolutionPointData sol : solutionVec) {
|
|
- testForBitField.push_back(GraphDataPoint(0.5, std::count(sol.bitVec.begin(), sol.bitVec.end(), true)));
|
|
|
|
|
|
+ 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;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|