//=========================================================================== // The basic algorythm of this simulation is based on Nicholas Gessler's // flocking bahavior simulation and Evolutionary Concert Tour. // The idea that an obstacle in front of the exit helps the flow of agents is // borrowed from Dirk Helbing's Pedestrian Simulations(helbing.org). // // Daisuke Imai //=========================================================================== //--------------------------------------------------------------------------- #include #include #pragma hdrstop #include #include #include "Unit1.h" #include "Unit2.h" #include #include "stdlib.h" #include "time.h" #include using namespace std; #include #include // for turning off floating point exceptions //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { // Double buffering eliminates some screen flicker... DoubleBuffered = true; _control87(MCW_EM, MCW_EM);// turning off floating point exceptions } //--------------------------------------------------------------------------- //=========================================================================== // GLOBAL VARIABLES //=========================================================================== // ------------------------------------------------- your program begins here class anAgent { public: double velocity; double direction; //double newDirection; //double newDistance; //double lastDistance; double x; double y; double pastX; double pastY; double inst; //int lastNN; //int dist; //bool flocking; int bin; int pause; //double velocityO; } agent[300]; typedef struct _SOLUTION{ double AX; double AY; double BX; double BY; double CX; double CY; int score; int itr; int inj; }SOLUTION; SOLUTION pattern[50]; SOLUTION patternC[48]; class tEMP{ public: double x; double y; } temp[300]; int increment = 7; bool stop = true; bool wasStopped = false; int iterations; int i; int chosenAgent; int shapeDownX, shapeDownY; bool agentWasJustChosen = false; int dist; double vectorD, vectorV, vectorX, vectorY; // average directions & velocities int visibleN; //visible neighbors double visibleI, visibleII; //visible inst int myNeighbor; double dirof; int radius = 20 ; // double x, y, z; int generation = 0; bool evo; int penalty = 3; int score; int injured; bool firstRandom; bool estop = true; //=========================================================================== // FUNCTIONS //=========================================================================== //---------------------------------------------------------------- color ramp int colorRamp(int range, double value){ int pixelDistanceAlongPath = (value * 1792) / range; int red, green, blue; // Which edge of the color cube are we on? if (value == 2000) { red = 255, green = 255, blue = 255; } else if (pixelDistanceAlongPath < 256) { // Edge 1 from BLACK to Green red=0; green=pixelDistanceAlongPath + 25; blue=0; if (green > 255) { green = 255; } } else if (pixelDistanceAlongPath < 512) { // Edge 2 from Green to CYAN red =0; green=255; blue=pixelDistanceAlongPath-256; } else if (pixelDistanceAlongPath < 768) { // Edge 3 from CYAN to Yellow red =(pixelDistanceAlongPath-512); green =255; blue= 255-(pixelDistanceAlongPath-512); } else if (pixelDistanceAlongPath < 1024) { // Edge 4 from YELLOW to Red red= 255; green =255-(pixelDistanceAlongPath-768); blue =0; } else if (pixelDistanceAlongPath <1280) { // Edge 5 from YELLOW to RED red =255; green=255-(pixelDistanceAlongPath-1024); blue =0; } else if (pixelDistanceAlongPath < 1536) { // Edge 6 from RED to MAGENTA red =255; green=0; blue=pixelDistanceAlongPath -1280; } else { // Edge 7 from MAGENTA to WHITE red =255; green=pixelDistanceAlongPath-1536; blue =255; } return (RGB(red, green, blue)); } //------------------------------------------------------------------- shuffle void shuffle (void) { //anAgent*agent; //agent = new anAgent[300]; for (int i = 0; i < 300; i++) { agent[i].x = random(400) + 30; agent[i].y = random(390) + 30; agent[i].bin = 0; agent[i].direction = 1; //goal(agent[i].x, agent[i].y); agent[i].velocity = 0.5; agent[i].inst = 1; agent[i].pause = 0; } iterations = 0; injured = 0; Form1->Refresh(); } //--------------------------------------------------------------------- reset void reset (void) { iterations = 0; Form1->EditIterations->Text = iterations; //delete [] agent; // randomize(); shuffle(); } //-----------------------------------------------------------------------Goal double goal(double x, double y){ x = agent[i].x - 230; y = agent[i].y - 431; if (x == 0 && y == 0) { x = 100; y = 100; } dirof = atan2(y, x) - M_PI; if (dirof < 0) { dirof = dirof + 2 * M_PI; } return dirof; } //---------------------------------------------------------------------------- //---------------------------------------------------------- nearest neighbor int nearestNeighbor (int me) { vectorD = 0; // directions vectorV = 0; // velocities vectorX = 0; // x component vectorY = 0; // y component visibleN = 0; // number of visible neighbors visibleI = 0; //visibleInst visibleII = 0; //vsible within its radius myNeighbor = 0; // my nearest neighbor dist = 10000; // shortest distance for (int i = 0; i < 300; i++) { if (i == me || agent[i].inst > 40) continue; if (agent[i].bin == agent[me].bin && agent[i].inst != 2000 ) { x = agent[i].x - agent[me].x; y = agent[i].y - agent[me].y; z = sqrt(x * x + y * y); if (z < dist) { // select nearest neighbor dist = z; myNeighbor = i; } if (z < radius) { // average all visible neighbors visibleII++; goal(agent[me].x, agent[me].y); if ( dirof > agent[i].direction - (M_PI/4) && dirof < agent[i].direction + (M_PI/4)) { //if (agent[i].y > agent[me].y){ visibleN++; visibleI = visibleI + agent[i].inst; vectorY += agent[i].velocity * sin(agent[i].direction); vectorX += agent[i].velocity * cos(agent[i].direction); //} } } } } if ((vectorY != 0) && (vectorX != 0) && (visibleN > 0)) { vectorD = atan(vectorY / vectorX); vectorV = sqrt(vectorX * vectorX + vectorY * vectorY) / visibleN; } return myNeighbor; } //-----------------------------------------------------obtain places of agetnts void placebin(int i){ /* double a,b; a = agent[i].x; b = agent[i].y; if (b < 130 && a < 130 ) { agent[i].bin = 0; break; } else if (b < 130 && 130 < a && a < 230) { agent[i].bin = 1; break; } else if (b < 130 && 230 < a && a < 330) { agent[i].bin = 2; break; } else if (b < 130 && 330 < a && a< 430) { agent[i].bin = 3; break; } else if (130 < b && b < 230 && a < 130 ) { agent[i].bin = 4; break; } else if (130 < b && b < 230 && 130 < a && a < 230) { agent[i].bin = 5; break; } else if (130 < b && b < 230 && 230 < a && a < 330) { agent[i].bin = 6; break; } else if (130 < b && b < 130 && 330 < a && a< 430) { agent[i].bin = 7; break; } else if (230 < b && b < 330 && a < 130 ) { agent[i].bin = 8; break; } else if (230 < b && b < 330 && 130 < a && a < 230) { agent[i].bin = 9; break; } else if (230 < b && b < 330 && 230 < a && a < 330) { agent[i].bin = 10; break; } else if (230 < b && b < 330 && 330 < a && a< 430) { agent[i].bin = 11; break; } else if (330 < b && b < 430 && a < 130 ) { agent[i].bin = 12; break; } else if (330 < b && b < 430 && 130 < a && a < 230) { agent[i].bin = 13; break; } else if (330 < b && b < 430 && 230 < a && a < 330) { agent[i].bin = 14; break; } else if (330 < b && b < 430 && 330 < a && a< 430) { agent[i].bin = 15; break; } */ if (agent[i].inst == 2000 || agent[i].inst > 40) { agent[i].bin = 16; } } //----------------------------------------------------------------------GetSurvivor void getS(void){ int NOA = 0; for (int i = 0; i < 300; i++) { if (agent[i].inst > 40 && agent[i].inst != 2000) { NOA++; } } Form1->EditNOA->Text = NOA; } void evac(int i){ //-----------------------------------------------------------------------Evac if (agent[i].inst != 2000 && agent[i].y < 430 ) { nearestNeighbor(i); if (vectorV != 0 && vectorD != 0 && visibleN > 1 && agent[i].inst < 40 ) { agent[i].velocity = (1.00/visibleN) ; // average the velocities agent[i].direction = goal(agent[i].x, agent[i].y);//(vectorD+(3*(goal(agent[i].x, agent[i].y))))/4; //agent[i].flocking = TRUE; if (agent[i].inst < 40) { agent[i].inst = visibleN; } } if (visibleII > 40) { agent[i].velocity = 0; agent[i].inst = 41; } if (Form1->RadioGroupColumn->ItemIndex == 1 && evo == false) { x = agent[i].x - 230; //1 y = agent[i].y - 400; z = sqrt(x * x + y * y); if (z < 20){ agent[i].direction = M_PI - agent[i].direction; } } if (Form1->RadioGroupColumn->ItemIndex == 2 && evo == false) { x = agent[i].x - 230; //1 y = agent[i].y - 400; z = sqrt(x * x + y * y); if (z < 20){ agent[i].direction = M_PI - agent[i].direction; } x = agent[i].x - 280; //2 y = agent[i].y - 400; z = sqrt(x * x + y * y); if (z < 20){ agent[i].direction = M_PI - agent[i].direction; } x = agent[i].x - 180; //3 y = agent[i].y - 400; z = sqrt(x * x + y * y); if (z < 20){ agent[i].direction = M_PI - agent[i].direction; } } } // } /*/---------------------------------------------------------------------Avoidance if (Form1->RadioGroupFlockingBehavior->ItemIndex == 1 && agent[i].inst != 2000 && agent[i].y < 430 ){ nearestNeighbor(i); if (visibleN > 1) { agent[i].velocity = (1.00/visibleN);//(vectorV + (agent[i].velocity * 199) )/200 ; // average the velocities agent[i].direction = goal(agent[i].x,agent[i].y);//(vectorD+(3*(goal(agent[i].x, agent[i].y))))/4; // agent[i].flocking = TRUE; if (agent[i].inst < 40) { agent[i].inst = visibleII; } if (agent[i].inst > 40) { agent[i].velocity = 0; } } //------------------------------------------------- if (dist < 5 && agent[i].pause == 0) { agent[i].velocityO = agent[i].velocity; agent[i].velocity = 0; agent[i].pause = 50; //int (random(50)); agent[i].direction = goal(agent[i].x, agent[i].y); } if (agent[i].pause > 0) { agent[i].pause--; } if (agent[i].pause == 1) { agent[i].velocity = agent[i].velocityO; } int ram(random(2)); if (ram == 0) { agent[i].inst = (visibleI/visibleN) - int(random(diversity)); } else if (ram == 1) { agent[i].inst = (visibleI/visibleN) + int(random(diversity)); } if (agent[i].inst < 0 || agent[i].inst > 21) { agent[i].inst = int(random(20)); } else if (agent[i].flocking == TRUE) { agent[i].direction = (double(random(1000)) / 500) * M_PI; agent[i].velocity = double(random(1000)) / 1500 + .1; agent[i].flocking = FALSE; } } */ } //---------------------------------------------------------------------- step void step (int f) { iterations++; Form1->EditIterations->Text = iterations; if (!evo){ increment = Form1->TrackBarIncrement->Position; //increment = 100; } penalty = Form1->TrackBarPenalty->Position; Form1->Canvas->Pen->Color = clWhite; Form1->Canvas->MoveTo(30,30); Form1->Canvas->LineTo(430,30); Form1->Canvas->LineTo(430,430); Form1->Canvas->LineTo(240,430); Form1->Canvas->MoveTo(220,430); Form1->Canvas->LineTo(30,430); Form1->Canvas->LineTo(30,30); if (Form1->RadioGroupColumn->ItemIndex == 1 && evo == false || Form1->RadioGroupColumn->ItemIndex == 2 && evo == false) { Form1->Canvas->Pen->Color = clWhite; Form1->Canvas->Brush->Color = clBlack; Form1->Canvas->Ellipse (210, 380, 250, 420); } if (Form1->RadioGroupColumn->ItemIndex == 2 && evo == false) { /*evo = true; increment = 100; injured = 0; for (int k = 0; k < 300; k++) { if (agent[k].inst > 40 && agent[k].inst != 2000) injured++; } Form1->EditIteration->Text = iterations; Form1->EditInjured->Text = injured; Form1->EditPenalty->Text = Form1->TrackBarPenalty->Position; Form1->EditScore->Text = iterations + (injured * penalty); */ Form1->Canvas->Pen->Color = clWhite; Form1->Canvas->Brush->Color = clBlack; Form1->Canvas->Ellipse (260, 380, 300, 420); Form1->Canvas->Pen->Color = clWhite; Form1->Canvas->Brush->Color = clBlack; Form1->Canvas->Ellipse (160, 380, 200, 420); } if (evo) { Form1->Canvas->Pen->Color = clWhite; Form1->Canvas->Brush->Color = clBlack; Form1->Canvas->Ellipse (pattern[f].AX - 20, pattern[f].AY - 20, pattern[f].AX + 20, pattern[f].AY + 20); Form1->Canvas->Pen->Color = clWhite; Form1->Canvas->Brush->Color = clBlack; Form1->Canvas->Ellipse (pattern[f].BX - 20, pattern[f].BY - 20, pattern[f].BX + 20, pattern[f].BY + 20); Form1->Canvas->Pen->Color = clWhite; Form1->Canvas->Brush->Color = clBlack; Form1->Canvas->Ellipse (pattern[f].CX - 20, pattern[f].CY - 20, pattern[f].CX + 20, pattern[f].CY + 20); } for (i = 0; i < 300; i++) { if(Form1->RadioGroupVisible->ItemIndex == 0){ // agents are visible Form1->Canvas->Pen->Color = clBlack; Form1->Canvas->Brush->Color = clBlack; Form1->Canvas->Ellipse (agent[i].pastX, agent[i].pastY + 5, agent[i].pastX +5, agent[i].pastY); // calculate agent's new position based on velocity and direction agent[i].x += (agent[i].velocity/2) * cos(agent[i].direction) * increment; agent[i].y += (agent[i].velocity/2) * sin(agent[i].direction) * increment; agent[i].pastX = agent[i].x; agent[i].pastY= agent[i].y; int ins = agent[i].inst; Form1->Canvas->Pen->Color = static_cast(colorRamp(40, ins)); Form1->Canvas->Brush->Color = static_cast(colorRamp(40, ins)); Form1->Canvas->Ellipse (agent[i].x, agent[i].y + 5, agent[i].x +5, agent[i].y); } if(Form1->RadioGroupVisible->ItemIndex == 1){ //when agents areinvisible agent[i].x += (agent[i].velocity/2) * cos(agent[i].direction) * increment; agent[i].y += (agent[i].velocity/2) * sin(agent[i].direction) * increment; } if (iterations < 2) { agent[i].direction = goal(agent[i].x, agent[i].y); } placebin(i); evac(i); // behavior if (agent[i].x > 425 && agent[i].inst != 2000) { agent[i].direction = goal(agent[i].x, agent[i].y); } if (agent[i].y > 425 && agent[i].x > 220 && agent[i].inst != 2000) { agent[i].direction = goal(agent[i].x, agent[i].y); } if (agent[i].y > 425 && agent[i].x < 240 && agent[i].inst != 2000) { agent[i].direction = goal(agent[i].x, agent[i].y); } if (agent[i].x < 35 && agent[i].inst != 2000) { agent[i].direction = goal(agent[i].x, agent[i].y); } if (agent[i].y < 35) { agent[i].direction = goal(agent[i].x, agent[i].y); } if (agent[i].y > 430) { agent[i].inst = 2000; } if (agent[i].inst == 2000 && agent[i].y < 430) { agent[i].y = 450; agent[i].direction = 1.5; } //evolutinary search of obstacles if (evo == true) { x = agent[i].x - pattern[f].AX; //1 y = agent[i].y - pattern[f].AY; z = sqrt(x * x + y * y); if (z < 20){ agent[i].direction = M_PI - agent[i].direction; } x = agent[i].x - pattern[f].BX; //2 y = agent[i].y - pattern[f].BY; z = sqrt(x * x + y * y); if (z < 20){ agent[i].direction = M_PI - agent[i].direction; } x = agent[i].x - pattern[f].CX; //3 y = agent[i].y - pattern[f].CY; z = sqrt(x * x + y * y); if (z < 20){ agent[i].direction = M_PI - agent[i].direction; } } // modular divide direction by one rotation if (agent[i].direction > 2 * M_PI) { agent[i].direction = agent[i].direction - 2 * M_PI; } if (agent[i].direction < 0) { agent[i].direction = agent[i].direction + 2 * M_PI; } } //----------------------------Stopping---------------------------------------- if (evo == true && iterations > 50) { for (int j = 0; j < 300; j++) { if (agent[j].bin != 16) { break; } else if (j == 299) { stop = true; } } } } //----------------------------------------------------------------for QuickSort int comp(const void *a, const void *b){ return ((SOLUTION *)a)->score - ((SOLUTION *)b)->score; } //-----------------------------------------------------------Evolutionary Search void randomObstacles(void){ for (int i = 0; i < 100; i++) { pattern[i].AX = random(390) + 20; pattern[i].AY = random(390) + 20; pattern[i].BX = random(390) + 20; pattern[i].BY = random(390) + 20; pattern[i].CX = random(390) + 20; pattern[i].CY = random(390) + 20; pattern[i].score = 0; } firstRandom = true; } void cheatRandom(void){ for (int i = 0; i < 100; i++) { pattern[i].AX = 213; pattern[i].AY = 407; pattern[i].BX = 217; pattern[i].BY = 283; pattern[i].CX = 353; pattern[i].CY = 218; } firstRandom = true; } void mutation (int i, int j){ do { int mut = random(200) - 100; pattern[j].AX = pattern[i].AX + mut; } while (pattern[j].AX > 410 || pattern[j].AX < 20); do { int mut = random(200) - 100; pattern[j].AY = pattern[i].AY + mut; } while (pattern[j].AY > 410 || pattern[j].AY < 20); do { int mut = random(200) - 100; pattern[j].BX = pattern[i].BX + mut; } while (pattern[j].BX > 410 || pattern[j].BX < 20); do { int mut = random(200) - 100; pattern[j].BY = pattern[i].BY + mut; } while (pattern[j].BY > 410 || pattern[j].BY < 20); do { int mut = random(200) - 100; pattern[j].CX = pattern[i].CX + mut; } while (pattern[j].CX > 410 || pattern[j].CX < 20); do { int mut = random(200) - 100; pattern[j].CY = pattern[i].CY + mut; } while (pattern[j].CY > 410 || pattern[j].CY < 20); } void mutation2 (int i){ do { int mut = random(200) - 100; patternC[i].AX = patternC[i].AX + mut; } while (patternC[i].AX > 410 || patternC[i].AX < 20); do { int mut = random(200) - 100; patternC[i].AY = patternC[i].AY + mut; } while (patternC[i].AY > 410 || patternC[i].AY < 20); do { int mut = random(200) - 100; patternC[i].BX = patternC[i].BX + mut; } while (patternC[i].BX > 410 || patternC[i].BX < 20); do { int mut = random(200) - 100; patternC[i].BY = patternC[i].BY + mut; } while (patternC[i].BY > 410 || patternC[i].BY < 20); do { int mut = random(200) - 100; patternC[i].CX = patternC[i].CX + mut; } while (patternC[i].CX > 410 || patternC[i].CX < 20); do { int mut = random(200) - 100; patternC[i].CY = patternC[i].CY + mut; } while (patternC[i].CY > 410 || patternC[i].CY < 20); } void suckIn(void){ for (int i = 0; i < 300; i++) { temp[i].x = agent[i].x; temp[i].y = agent[i].y; } } void suckOut(void){ for (int i = 0; i < 300; i++) { agent[i].x = temp[i].x; agent[i].y = temp[i].y; agent[i].bin = 0; agent[i].inst = 1; agent[i].velocity = 0.5; } iterations = 0; injured = 0; Form1->Refresh(); } void graph(void){ if (generation < 250) { Form2->Canvas->Pen->Color = clBlack; Form2->Canvas->MoveTo(generation * 2, 350); Form2->Canvas->LineTo(generation * 2, 350 - pattern[0].score); } if (generation > 250 && generation < 500) { Form2->Canvas->Pen->Color = clBlack; Form2->Canvas->MoveTo((generation * 2) - 499, 350); Form2->Canvas->LineTo((generation * 2) - 499, 350 - pattern[0].score); } if (750 > generation && generation > 500) { Form2->Canvas->Pen->Color = clGray; Form2->Canvas->MoveTo((generation * 2) - 1000, 350); Form2->Canvas->LineTo((generation * 2) - 1000, 350 - pattern[0].score); } if (1000 > generation && generation > 750) { Form2->Canvas->Pen->Color = clGray; Form2->Canvas->MoveTo((generation * 2) - 1499, 350); Form2->Canvas->LineTo((generation * 2) - 1499, 350 - pattern[0].score); } } int roulette(void){ int r = random(10); int s; int result; switch (r) { case 0: case 1: case 2: case 3: s = 1; break; case 4: case 5: case 6: s = 2; break; case 7: case 8: s = 3; break; case 9: s = 4; break; default: s = 0; } switch (s){ case 1: result = random(5); break; case 2: result = random(5) + 5; break; case 3: result = random(15) + 10; break; case 4: result = random(25) + 25; } return result; } void crossover(int l){ int p1 = l; int p2 = l + 1; int n = random(3); int mt = random(4); double tmp; switch (n) { case 0: // Obstacle A tmp = patternC[l].AX; patternC[l].AX = patternC[l+1].AX; patternC[l+1].AX = tmp; tmp = patternC[l].AY; patternC[l].AY = patternC[l+1].AY; patternC[l+1].AY = tmp; break; case 1: //Obstacle B tmp = patternC[p1].BX; patternC[p1].BX = patternC[p2].BX; patternC[p2].BX = tmp; tmp = patternC[p1].BY; patternC[p1].BY = patternC[p2].BY; patternC[p2].BY = tmp; break; case 2: //Obstacle C tmp = patternC[p1].CX; patternC[p1].CX = patternC[p2].CX; patternC[p2].CX = tmp; tmp = patternC[p1].CY; patternC[p1].CY = patternC[p2].CY; patternC[p2].CY = tmp; break; default: ; } if (mt == 2) { //25% will be mutated mutation2(p1); mutation2(p2); } } void copyP(int i, int p1, int p2){ patternC[i].AX = pattern[p1].AX; patternC[i + 1].AX = pattern[p2].AX; patternC[i].AY = pattern[p1].AY; patternC[i + 1].AY = pattern[p2].AY; patternC[i].BX = pattern[p1].BX; patternC[i + 1].BX = pattern[p2].BX; patternC[i].BY = pattern[p1].BY; patternC[i + 1].BY = pattern[p2].BY; patternC[i].CX = pattern[p1].CX; patternC[i + 1].CX = pattern[p2].CX; patternC[i].CY = pattern[p1].CY; patternC[i + 1].CY = pattern[p2].CY; } void reproduction(void){ for (int i = 0; i < 48; i = i+2) { int p1 = roulette(); int p2 = roulette(); int ra = random(10); switch (ra) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: // crpssing over patternC[i].AX = pattern[p1].AX; patternC[i + 1].AX = pattern[p2].AX; patternC[i].AY = pattern[p1].AY; patternC[i + 1].AY = pattern[p2].AY; patternC[i].BX = pattern[p1].BX; patternC[i + 1].BX = pattern[p2].BX; patternC[i].BY = pattern[p1].BY; patternC[i + 1].BY = pattern[p2].BY; patternC[i].CX = pattern[p1].CX; patternC[i + 1].CX = pattern[p2].CX; patternC[i].CY = pattern[p1].CY; patternC[i + 1].CY = pattern[p2].CY; crossover(i); break; case 7: case 8: case 9: patternC[i].AX = pattern[p1].AX; patternC[i + 1].AX = pattern[p2].AX; patternC[i].AY = pattern[p1].AY; patternC[i + 1].AY = pattern[p2].AY; patternC[i].BX = pattern[p1].BX; patternC[i + 1].BX = pattern[p2].BX; patternC[i].BY = pattern[p1].BY; patternC[i + 1].BY = pattern[p2].BY; patternC[i].CX = pattern[p1].CX; patternC[i + 1].CX = pattern[p2].CX; patternC[i].CY = pattern[p1].CY; patternC[i + 1].CY = pattern[p2].CY; break; default: ; } } for (int i = 0; i < 50; i++) { pattern[i+2].AX = patternC[i].AX; pattern[i+2].AY = patternC[i].AY; pattern[i+2].BX = patternC[i].BX; pattern[i+2].BY = patternC[i].BY; pattern[i+2].CX = patternC[i].CX; pattern[i+2].CY = patternC[i].CY; } /* ofstream outfile("resultsC.txt"); for( int g = 0 ; g < 48 ; g++ ){ outfile << patternC[g].AX; outfile <<" "; outfile << patternC[g].AY; outfile <<" "; outfile << patternC[g].BX; outfile <<" "; outfile << patternC[g].BY; outfile <<" "; outfile << patternC[g].CX; outfile <<" "; outfile << patternC[g].CY; outfile <<" "; outfile << patternC[g].itr; outfile <<" "; outfile << patternC[g].inj; outfile <<" "; outfile << patternC[g].score<< endl; } outfile.close(); */ } void nextGeneration2(void){ evo = true; increment = 100; if (firstRandom == true) { // if it is right after the initial random plot, test all for (int i = 0; i < 50; i++) { if (estop == true) { break; } stop = false; if (i == 0 && generation == 0) { //randomize(); shuffle(); suckIn(); } suckOut(); while (stop == false) { step(i); Application->ProcessMessages(); } for (int k = 0; k < 300; k++) { if (agent[k].inst > 40 && agent[k].inst != 2000) injured++; } pattern[i].score = iterations + (injured * penalty); Form1->EditIteration->Text = iterations; Form1->EditInjured->Text = injured; pattern[i].itr = iterations; pattern[i].inj = injured; Form1->EditPenalty->Text = Form1->TrackBarPenalty->Position; Form1->EditScore->Text = pattern[i].score; } firstRandom = false; //if (multiRun) } qsort(pattern, 50, sizeof(SOLUTION), comp); //sort Form1->EditBestScore->Text = pattern[0].score; reproduction(); if(firstRandom == false) { //if it's not the first run, test the newborns for (int s = 2; s < 50; s++) { if (estop == true) { break; } stop = false; //shuffle(); suckOut(); while (stop == false) { step(s); Application->ProcessMessages(); } for (int k = 0; k < 300; k++) { if (agent[k].inst > 40 && agent[k].inst != 2000) injured++; } pattern[s].score = iterations + (injured * penalty); Form1->EditIteration->Text = iterations; pattern[s].itr = iterations; pattern[s].inj = injured; Form1->EditInjured->Text = injured; Form1->EditPenalty->Text = Form1->TrackBarPenalty->Position; Form1->EditScore->Text = pattern[s].score; } } graph(); generation++; Form1->EditGeneration->Text = generation; } void nextGeneration(void){ evo = true; increment = 100; if (firstRandom == true) { // if it is right after the initial random plot, test all for (int i = 0; i < 50; i++) { if (estop == true) { break; } stop = false; if (i == 0) { //randomize(); shuffle(); suckIn(); } suckOut(); while (stop == false) { step(i); Application->ProcessMessages(); } for (int k = 0; k < 300; k++) { if (agent[k].inst > 40 && agent[k].inst != 2000) injured++; } pattern[i].score = iterations + (injured * penalty); Form1->EditIteration->Text = iterations; Form1->EditInjured->Text = injured; pattern[i].itr = iterations; pattern[i].inj = injured; Form1->EditPenalty->Text = Form1->TrackBarPenalty->Position; Form1->EditScore->Text = pattern[i].score; } firstRandom = false; //if (multiRun) } qsort(pattern, 50, sizeof(SOLUTION), comp); //sort Form1->EditBestScore->Text = pattern[0].score; for (int b = 25; b < 50; b++) { //mutation if (b < 35){ for (int a = 0; a < 10; a++) { mutation(a,b); }} if (b > 35) { // copying for (int a = 0; a < 11; a++) { if (a > 10) { a = 0; } pattern[b].AX = pattern[a].AX; pattern[b].AY = pattern[a].AY; pattern[b].BX = pattern[a].BX; pattern[b].BY = pattern[a].BY; pattern[b].CX = pattern[a].CX; pattern[b].CY = pattern[a].CY; } } } if(firstRandom == false) { //if it's not the first run, test the newborns for (int s = 25; s < 50; s++) { if (estop == true) { break; } stop = false; //shuffle(); suckOut(); while (stop == false) { step(s); Application->ProcessMessages(); } for (int k = 0; k < 300; k++) { if (agent[k].inst > 40 && agent[k].inst != 2000) injured++; } pattern[s].score = iterations + (injured * penalty); Form1->EditIteration->Text = iterations; pattern[s].itr = iterations; pattern[s].inj = injured; Form1->EditInjured->Text = injured; Form1->EditPenalty->Text = Form1->TrackBarPenalty->Position; Form1->EditScore->Text = pattern[s].score; } } graph(); //* //*/ generation++; Form1->EditGeneration->Text = generation; } void topten(void){ evo = true; estop = false; increment = 100; for (int q = 10; q > 0; q--) { if (estop == true) { break; } stop = false; shuffle(); //suckOut(); while (stop == false) { step(q); Application->ProcessMessages(); } for (int k = 0; k < 300; k++) { if (agent[k].inst > 40 && agent[k].inst != 2000) injured++; } Form1->EditIteration->Text = iterations; pattern[q].itr = iterations; pattern[q].inj = injured; Form1->EditInjured->Text = injured; Form1->EditPenalty->Text = Form1->TrackBarPenalty->Position; Form1->EditScore->Text = iterations + (injured * penalty); } } void openresults(void){ if (Form1->OpenDialog1->Execute()) { ifstream infile(Form1->OpenDialog1->FileName.c_str()); for (int i = 0; i < 50; i++) { infile >> pattern[i].AX; infile >> pattern[i].AY; infile >> pattern[i].BX; infile >> pattern[i].BY; infile >> pattern[i].CX; infile >> pattern[i].CY; infile >> pattern[i].itr; infile >> pattern[i].inj; infile >> pattern[i].score; } infile.close(); } Form1->OpenDialog1->Destroying(); Application->ProcessMessages(); } void evolution(int steps){ generation = 0; Form2->Visible = true; randomObstacles(); // the initial random plot of obstacles estop = false; for (int i = 0; i < steps; i++) { if (Form1->RadioGroupAlgorithm->ItemIndex == 0) { nextGeneration2(); } if (Form1->RadioGroupAlgorithm->ItemIndex == 1) { nextGeneration(); } Application->ProcessMessages(); // if (estop) break; } qsort(pattern, 50, sizeof(SOLUTION), comp); //sort ofstream outfile("results.txt"); for( int g = 0 ; g < 50 ; g++ ){ outfile << pattern[g].AX; outfile <<" "; outfile << pattern[g].AY; outfile <<" "; outfile << pattern[g].BX; outfile <<" "; outfile << pattern[g].BY; outfile <<" "; outfile << pattern[g].CX; outfile <<" "; outfile << pattern[g].CY; outfile <<" "; outfile << pattern[g].itr; outfile <<" "; outfile << pattern[g].inj; outfile <<" "; outfile << pattern[g].score<< endl; } outfile.close(); } //--------------------------------------------------------------------run void run (void) { stop = false; while (stop == false) { step(1); Application->ProcessMessages(); } } //=========================================================================== // EVENT HANDLERS //=========================================================================== //------------------------------------------------------------ On Form Create void __fastcall TForm1::FormCreate(TObject *Sender) { randomize(); shuffle(); } //---------------------------------------------------------------- run button void __fastcall TForm1::ButtonRunClick(TObject *Sender) { run(); } //--------------------------------------------------------------- step button void __fastcall TForm1::ButtonStepClick(TObject *Sender) { stop = true; step(1); } //--------------------------------------------------------------- stop button void __fastcall TForm1::ButtonStopClick(TObject *Sender) { stop = true; estop = true; evo = false; } //---------------------------------------------------------- randomize button void __fastcall TForm1::ButtonResetClick(TObject *Sender) { reset(); } void __fastcall TForm1::FormPaint(TObject *Sender) { Form1->Canvas->Pen->Color = clWhite; Form1->Canvas->MoveTo(30,30); Form1->Canvas->LineTo(430,30); Form1->Canvas->LineTo(430,430); Form1->Canvas->LineTo(240,430); Form1->Canvas->MoveTo(220,430); Form1->Canvas->LineTo(30,430); Form1->Canvas->LineTo(30,30); for (int i=0; i < 300; i++) { int ins = agent[i].inst; Form1->Canvas->Pen->Color = static_cast(colorRamp(40,ins)); Form1->Canvas->Brush->Color = static_cast(colorRamp(40,ins)); Form1->Canvas->Ellipse (agent[i].x, agent[i].y + 5, agent[i].x +5, agent[i].y); agent[i].pastX = agent[i].x; agent[i].pastY= agent[i].y; } } //--------------------------------------------------------------------------- void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { for (int i = 6; i < 300; i++) { if (agent[i].x < X && agent[i].x > X-5 && agent[i].y < Y && agent[i].y > Y-5 ) { EditVelocity->Text = agent[i].velocity; EditDirection->Text = agent[i].direction; EditAgent->Text = i; EditX->Text = (int)agent[i].x; EditY->Text = (int)agent[i].y; //EditInst->Text = //agent[i].bin; } } } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonGetSClick(TObject *Sender) { getS(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { evolution(200); //1->10+5/2->10+5+5/3->10+5+5+5 } //--------------------------------------------------------------------------- void __fastcall TForm1::Button100Click(TObject *Sender) { evolution(100); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button200Click(TObject *Sender) { evolution(200); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button500Click(TObject *Sender) { evolution(500); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1000Click(TObject *Sender) { evolution(1000); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonFirstRandomClick(TObject *Sender) { evolution(1); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonOpenClick(TObject *Sender) { openresults(); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonBest10Click(TObject *Sender) { topten(); } //---------------------------------------------------------------------------