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

Тема в разделе "C/C++/C#", создана пользователем okwell5, 29 янв 2012.

  1. okwell5

    okwell5 Гость

    Задача: есть цель(круг), к которой за определенное количество шагов особи-круги либо достигают, либо не достигают. Достижение с помощью генетического алгоритма.
    Сам алгоритм я написал, все уже вроде готово. Но с визуализацией мне дается тяжело. Осталось только в цикле шагов рисовать объекты(как движение или хотя бы новые как на картинке). Должно получиться примерно такое движение(или посекундное рисование)(см. картинку).
    Вот код:
    Код (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] соответственно
     

    Вложения:

    • 1.JPG
      1.JPG
      Размер файла:
      27 КБ
      Просмотров:
      49
  2. okwell5

    okwell5 Гость

    В общем, сделал в 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() или упустил что-то?
     

    Вложения:

Загрузка...
Похожие Темы - Визуализация Генетического Алгоритма
  1. XenoGig
    Ответов:
    1
    Просмотров:
    1.576
  2. morpheus
    Ответов:
    5
    Просмотров:
    4.219

Поделиться этой страницей