mutation seems to be working now

main
Brett 2023-07-19 22:06:04 -04:00
parent b09658f03f
commit 40b4414cc0
15 changed files with 145 additions and 23 deletions

View File

@ -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

View File

@ -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

Binary file not shown.

View File

@ -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;

View File

@ -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++)

View File

@ -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;

View File

@ -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<int> nodesToProcess;
std::queue<int> 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<int> 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;
}
}