mutation seems to be working now
parent
b09658f03f
commit
40b4414cc0
Binary file not shown.
|
@ -433,3 +433,16 @@
|
||||||
1637 1793 1689815127566015790 parksnrec fc63db74fd58366e
|
1637 1793 1689815127566015790 parksnrec fc63db74fd58366e
|
||||||
4 1712 1689815769560520877 CMakeFiles/parksnrec.dir/src/genetic/v3/program_v3.cpp.o 7203e7cb37c07468
|
4 1712 1689815769560520877 CMakeFiles/parksnrec.dir/src/genetic/v3/program_v3.cpp.o 7203e7cb37c07468
|
||||||
1713 1866 1689815769710517695 parksnrec fc63db74fd58366e
|
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
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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.
|
@ -10,7 +10,10 @@
|
||||||
namespace parks::genetic {
|
namespace parks::genetic {
|
||||||
|
|
||||||
constexpr double d = 0.4;
|
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 {
|
struct Color {
|
||||||
double r, g, b;
|
double r, g, b;
|
||||||
|
|
|
@ -97,6 +97,15 @@ namespace parks::genetic {
|
||||||
return acceptsArgs & ARGS_FUNCS;
|
return acceptsArgs & ARGS_FUNCS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline unsigned int getRequiredScalars() const{
|
||||||
|
return requiredScalars;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline unsigned int getRequiredColors() const{
|
||||||
|
return requiredColors;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[[nodiscard]] ParameterSet generateRandomParameters() const {
|
[[nodiscard]] ParameterSet generateRandomParameters() const {
|
||||||
ParameterSet set;
|
ParameterSet set;
|
||||||
for (unsigned int i = 0; i < requiredScalars; i++)
|
for (unsigned int i = 0; i < requiredScalars; i++)
|
||||||
|
|
|
@ -22,12 +22,13 @@ namespace parks::genetic {
|
||||||
private:
|
private:
|
||||||
GeneticNode** nodes;
|
GeneticNode** nodes;
|
||||||
int size = 1;
|
int size = 1;
|
||||||
|
int max_height;
|
||||||
|
|
||||||
void generateRandomTree();
|
void generateRandomTree(int n);
|
||||||
|
|
||||||
Color execute_internal(double x, double y, int node);
|
Color execute_internal(double x, double y, int node);
|
||||||
public:
|
public:
|
||||||
explicit GeneticTree(int max_height){
|
explicit GeneticTree(int max_height): max_height(max_height) {
|
||||||
for (int i = 0; i < max_height; i++)
|
for (int i = 0; i < max_height; i++)
|
||||||
size *= 2;
|
size *= 2;
|
||||||
nodes = new GeneticNode*[size];
|
nodes = new GeneticNode*[size];
|
||||||
|
@ -37,7 +38,7 @@ namespace parks::genetic {
|
||||||
|
|
||||||
//nodes[0] = new GeneticNode(FunctionID::ADD, 0, functions[FunctionID::ADD].generateRandomParameters());
|
//nodes[0] = new GeneticNode(FunctionID::ADD, 0, functions[FunctionID::ADD].generateRandomParameters());
|
||||||
|
|
||||||
generateRandomTree();
|
generateRandomTree(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color execute(double x, double y);
|
Color execute(double x, double y);
|
||||||
|
@ -75,6 +76,9 @@ namespace parks::genetic {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int height(int node);
|
static int height(int node);
|
||||||
|
int subtreeSize(int n) const;
|
||||||
|
|
||||||
|
void deleteSubtree(int n);
|
||||||
|
|
||||||
void deleteTree(){
|
void deleteTree(){
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
|
@ -87,6 +91,8 @@ namespace parks::genetic {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mutate();
|
||||||
|
|
||||||
~GeneticTree(){
|
~GeneticTree(){
|
||||||
deleteTree();
|
deleteTree();
|
||||||
delete[] nodes;
|
delete[] nodes;
|
||||||
|
@ -115,6 +121,8 @@ namespace parks::genetic {
|
||||||
}
|
}
|
||||||
void regenTreeDisplay();
|
void regenTreeDisplay();
|
||||||
|
|
||||||
|
void processImage();
|
||||||
|
|
||||||
float renderProgress;
|
float renderProgress;
|
||||||
public:
|
public:
|
||||||
Program() = default;
|
Program() = default;
|
||||||
|
|
|
@ -16,31 +16,22 @@ namespace parks::genetic {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Program::run() {
|
void Program::run() {
|
||||||
|
if (ImGui::Button("Run Program")){
|
||||||
|
processImage();
|
||||||
|
regenTreeDisplay();
|
||||||
|
}
|
||||||
if (ImGui::Button("Regen Program And Run")) {
|
if (ImGui::Button("Regen Program And Run")) {
|
||||||
delete tree;
|
delete tree;
|
||||||
tree = new GeneticTree(7);
|
tree = new GeneticTree(7);
|
||||||
regenTreeDisplay();
|
regenTreeDisplay();
|
||||||
ParameterSet set = functions[FunctionID::COLOR_NOISE].generateRandomParameters();
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < WIDTH; i++) {
|
processImage();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (ImGui::Button("Crossover")){
|
if (ImGui::Button("Crossover")){
|
||||||
|
|
||||||
}
|
}
|
||||||
if (ImGui::Button("Mutate")){
|
if (ImGui::Button("Mutate")){
|
||||||
|
tree->mutate();
|
||||||
}
|
}
|
||||||
if (ImGui::Button("Save")){
|
if (ImGui::Button("Save")){
|
||||||
|
|
||||||
|
@ -112,13 +103,29 @@ namespace parks::genetic {
|
||||||
ImGui::End();
|
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):
|
GeneticNode::GeneticNode(FunctionID op, unsigned int pos, ParameterSet set):
|
||||||
op(op), pos(pos), set(std::move(set)) {}
|
op(op), pos(pos), set(std::move(set)) {}
|
||||||
|
|
||||||
void GeneticTree::generateRandomTree() {
|
void GeneticTree::generateRandomTree(int n) {
|
||||||
std::queue<int> nodesToProcess;
|
std::queue<int> nodesToProcess;
|
||||||
std::queue<int> nonFuncNodesToProcess;
|
std::queue<int> nonFuncNodesToProcess;
|
||||||
nodesToProcess.push(0);
|
nodesToProcess.push(n);
|
||||||
while (!nodesToProcess.empty()){
|
while (!nodesToProcess.empty()){
|
||||||
int node = nodesToProcess.front();
|
int node = nodesToProcess.front();
|
||||||
nodesToProcess.pop();
|
nodesToProcess.pop();
|
||||||
|
@ -228,4 +235,86 @@ namespace parks::genetic {
|
||||||
return func.call({ARGS_BOTH, leftC, rightC}, ourNode->set);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue