我正在尝试使用C++创建一个类似于NEAT的人工智能。然而,我在使种群正常工作时遇到了问题。当我使用自定义对象的数组时,每个对象的属性中存储的一些数据会被损坏。在网络被分配后,每个连接中的数据被设置为0xDDDDDDDD
。当我在构造函数中测试给定的属性时,看起来一切正常,但当它被分配到种群数组中(在本例中为t
)时,所有的数据都被设置为0xDDDDDDDD
,就像被删除了一样。
// neat network.cpp : This file contains the 'main' function. Program execution begins and ends there.//#include <iostream>#include <cmath>class node{public: int id; double value; node() { id = 0; value = 0; } node(int n) { id = n; value = 0; } void apply(double v) { value = v; } node copy() { return node(id); }};class connection{public: double weight; int in; int out; connection(int i, int o, double w=0) { in = i; out = o; weight = w; int r = rand(); weight = ((double)(r % 2000) - 1000.0) / 1000.0; srand(r); } connection() { in = 0; out = 0; weight = 0; } void mutate() { weight += (double)((rand() % 50 - 2) / 1000); } connection copy() { connection ret = connection(in, out); ret.weight = weight; return ret; }};double sigmoid(double n){ return 1 / (exp(-n) + 1);}class net{public: double* position; int quant; node* nodes; int* inpernode; connection* connections; int connlen; int inn; int ut; net(int ins, int outs, int cn=0) { inn = ins; ut = outs; quant = ins+outs; nodes = new node[quant]; position = new double[quant]; connections = new connection[ins*outs]; inpernode = new int[quant]; for (int i = 0; i < quant; i++) { nodes[i] = node(i); if (i < ins) { position[i] = 0; } else { position[i] = 1; } inpernode[i] = 0; } int c = 0; connlen = ins * outs; for (int i = 0; i < ins; i++) { for (int j = ins; j < quant; j++) { connections[c] = connection(i, j); //std::cout << connections[c].weight << " "; inpernode[j]++; c++; } } //std::cout << connections[0].in << std::endl; } net() { connections = new connection(); connlen = 0; inn = 0; inpernode = new int(); quant = 0; nodes = new node(); position = new double(); ut = 0; } ~net() { delete[] position; delete[] nodes; delete[] connections; delete[] inpernode; } double* apply(double* inputs) { bool* finished = new bool[quant]; //std::cout << connections[0].in; bool* cfinished = new bool[connlen]; int* ndone = new int[quant]; bool alldone=false; for (int i = 0; i < connlen; i++) { cfinished[i] = false; } for (int i = 0; i < quant; i++) { finished[i] = i<inn; ndone[i] = 0; nodes[i].value = 0; if (i < inn) { nodes[i].value = inputs[i]; } } while (!alldone) { alldone = true; for (int i = 0; i < connlen; i++) { //std::cout << quant; if (finished[connections[i].in] && !cfinished[i]) { alldone = false; nodes[connections[i].out].value += connections[i].weight * sigmoid(nodes[connections[i].in].value); cfinished[i] = true; ndone[connections[i].out]++; if (ndone[connections[i].out] == inpernode[connections[i].out]) { finished[connections[i].out] = true; } } } } double* outs = new double[ut]; for (int i = inn; i < inn + ut; i++) { outs[i - inn] = sigmoid(nodes[i].value); } return outs; } net copy() { net ret = net(inn, ut); ret.quant = quant; ret.connlen = connlen; for (int i = 0; i < quant; i++) { ret.position[i] = position[i]; ret.nodes[i] = nodes[i].copy(); ret.inpernode[i] = inpernode[i]; } for (int i = 0; i < connlen; i++) { ret.connections[i] = connections[i].copy(); } return ret; } net mutate() { net ret = copy(); for (int i = 0; i < quant; i++) { if (rand() % 20 == 19) { connections[i].mutate(); } if (rand() % 333 == 332) { nodes[quant] = node(quant); int temp = connections[i].out; connections[i].out = quant; connections[connlen] = connection(quant, temp); quant++; connlen++; } } if (rand() % 33 == 32) { bool done = false; int tries = 200; while (!done) { tries--; if (tries < 0) done = true; int inc = rand() % quant; if (position[inc] == 1) continue; int utc = rand() % quant; if (position[inc] > position[utc]) continue; bool found = false; for (int i = 0; i < connlen; i++) { if (connections[i].in == inc && connections[i].out == utc) found = true; } if (!found) { connections[connlen] = connection(inc, utc); connlen++; done = true; } } } return ret; }};int main(){ srand(2002); /*net test = net(2, 1); net test2 = net(2, 1); std::cout << test.connections[0].weight << " " << test.connections[1].weight << std::endl; std::cout << test2.connections[0].weight << " " << test2.connections[1].weight << std::endl; double ins[] = { 0,0 }; double* cp = test.apply(ins); std::cout << cp[0]<<" "; cp = test2.apply(ins); std::cout << cp[0];*/ net t[1]; t[0] = net(2, 1); std::cout << t[0].inn << " " << t[0].ut << std::endl; std::cout << t[0].connections[0].in << " " << t[0].connections[0].weight << std::endl; /*net pop[100]; for (int i = 0; i < 100; i++) { pop[i] = net(2, 1); std::cout << pop[i].connections[0].in << " " << pop[i].connections[1].in << " " << std::endl; } int* scores = new int[100]; for (int gen = 0; gen < 100; gen++) { for (int i = 0; i < 100; i++) { scores[i] = 0; double inp[] = { 0, 0 }; double* t = pop[i].apply(inp); if (t[0] < .1) scores[i]++; inp[1] = 1; t = pop[i].apply(inp); if (t[0] > .9) scores[i]++; inp[0] = 1; inp[1] = 0; t = pop[i].apply(inp); if (t[0] > .9) scores[i]++; inp[1] = 1; t = pop[i].apply(inp); if (t[0] < .1) scores[i]++; if (scores[i] == 4) { std::cout << "Solved" << gen; return 0; } scores[i] -= pop[i].connlen + pop[i].quant; } int sum = 0; for (int i = 0; i < 100; i++) sum += scores[i]; double avg = (double)(sum / 100); net newpop[100]; int nplen = 0; for (int i = 0; i < 100; i++) { if (scores[i] > avg) { newpop[nplen++] = pop[i]; } } for (int i = 0; i < nplen; i++) { pop[i] = newpop[i]; } for (int i = nplen; i < 100; i++) { pop[i] = pop[i % nplen].mutate(); } }*/ return 0;}// Run program: Ctrl + F5 or Debug > Start Without Debugging menu// Debug program: F5 or Debug > Start Debugging menu// Tips for Getting Started: // 1. Use the Solution Explorer window to add/manage files// 2. Use the Team Explorer window to connect to source control// 3. Use the Output window to see build output and other messages// 4. Use the Error List window to view errors// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file
回答: