diff --git a/cmake-build-relwithdebinfo/.ninja_deps b/cmake-build-relwithdebinfo/.ninja_deps index b4e0ee6..f52e910 100644 Binary files a/cmake-build-relwithdebinfo/.ninja_deps and b/cmake-build-relwithdebinfo/.ninja_deps differ diff --git a/cmake-build-relwithdebinfo/.ninja_log b/cmake-build-relwithdebinfo/.ninja_log index 37ae514..d1c00b4 100644 --- a/cmake-build-relwithdebinfo/.ninja_log +++ b/cmake-build-relwithdebinfo/.ninja_log @@ -433,3 +433,16 @@ 1637 1793 1689815127566015790 parksnrec fc63db74fd58366e 4 1712 1689815769560520877 CMakeFiles/parksnrec.dir/src/genetic/v3/program_v3.cpp.o 7203e7cb37c07468 1713 1866 1689815769710517695 parksnrec fc63db74fd58366e +4 1545 1689818500350353204 CMakeFiles/parksnrec.dir/src/genetic/v3/functions_v3.cpp.o 2851fa30bacfc7d5 +5 1938 1689818500743686832 CMakeFiles/parksnrec.dir/src/parks/renderer/engine.cpp.o 875432a17ebda434 +4 2018 1689818500820353556 CMakeFiles/parksnrec.dir/src/genetic/v3/program_v3.cpp.o 7203e7cb37c07468 +2018 2184 1689818500987020348 parksnrec fc63db74fd58366e +5 1817 1689818610000447805 CMakeFiles/parksnrec.dir/src/parks/renderer/engine.cpp.o 875432a17ebda434 +4 1854 1689818610037114507 CMakeFiles/parksnrec.dir/src/genetic/v3/program_v3.cpp.o 7203e7cb37c07468 +1854 2011 1689818610193781326 parksnrec fc63db74fd58366e +4 1811 1689818644790482576 CMakeFiles/parksnrec.dir/src/genetic/v3/program_v3.cpp.o 7203e7cb37c07468 +1811 1969 1689818644950482741 parksnrec fc63db74fd58366e +4 1427 1689818705053880876 CMakeFiles/parksnrec.dir/src/genetic/v3/functions_v3.cpp.o 2851fa30bacfc7d5 +4 1842 1689818705467214674 CMakeFiles/parksnrec.dir/src/parks/renderer/engine.cpp.o 875432a17ebda434 +4 1886 1689818705510548056 CMakeFiles/parksnrec.dir/src/genetic/v3/program_v3.cpp.o 7203e7cb37c07468 +1886 2044 1689818705667214899 parksnrec fc63db74fd58366e diff --git a/cmake-build-relwithdebinfo/2023-7-19_22-1-41.log b/cmake-build-relwithdebinfo/2023-7-19_22-1-41.log new file mode 100644 index 0000000..e69de29 diff --git a/cmake-build-relwithdebinfo/2023-7-19_22-3-30.log b/cmake-build-relwithdebinfo/2023-7-19_22-3-30.log new file mode 100644 index 0000000..e69de29 diff --git a/cmake-build-relwithdebinfo/2023-7-19_22-4-5.log b/cmake-build-relwithdebinfo/2023-7-19_22-4-5.log new file mode 100644 index 0000000..e69de29 diff --git a/cmake-build-relwithdebinfo/2023-7-19_22-5-5.log b/cmake-build-relwithdebinfo/2023-7-19_22-5-5.log new file mode 100644 index 0000000..e69de29 diff --git a/cmake-build-relwithdebinfo/CMakeFiles/parksnrec.dir/src/genetic/v3/functions_v3.cpp.o b/cmake-build-relwithdebinfo/CMakeFiles/parksnrec.dir/src/genetic/v3/functions_v3.cpp.o index c2680ad..691366b 100644 Binary files a/cmake-build-relwithdebinfo/CMakeFiles/parksnrec.dir/src/genetic/v3/functions_v3.cpp.o and b/cmake-build-relwithdebinfo/CMakeFiles/parksnrec.dir/src/genetic/v3/functions_v3.cpp.o differ diff --git a/cmake-build-relwithdebinfo/CMakeFiles/parksnrec.dir/src/genetic/v3/program_v3.cpp.o b/cmake-build-relwithdebinfo/CMakeFiles/parksnrec.dir/src/genetic/v3/program_v3.cpp.o index 57562a3..df6b64e 100644 Binary files a/cmake-build-relwithdebinfo/CMakeFiles/parksnrec.dir/src/genetic/v3/program_v3.cpp.o and b/cmake-build-relwithdebinfo/CMakeFiles/parksnrec.dir/src/genetic/v3/program_v3.cpp.o differ diff --git a/cmake-build-relwithdebinfo/CMakeFiles/parksnrec.dir/src/parks/renderer/engine.cpp.o b/cmake-build-relwithdebinfo/CMakeFiles/parksnrec.dir/src/parks/renderer/engine.cpp.o index 2650d2a..923129f 100644 Binary files a/cmake-build-relwithdebinfo/CMakeFiles/parksnrec.dir/src/parks/renderer/engine.cpp.o and b/cmake-build-relwithdebinfo/CMakeFiles/parksnrec.dir/src/parks/renderer/engine.cpp.o differ diff --git a/cmake-build-relwithdebinfo/Testing/Temporary/LastTest.log b/cmake-build-relwithdebinfo/Testing/Temporary/LastTest.log index 077c311..d0cf550 100644 --- a/cmake-build-relwithdebinfo/Testing/Temporary/LastTest.log +++ b/cmake-build-relwithdebinfo/Testing/Temporary/LastTest.log @@ -1,3 +1,3 @@ -Start testing: Jul 19 21:16 EDT +Start testing: Jul 19 22:05 EDT ---------------------------------------------------------- -End testing: Jul 19 21:16 EDT +End testing: Jul 19 22:05 EDT diff --git a/cmake-build-relwithdebinfo/parksnrec b/cmake-build-relwithdebinfo/parksnrec index 784ab9a..c38851c 100755 Binary files a/cmake-build-relwithdebinfo/parksnrec and b/cmake-build-relwithdebinfo/parksnrec differ diff --git a/include/genetic/v3/arguments.h b/include/genetic/v3/arguments.h index 7411594..0650ea1 100644 --- a/include/genetic/v3/arguments.h +++ b/include/genetic/v3/arguments.h @@ -10,7 +10,10 @@ namespace parks::genetic { constexpr double d = 0.4; - constexpr double m = 0.2; + constexpr double nodeMutationChance = 0.2; + constexpr double scalarMutationChance = 0.2; + constexpr double colorMutationChance = 0.2; + constexpr double functionMutationChance = 0.2; struct Color { double r, g, b; diff --git a/include/genetic/v3/functions_v3.h b/include/genetic/v3/functions_v3.h index 85a1c43..902ec3e 100644 --- a/include/genetic/v3/functions_v3.h +++ b/include/genetic/v3/functions_v3.h @@ -97,6 +97,15 @@ namespace parks::genetic { return acceptsArgs & ARGS_FUNCS; } + [[nodiscard]] inline unsigned int getRequiredScalars() const{ + return requiredScalars; + } + + [[nodiscard]] inline unsigned int getRequiredColors() const{ + return requiredColors; + } + + [[nodiscard]] ParameterSet generateRandomParameters() const { ParameterSet set; for (unsigned int i = 0; i < requiredScalars; i++) diff --git a/include/genetic/v3/program_v3.h b/include/genetic/v3/program_v3.h index 4b87b47..446e3cd 100644 --- a/include/genetic/v3/program_v3.h +++ b/include/genetic/v3/program_v3.h @@ -22,12 +22,13 @@ namespace parks::genetic { private: GeneticNode** nodes; int size = 1; + int max_height; - void generateRandomTree(); + void generateRandomTree(int n); Color execute_internal(double x, double y, int node); public: - explicit GeneticTree(int max_height){ + explicit GeneticTree(int max_height): max_height(max_height) { for (int i = 0; i < max_height; i++) size *= 2; nodes = new GeneticNode*[size]; @@ -37,7 +38,7 @@ namespace parks::genetic { //nodes[0] = new GeneticNode(FunctionID::ADD, 0, functions[FunctionID::ADD].generateRandomParameters()); - generateRandomTree(); + generateRandomTree(0); } Color execute(double x, double y); @@ -75,6 +76,9 @@ namespace parks::genetic { } static int height(int node); + int subtreeSize(int n) const; + + void deleteSubtree(int n); void deleteTree(){ for (int i = 0; i < size; i++) { @@ -87,6 +91,8 @@ namespace parks::genetic { return size; } + void mutate(); + ~GeneticTree(){ deleteTree(); delete[] nodes; @@ -115,6 +121,8 @@ namespace parks::genetic { } void regenTreeDisplay(); + void processImage(); + float renderProgress; public: Program() = default; diff --git a/src/genetic/v3/program_v3.cpp b/src/genetic/v3/program_v3.cpp index b57d991..75db699 100644 --- a/src/genetic/v3/program_v3.cpp +++ b/src/genetic/v3/program_v3.cpp @@ -16,31 +16,22 @@ namespace parks::genetic { } void Program::run() { + if (ImGui::Button("Run Program")){ + processImage(); + regenTreeDisplay(); + } if (ImGui::Button("Regen Program And Run")) { delete tree; tree = new GeneticTree(7); regenTreeDisplay(); - ParameterSet set = functions[FunctionID::COLOR_NOISE].generateRandomParameters(); - for (unsigned int i = 0; i < WIDTH; i++) { - for (unsigned int j = 0; j < HEIGHT; j++){ - auto pos = getPixelPosition(i, j); - - //auto out = functions[FunctionID::COLOR_NOISE].call({ARGS_BOTH, Color((double)i / WIDTH), Color((double)j / HEIGHT)}, set); - - auto out = tree->execute((double)i / WIDTH, (double)j / HEIGHT); - - pixels[pos] = (unsigned char)(out.r * 255); - pixels[pos + 1] = (unsigned char) (out.g * 255); - pixels[pos + 2] = (unsigned char) (out.b * 255); - } - } + processImage(); } if (ImGui::Button("Crossover")){ } if (ImGui::Button("Mutate")){ - + tree->mutate(); } if (ImGui::Button("Save")){ @@ -112,13 +103,29 @@ namespace parks::genetic { ImGui::End(); } + void Program::processImage() { + for (unsigned int i = 0; i < WIDTH; i++) { + for (unsigned int j = 0; j < HEIGHT; j++){ + auto pos = getPixelPosition(i, j); + + //auto out = functions[FunctionID::COLOR_NOISE].call({ARGS_BOTH, Color((double)i / WIDTH), Color((double)j / HEIGHT)}, set); + + auto out = tree->execute((double)i / WIDTH, (double)j / HEIGHT); + + pixels[pos] = (unsigned char)(out.r * 255); + pixels[pos + 1] = (unsigned char) (out.g * 255); + pixels[pos + 2] = (unsigned char) (out.b * 255); + } + } + } + GeneticNode::GeneticNode(FunctionID op, unsigned int pos, ParameterSet set): op(op), pos(pos), set(std::move(set)) {} - void GeneticTree::generateRandomTree() { + void GeneticTree::generateRandomTree(int n) { std::queue nodesToProcess; std::queue nonFuncNodesToProcess; - nodesToProcess.push(0); + nodesToProcess.push(n); while (!nodesToProcess.empty()){ int node = nodesToProcess.front(); nodesToProcess.pop(); @@ -228,4 +235,86 @@ namespace parks::genetic { return func.call({ARGS_BOTH, leftC, rightC}, ourNode->set); } + void GeneticTree::mutate() { + for (int i = 0; i < size; i++){ + if (nodes[i] == nullptr) { + // TODO: ? + } else { + int nodeSize = subtreeSize(i); + double factor = 1.0 / nodeSize; + if (chance(nodeMutationChance * factor)) { + // delete old subtrees + deleteSubtree(i); + // create a new completely random tree + generateRandomTree(i); + } + if (chance(functionMutationChance * factor)){ + auto newFuncID = functions.select(); + auto oldFuncID = nodes[i]->op; + if (newFuncID != nodes[i]->op){ + nodes[i]->op = newFuncID; + auto& newFunc = functions[newFuncID]; + auto& oldFunc = functions[oldFuncID]; + // TODO: use some of the old params!! + if (newFunc.getRequiredColors() != oldFunc.getRequiredColors() || newFunc.getRequiredScalars() != oldFunc.getRequiredScalars()){ + nodes[i]->set = newFunc.generateRandomParameters(); + } + if (oldFunc.dontCareArgument() && newFunc.dontCareArgument()) + continue; + if (oldFunc.singleArgument() && newFunc.singleArgument()) + continue; + if (oldFunc.bothArgument() && oldFunc.bothArgument()) + continue; + if (oldFunc.singleArgument() && newFunc.bothArgument()) + generateRandomTree(right(i)); + if (oldFunc.bothArgument() && newFunc.singleArgument()) + deleteSubtree(right(i)); + } + } + if (nodes[i]->op == FunctionID::RAND_SCALAR && chance(scalarMutationChance * factor)){ + ParameterSet newSet; + newSet.add(RandomScalar::get(nodes[i]->set[0])); + nodes[i]->set = std::move(newSet); + } + if (nodes[i]->op == FunctionID::RAND_COLOR && chance(colorMutationChance * factor)){ + ParameterSet newSet; + newSet.add(RandomColor::get(nodes[i]->set[0])); + nodes[i]->set = std::move(newSet); + } + } + } + } + + void GeneticTree::deleteSubtree(int n) { + std::queue nodesToDelete; + nodesToDelete.push(n); + while (!nodesToDelete.empty()){ + auto node = nodesToDelete.front(); + nodesToDelete.pop(); + + if (node >= size) + continue; + + if (nodes[node] != nullptr) { + delete nodes[node]; + nodes[node] = nullptr; + } + + nodesToDelete.push(left(node)); + nodesToDelete.push(right(node)); + } + } + + int GeneticTree::subtreeSize(int n) const { + int l = left(n); + int r = right(n); + int leftSize = 1; + int rightSize = 1; + if (l < size && nodes[l] != nullptr) + leftSize = subtreeSize(l); + if (r < size && nodes[r] != nullptr) + rightSize = subtreeSize(r); + return std::max(leftSize, rightSize) + 1; + } + } \ No newline at end of file