Визуализация Генетического Алгоритма Движения К Цели

  • Автор темы okwell5
  • Дата начала
O

okwell5

Гость
#1
Задача: есть цель(круг), к которой за определенное количество шагов особи-круги либо достигают, либо не достигают. Достижение с помощью генетического алгоритма.
Сам алгоритм я написал, все уже вроде готово. Но с визуализацией мне дается тяжело. Осталось только в цикле шагов рисовать объекты(как движение или хотя бы новые как на картинке). Должно получиться примерно такое движение(или посекундное рисование)(см. картинку).
Вот код:
C++:
// moveC.cpp: определяет точку входа для консольного приложения.
//
#include "stdafx.h"
#include <stdlib.h>
#include<stdio.h>
//#include <gl/glut.h"
#include <math.h>
#include<glut.h>

GLint Width = 512, Height = 512;
//--------------------------------
const int N=3;
const int n=4;
float L=400;
float h=1;
//--------------------------------
class hromos{
public:
float genes[n];
};
//--------------------------------
hromos *H;
//--------------------------------
hromos mutation(hromos hr)
{
if(hr.genes[0]<L/2) hr.genes[0]+=hr.genes[2];//x
if(hr.genes[0]>L/2) hr.genes[0]-=hr.genes[2];//x
hr.genes[1]+=hr.genes[3];//y
hr.genes[3]+=h;//hy

return hr;
}
//--------------------------------
void crossover_and_mutation()
{
int g1,g2;
float c;
hromos *ocross;
ocross=new hromos[N];
hromos *mas;
mas=new hromos[3*N];
//выбор 2х особей 
int io1,io2;
//разные индексы
for(int i=0;i<N/2;++i)
{
do 
io1=rand();
while(io1>=N && io1>=n); 
io2=io1;
while(io2=io1 && io2>=n)
io2=rand();

//копируем выбранные особи в отдельный массив для кроссинговера
ocross[i]=H[io1];
ocross[i+1]=H[io2];
//выбираем 2 случайных гена для обмена
do 
g1=rand();
while(g1>=N && g1>=n); 
g2=g1;
while(g2=g1 && g2>=n)
g2=rand();
//обмен первыми генами
c=ocross[i].genes[g1];
ocross[i].genes[g1]=ocross[i+1].genes[g1];
ocross[i+1].genes[g1]=c;
//обмен вторыми генами
c=ocross[i].genes[g2];
ocross[i].genes[g2]=ocross[i+1].genes[g2];
ocross[i+1].genes[g2]=c;
//мутация потомков
ocross[i]=mutation(ocross[i]);
ocross[i+1]=mutation(ocross[i+1]);
}
//помещаем всех особей(поп.+потомки) в 1 массив для сортировки
for(int i=0;i<N;++i)
mas[i]=H[i];
int k=0;
for(int i=N;i<(N+N);++i)
{
mas[i]=ocross[k];
k++;
}
//сортируем по лучшим показателям x,y по убыванию
hromos d;
for(int i=0;i<(N+N+N);++i)
for(int j=i;j<(N+N+N);++j)
{
if((mas[i].genes[0]+mas[i].genes[1])<(mas[j].genes[0]+mas[j].genes[1]))
{
d=mas[i];
mas[i]=mas[j];
mas[j]=d;
}
}
//из mas создаем новую популяци из лучших особей
for(int i=0;i<N;++i)
H[i]=mas[i];
//рисуем особей

//высвобождаем память
delete[] ocross;
}
//--------------------------------
int _tmain(int argc, char* argv[])
{
int steps;
printf("\nInput count of steps: ");
scanf("%d", &steps);
H=new hromos[N];
for(int i=0;i<N;++i)
for(int j=0;j<n;++j)
H[i].genes[j]=rand();
//на каждом шаге должна рисоваться новая популяция
for(int step=1;step<steps;++step)
{
crossover_and_mutation();
//здесь надо нарисовать получившуюся новую популяцию H[i]
}
}
По коду: координаты х,y - это H.genes[0] и H.genes[1] соответственно
 

Вложения

  • 27 КБ Просмотры: 49
O

okwell5

Гость
#2
В общем, сделал в OpenGL. Но не совсем так, как на рисунке, но примерно так, только цель вверху и кружки одинакового цвета. Но почему-то оно у меня не постепенно выводит на экран шаг за шагом, а все сразу и кажется что нет никакого движения. Может, где-то я не там поставил glFlush() или упустил что-то?
C++:
// очищаем буфер цвета
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
int N = int.Parse(textBox4.Text);
float h = float.Parse(textBox3.Text);
const int n = 4;
int steps;
float xi = 0;
float xj = 0;
float yi = 0;
float yj = 0;
hromos T = new hromos();
int s = int.Parse(textBox1.Text);
T.steps = s;
steps = s;
int N1 = N;
hromos[] lH = new hromos[N1];
int w = 30 * (int)OGl.Height / (int)OGl.Width;
int he = 30;
T.GiveParameters(steps, N, h, w, he);
//coordinate x
for (int i = 0; i < N; ++i)
{
lH[i] = new hromos();
lH[i].GiveParameters(steps, N, h, w, he);
for (int j = 0; j < 1; ++j)
lH[i].genes[j] = (float)lH[i].rrand(w);
}
//coordinate y
for (int i = 0; i < N; ++i)
lH[i].genes[1] = 0;
//steps of coordinates
for (int i = 0; i < N; ++i)
{
lH[i].genes[2] = float.Parse(textBox2.Text);
lH[i].genes[3] = float.Parse(textBox3.Text);
}
int g1, g2;
int fdraw = 1;
float c;
hromos[] ocross = new hromos[N + 1];
for (int l1 = 0; l1 < N + 1; ++l1)
{
ocross[l1] = new hromos();
ocross[l1].GiveParameters(steps, N, h, w, he);
}
hromos[] mas = new hromos[3 * N + 1];
for (int l1 = 0; l1 < 3 * N + 1; ++l1)
{
mas[l1] = new hromos();
mas[l1].GiveParameters(steps, N, h, w, he);
}
//выбор 2х особей 
int io1, io2;
int k = 0;
hromos d = new hromos();
d.GiveParameters(steps, N, h, w, he);
for (int step = 1; step <= steps; ++step)
{
//разные индексы
for (int i = 0; i < N / 2; ++i)
{
io1 = T.rrand(N);
io2 = io1;
while (io2 == io1)
io2 = T.rrand(N);
//копируем выбранные особи в отдельный массив для кроссинговера
for (int j1 = 0; j1 < n; ++j1)
{
ocross[i].genes[j1] = lH[io1].genes[j1];
ocross[i + 1].genes[j1] = lH[io2].genes[j1];
}
//выбираем 2 случайных гена для обмена
do
g1 = T.rrand(n);
while (g1 >= n);
g2 = g1;
while (g2 == g1)
g2 = T.rrand(n);
//обмен первыми генами
c = ocross[i].genes[g1];
ocross[i].genes[g1] = ocross[i + 1].genes[g1];
ocross[i + 1].genes[g1] = c;
//обмен вторыми генами
c = ocross[i].genes[g2];
ocross[i].genes[g2] = ocross[i + 1].genes[g2];
ocross[i + 1].genes[g2] = c;
//мутация потомков
ocross[i].mutation();
ocross[i + 1].mutation();
}
//помещаем всех особей(поп.+потомки) в 1 массив для сортировки
for (int i = 0; i < N; ++i)
mas[i] = lH[i];
for (int i = N; i < (N + N); ++i)
{
mas[i] = ocross[k];
k++;
}
k = 0;
//сортируем по лучшим показателям x,y по убыванию	
xi = 0;
xj = 0;
for (int i = 0; i < (N + N + N); ++i)
for (int j = i; j < (N + N + N); ++j)
{
if ((mas[i].genes[0] < w / 2) && (mas[j].genes[0] < w / 2))
{
xi = w / 2 - mas[i].genes[0];
xj = w / 2 - mas[j].genes[0];
}
if ((mas[i].genes[0] < w / 2) && (mas[j].genes[0] > w / 2))
{
xi = w / 2 - mas[i].genes[0];
xj = mas[j].genes[0] - w / 2;
}
if ((mas[i].genes[0] > w / 2) && (mas[j].genes[0] < w / 2))
{
xi = mas[i].genes[0] = w / 2;
xj = w / 2 - mas[j].genes[0];
}
if ((mas[i].genes[0] > w / 2) && (mas[j].genes[0] > w / 2))
{
xi = mas[i].genes[0] - w / 2;
xj = mas[j].genes[0] - w / 2;
}
yi = he - 2 - mas[i].genes[1];
yj = he - 2 - mas[j].genes[1];
if (Math.Sqrt(xi * xi + yi * yi) > Math.Sqrt(xj * xj + yj * yj))
{
d = mas[i];
mas[i] = mas[j];
mas[j] = d;
}
}
//из mas создаем новую популяци из лучших особей
for (int i = 0; i < N; ++i)
lH[i] = mas[i];
// очищаем текущую матрицу
Gl.glLoadIdentity();
// устанавливаем текущий цвет - красный
Gl.glColor3f(255, 0, 0);
//цель красная
Gl.glColor3f(255, 0, 0);
T.drawCircle(w / 2, he - 2, 1f, T.seg);
for (int ym = 0; ym < N; ++ym)
{
if (lH[ym].genes[1] >= (he - 1)) fdraw = 0;
}
//MessageBox.Show("Шаг: " + step);
label5.Text = "Шаг: " + step;
for (long ll = 0; ll < 10000000; ++ll)
{
;
}
if (fdraw == 1)
{
for (int i = 0; i < N; ++i)
{
Gl.glColor3f(0, 0, 1.0f);
lH[i].drawCircle(lH[i].genes[0], lH[i].genes[1], T.r, T.seg);
// дожидаемся конца визуализации кадра 
Gl.glFlush();
// посылаем сигнал перерисовки элемента OGl 
OGl.Invalidate();
}
}
}
Может, где-то я не там поставил glFlush() или упустил что-то?
 

Вложения