Browse Source

Pascal Triangle

Tom Troppmann 4 years ago
parent
commit
3c33cb6c85
3 changed files with 120 additions and 4 deletions
  1. 91 1
      metavis/RunData.cpp
  2. 4 0
      metavis/RunData.h
  3. 25 3
      metaviscon/metaviscon.cpp

+ 91 - 1
metavis/RunData.cpp

@@ -152,10 +152,100 @@ void RunData::calculateDotsForDistribution()
         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) {
-        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;
+}
+
+

+ 4 - 0
metavis/RunData.h

@@ -4,6 +4,8 @@
 #include <fstream>
 #include <QPoint>
 #include <map>
+#include <boost/multiprecision/cpp_int.hpp>
+#include <boost/multiprecision/cpp_dec_float.hpp>
 #include "GraphView.h"
 
 
@@ -45,5 +47,7 @@ private:
 	void calculateDotsForDistribution();
 	void generateRandomBitFieldData();
 
+	boost::multiprecision::cpp_int binominal(const int n, const int k);
+	boost::multiprecision::cpp_int positionInPermutation(std::vector<bool>::iterator begin, std::vector<bool>::iterator end, int amountOfSetBits);
 };
 

+ 25 - 3
metaviscon/metaviscon.cpp

@@ -1,13 +1,35 @@
 
 
 #include <iostream>
-#include "Test.h"
+
+int binominalIndex(const int n, const int k);
+
 
 int main(int argc, char * argv[] )
 {
 	if(argc > 1)
     std::cout << "Hello World! " << argv[1] << std::endl;
-	Test q;
-	std::cout << q.b << std::endl;
+	std::cout << "PascalTriangle" << std::endl;
+	int memory[45];
+	for (int line = 0; line < 9; line++) {
+		for (int number = 0; number < line + 1; number++) {
+			if (number == 0 || number == line) {
+				memory[binominalIndex(line,number)] = 1;
+			}
+			else {
+				memory[binominalIndex(line, number)] = memory[binominalIndex(line -1, number)] + memory[binominalIndex(line - 1, number - 1)];
+			}
+
+		}
+	}
+	for (int zeile = 0; zeile < 9; zeile++) {
+		for (int number = 0; number < zeile + 1; number++) {
+			std::cout << " " << memory[binominalIndex(zeile, number)];
+
+		}
+		std::cout << std::endl;
+	}
 	return 0;
 }
+
+