mutation seems to be working now
parent
b09658f03f
commit
40b4414cc0
Binary file not shown.
|
@ -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
|
||||
|
|
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 {
|
||||
|
||||
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;
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue