编程作业:机器人遗传算法



该程序旨在运行10000代200个机器人,允许进化塑造机器人"DNA"中的数字。我遇到的问题是,即使只有数字进入"机器人基因"阵列,打印的DNA也是字母,数字和符号的随机集合。我完全不知道为什么。我尝试切换我声明和分配变量的位置,不幸的是,这一切都在风向标中。请减半。

附言我在这里发布整个程序代码,因为我不确定是什么导致了问题,尽管我很肯定我只是愚蠢。任何帮助将不胜感激。

#include <iostream>
#include <string>
#include <stdlib.h>
#include <cmath>
using namespace std;
int randBattery = 0,
randRobot = 0,
randDirect = 0,
board[144] = { },
testDirect = 0,
randTurn = 0,
randTurnDirect = 0,
genAdd = 0,
masterFit = 0,
abc = 0;
double fitness[10000] = { },
winners[5] = { };
std::string startCond;
unsigned char robotGenes[200][12] = { },
test[12] = { };
class Display {
public:
int results() {
cout << "nnn-Evolution Winning Avg. Fitness Ratings-nn";
cout << "1. " << winners[1];
cout << "n DNA: ";
for (int G = 1; G <= 12; G++)
{
cout << robotGenes[1][G];
}
cout << "nn2. " << winners[2];
cout << "n DNA: ";
for (int G = 1; G <= 12; G++)
{
cout << robotGenes[41][G];
}
cout << "nn3. " << winners[3];
cout << "n DNA: ";
for (int G = 1; G <= 12; G++)
{
cout << robotGenes[81][G];
}
cout << "nn4. " << winners[4];
cout << "n DNA: ";
for (int G = 1; G <= 12; G++)
{
cout << robotGenes[121][G];
}
cout << "nn5. " << winners[5];
cout << "n DNA: ";
for (int G = 1; G <= 12; G++)
{
cout << robotGenes[161][G];
}
return 0;
};
};
class RobotSex {
public:
int bang() {
int newGen, newGen2, B;
newGen = 101;
newGen2 = 102;
B = 2;
for (int C = 1; C <= 100; C += 2)
{
robotGenes[newGen][6] = robotGenes[C][6];
robotGenes[newGen][7] = robotGenes[C][7];
robotGenes[newGen][8] = robotGenes[C][8];
robotGenes[newGen][9] = robotGenes[C][9];
robotGenes[newGen][10] = robotGenes[B][10];
robotGenes[newGen][11] = robotGenes[B][11];
robotGenes[newGen2][6] = robotGenes[B][6];
robotGenes[newGen2][7] = robotGenes[B][7];
robotGenes[newGen2][8] = robotGenes[B][8];
robotGenes[newGen2][9] = robotGenes[B][9];
robotGenes[newGen2][10] = robotGenes[C][10];
robotGenes[newGen2][11] = robotGenes[C][11];
newGen += 2;
newGen2 += 2;
B += 2;
}
};
};
class Genocide {
public:
int ethnicCleansing() {
for (int x = 101; x <= 200; x++)
{
for (int y = 6; y <= 12; y++)
{
robotGenes[x][y] = 0;
}
}
};
};
class Sorting {
public:
int sortPower() {
for (int P = 0; P <= 200; P++)
{
for (int x = 1; x <= 200; x++)
{
int y;
y = x + 1;
if (robotGenes[x][12] < robotGenes[y][12])
for (int Q = 1; Q <= 12; Q++)
swap (robotGenes[x][Q], robotGenes[y][Q]);
}
}
};
int addGenFit() {
for (int o = 1; o <= 200; o++)
{
genAdd += robotGenes[o][12];
}
fitness[masterFit] = genAdd / 200;
::masterFit += 1;
};
int sortGenFit() {
for (int P = 0; P <= 10000; P++)
{
for (int x = 1; x <= 9999; x++)
{
int y;
y = x + 1;
if (fitness[x] < fitness[y])
swap (fitness[x], fitness[y]);
}
}
for (int o = 1; o <= 2000; o++)
{
genAdd += fitness[o];
}
winners[1] = genAdd / 2000;
for (int o = 2001; o <= 4000; o++)
{
genAdd += fitness[o];
}
winners[2] = genAdd / 2000;
for (int o = 4001; o <= 6000; o++)
{
genAdd += fitness[o];
}
winners[3] = genAdd / 2000;
for (int o = 6001; o <= 8000; o++)
{
genAdd += fitness[o];
}
winners[4] = genAdd / 2000;
for (int o = 8001; o <= 10000; o++)
{
genAdd += fitness[o];
}
winners[5] = genAdd / 2000;
};
};
class Establishing {
public:
int clearBoard() {
for (int c = 0; c <= 144; c++)  //Clearing board
{
board[c] = 0;
}
for (int x = 0; x <= 12; x++)   //Establishing walls
{
board[x] = 9;
}
for (int x = 132; x <= 144; x++)
{
board[x] = 9;
}
for (int x = 13; x <= 121; x += 12)
{
board[x] = 9;
}
for (int x = 24; x <= 132; x += 12)
{
board[x] = 9;
}
};
};
class Randomizer {
public:
int randBattery() {
for (int t = 1; t <= 4; t++)
{
srand(time(NULL));      //Random battery placement R1
::randBattery = (rand() % 14+23);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL));      //Random battery placement R2
::randBattery = (rand() % 26+35);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL));      //Random battery placement R3
::randBattery = (rand() % 38+47);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL));      //Random battery placement R4
::randBattery = (rand() % 50+59);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL));      //Random battery placement R5
::randBattery = (rand() % 62+71);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL));      //Random battery placement R6
::randBattery = (rand() % 74+82);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL));      //Random battery placement R7
::randBattery = (rand() % 85+95);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL));      //Random battery placement R8
::randBattery = (rand() % 98+107);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL));      //Random battery placement R9
::randBattery = (rand() % 110+119);
board[::randBattery] = 1;
}
for (int t = 1; t <= 4; t++)
{
srand(time(NULL));      //Random battery placement R10
::randBattery = (rand() % 122+131);
board[::randBattery] = 1;
}
};
int randPlacement() {
for (int t = 1; t <= 200; t++)
{
srand(time(NULL));      //Random robot placement & resets power level
randRobot = (rand() % 62+71);
robotGenes[t][1] = randRobot;
robotGenes[t][12] = 5;
}
};
char randDirect() {
for (int d = 1; d <= 200; d++)
{
srand(time(NULL));      //Random robot direction
::randDirect = (rand() % 62+71);
robotGenes[d][5] = ::randDirect;
}
};
};
class Reader {
public:
int readDNA() { 
do {
if (board[test[1]] == 1)    //Pickup battery
test[12] += 5;
if (test[9] == 1)       //Check for wall
{
if (board[test[2]] == 9)
{
if (test[5] == 1)
test[5] = 4;
if (test[5] == 2)
test[5] = 1;
if (test[5] == 3)
test[5] = 2;
if (test[5] == 4)
test[5] = 3;
}
if (board[test[2]] == 9 && board[test[3]] == 9)
{
if (test[5] == 1)
test[5] = 2;
if (test[5] == 2)
test[5] = 3;
if (test[5] == 3)
test[5] = 4;
if (test[5] == 4)
test[5] = 1;
}
}
if (test[7] == test[6])     //Changing direction after # of moves
if (test[6] % 2 == 0)       //Turning left
{
if (test[5] == 1)
test[5] = 4;
if (test[5] == 2)
test[5] = 1;
if (test[5] == 3)
test[5] = 2;
if (test[5] == 4)
test[5] = 3;
}
else                //Turning right
{
if (test[5] == 1)
test[5] = 2;
if (test[5] == 2)
test[5] = 3;
if (test[5] == 3)
test[5] = 4;
if (test[5] == 4)
test[5] = 1;
}
if (test[10] == 1)      //Left sensor checking for battery, TURN LEFT
if (test[5] == 1)
test[5] = 4;
if (test[5] == 2)
test[5] = 1;
if (test[5] == 3)
test[5] = 2;
if (test[5] == 4)
test[5] = 3;
if (test[11] == 1)      //Right sensor checking for battery, TURN RIGHT
if (test[5] == 1)
test[5] = 2;
if (test[5] == 2)
test[5] = 3;
if (test[5] == 3)
test[5] = 4;
if (test[5] == 4)
test[5] = 1;
if (test[5] == 1)           //Face north 
{
test[2] = test[1] + 12;
::test[3] = test[1] - 1;
test[4] = test[1] + 1;
test[1] += 12;          //Move north
test[2] += 12;
::test[3] += 12;
test[4] += 12;
}
if (test[5] == 2)           //Face east 
{
test[2] = test[1] + 1;
::test[3] = test[1] + 12;
test[4] = test[1] - 12;
test[1] += 1;           //Move east
test[2] += 1;
::test[3] += 1;
test[4] += 1;
}
if (test[5] == 3)           //Face south
{
test[2] = test[1] - 12;
::test[3] = test[1] + 1;
test[4] = test[1] - 1;
test[1] -= 12;          //Move south
test[2] -= 12;
::test[3] -= 12;
test[4] -= 12;
}
if (test[5] == 4)           //Face west
{
test[2] = test[1] - 1;
::test[3] = test[1] - 12;
test[4] = test[1] + 12;
test[1] -= 1;           //Move west
test[2] -= 1;
::test[3] -= 1;
test[4] -= 1;
}
test[7] += 1;
test[12] -= 1;
} while (test[12] > 1 && test[7] < 24); 
};
};
class Running {
public:
void runRobot() {
for (int q = 1; q <= 200; q++)
{
for (int z = 1; z <= 12; z++)
{
::test[z] = robotGenes[q][z];
}
Reader objectDNA;
objectDNA.readDNA();
for (int z = 1; z <= 12; z++)
{
::robotGenes[q][z] = test[z];
}
}
};
};
int main()
{
//System Greeting
cout << "Enter anything to start simulation.nn";
cin >> startCond;
masterFit = 1;
//Setting starting genes
for (int t = 1; t <= 200; t++)
{
srand(time(NULL));
randTurn = (rand() % 10+1);
robotGenes[t][6] = randTurn;
}
for (int o = 1; o <= 40; o++)
{
robotGenes[o][8] = 1;
robotGenes[o][9] = 0;
robotGenes[o][10] = 0;
robotGenes[o][11] = 0;
}
for (int o = 41; o <= 80; o++)
{
robotGenes[o][8] = 0;
robotGenes[o][9] = 1;
robotGenes[o][10] = 1;
robotGenes[o][11] = 1;
}
for (int o = 81; o <= 120; o++)
{
robotGenes[o][8] = 1;
robotGenes[o][9] = 1;
robotGenes[o][10] = 0;
robotGenes[o][11] = 0;
}
for (int o = 121; o <= 160; o++)
{
robotGenes[o][8] = 0;
robotGenes[o][9] = 0;
robotGenes[o][10] = 0;
robotGenes[o][11] = 0;
}
for (int o = 161; o <= 200; o++)
{
robotGenes[o][8] = 1;
robotGenes[o][9] = 0;
robotGenes[o][10] = 1;
robotGenes[o][11] = 1;
}
//Running sims (not the game)
Randomizer objectRaDirect;
objectRaDirect.randDirect();
Randomizer objectRaPlace;
objectRaPlace.randPlacement();
for (int sims = 1; sims <= 10000; sims++)
{
Establishing objectClear;
objectClear.clearBoard();
Randomizer objectRaBattery;
objectRaBattery.randBattery();
Running objectRun;
objectRun.runRobot();
abc += 1;
cout << "nnGeneration " << abc << " is complete.n";
Sorting objectPower;
objectPower.sortPower();
Sorting objectGenFit;
objectGenFit.addGenFit();
Genocide objectHitler;
objectHitler.ethnicCleansing();
RobotSex objectSex;
objectSex.bang();
}
Sorting objectWin;
objectWin.sortGenFit();
for (int B = 1; B <= 5; B++)
{
winners[B] = abs (winners[B]);
}
Display objectEnd;
objectEnd.results();
};

您的代码有两个主要问题:

1) 您在此处具有越界数组访问权限:

unsigned char robotGenes[200][12] = { }, test[12] = { };
//...
for (int G = 1; G <= 12; G++)
{
cout << robotGenes[1][G];
}

在上次迭代中,您正在打印垃圾值。 该程序实际上调用未定义的行为,因为当12GrobotGenes[1][G]是越界的。

您在ethnicCleansing函数中也犯了同样的错误,但可能更糟,因为您不只是读取无效位置,而是写入它:

for (int y = 6; y <= 12; y++)
{
robotGenes[x][y] = 0;
}

y为 12 时,您正在写入无效的索引。

数组索引从0n-1开始,其中n是数组中的条目总数。 因此G范围从011,包括。 转到索引12是越界访问。


2)您正在调用应该返回值的函数,但未能这样做。 例如

int Genocide::ethnicCleansing

这个函数应该返回一个int,但不返回任何内容。 因此,程序调用未定义的行为。 不从应该返回值的函数返回值是未定义的行为。请注意,您还有其他几个具有相同问题的函数。

请在此处查看您的完整代码。

修复警告,首先修复越界访问。 我不知道这些是否是唯一的问题,但它们是两个像拇指酸痛一样突出的问题。

您很可能将数据打印为 char 数组而不是无符号 char 数组。这会导致打印由数字表示的 ASCII 字符,而不是实际数字。

最新更新