- #include <iostream>
- #include <stdlib.h>
- #include <time.h>
- #include <math.h>
- #include <fstream>
- #include <windows.h>
- #define LENGTH_GEN 8
- using namespace std;
- struct Person
- {
- char gen[LENGTH_GEN + 1];
- unsigned int value;
- };
- void copyGen(char gen1[], const char gen2[])
- {
- for (int i = 0; i < LENGTH_GEN; i++)
- {
- if (gen2[i] == 0 || gen2[i] == '0')
- gen1[i] = '0';
- else if (gen2[i] == 1 || gen2[i] == '1')
- gen1[i] = '1';
- else
- gen1[i] = -1;
- }
- }
- unsigned int binToDec(const char gen[])
- {
- unsigned int value = 0;
- char genTmp[LENGTH_GEN];
- copyGen(genTmp, gen);
- for (int i = LENGTH_GEN - 1, j = 0; i >= 0; i--, j++)
- {
- if (genTmp[i] == '1')
- value += pow(2, j);
- }
- return value;
- }
- void bindValue(Person persons[], const unsigned int cardin)
- {
- for (int i = 0; i < cardin; i++)
- persons[i].value = binToDec(persons[i].gen);
- }
- void initPersons(Person persons[], const unsigned int cardin)
- {
- srand(time(NULL));
- char gen[LENGTH_GEN];
- for (int i = 0; i < cardin; i++)
- {
- for (int j = 0; j < LENGTH_GEN; j++)
- {
- gen[j] = rand() % 2;
- }
- copyGen(persons[i].gen, gen);
- persons[i].value = binToDec(gen);
- persons[i].gen[LENGTH_GEN] = 0;
- }
- }
- void typePersons(const Person persons[], const unsigned int cardin)
- {
- for (int i = 0; i < cardin; i++)
- cout << i << ": " << persons[i].gen << ", wartosc: " << persons[i].value << endl;
- }
- double punktValue(const double a, const double b, const double c, const double x)
- {
- double y = a * x * x + b * x + c;
- return y;
- }
- void clear(string nazwafileu)
- {
- remove("file.txt");
- }
- void mutation(char gen[], const float probMutation)
- {
- int random;
- for (int i = 0; i < LENGTH_GEN; i++)
- {
- random = rand() % 100 + 1;
- if ((float)random <= probMutation * 100)
- {
- if (gen[i] == '0')
- {
- gen[i] = '1';
- }
- else if (gen[i] == '1')
- {
- gen[i] = '0';
- }
- }
- }
- }
- void best(Person persons[], const unsigned int cardin, const double a, const double b, const double c)
- {
- double value, maxvalue = punktValue(a, b, c, persons[0].value);
- double xMax = persons[0].value;
- for (int i = 1; i < cardin; i++)
- {
- value = punktValue(a, b, c, persons[i].value);
- if (value > maxvalue)
- {
- maxvalue = value;
- xMax = persons[i].value;
- }
- }
- cout << "Wartosc funkcji najlepiej przystosowanego Osobnika wynosi: " << maxvalue << ", dla x = " << xMax << endl;
- ofstream file;
- file.open("wynik.txt", ios::app);
- if (!file)
- cout << "Nie moge otworzyc fileu!n";
- file << xMax << " " << maxvalue << endl;
- file.close();
- }
- void hybirdParents(char *child, const char parentOne[], const char parentTwo[], const int param)
- {
- int cutPoint = rand() % (LENGTH_GEN - 1) + 1;
- if (param == 1)
- {
- for (int i = 0; i < cutPoint; i++)
- child[i] = parentOne[i];
- for (int i = cutPoint; i < LENGTH_GEN; i++)
- child[i] = parentTwo[i];
- }
- else
- {
- for (int i = 0; i < cutPoint; i++)
- child[i] = parentTwo[i];
- for (int i = cutPoint; i < LENGTH_GEN; i++)
- child[i] = parentOne[i];
- }
- }
- void hybrid(Person persons[], const unsigned int cardin, const float probHybird)
- {
- bool busyArray[cardin];
- for (int i = 0; i < cardin; i++)
- busyArray[i] = false;
- int index, random;
- char child1[LENGTH_GEN + 1];
- char child2[LENGTH_GEN + 1];
- child1[LENGTH_GEN] = 0;
- child2[LENGTH_GEN] = 0;
- for (int i = 0; i < cardin / 2; i++)
- {
- index = rand() % (cardin / 2) + (cardin / 2);
- if (!busyArray[index])
- {
- busyArray[i] = true;
- busyArray[index] = true;
- random = rand() % 100 + 1;
- if ((float)random <= probHybird * 100)
- {
- hybirdParents(child1, persons[i].gen, persons[index].gen, 1);
- hybirdParents(child2, persons[i].gen, persons[index].gen, 2);
- copyGen(persons[i].gen, child1);
- copyGen(persons[index].gen, child2);
- }
- }
- else
- {
- i--;
- continue;
- }
- }
- }
- void selection(Person persons[], const unsigned int cardin, const double a, const double b, const double c)
- {
- double fsum = 0;
- double f[cardin];
- double p[cardin];
- for (int i = 0; i < cardin; i++)
- {
- f[i] = punktValue(a, b, c, persons[i].value);
- fsum += f[i];
- }
- for (int i = 0; i < cardin; i++)
- {
- p[i] = f[i] / fsum;
- }
- Person personsTmp[cardin];
- float random, tmp;
- for (int i = 0; i < cardin; i++)
- {
- random = static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
- tmp = 0;
- for (int j = 0; j < cardin; j++)
- {
- tmp += p[j];
- if (tmp >= random)
- {
- copyGen(personsTmp[i].gen, persons[j].gen);
- personsTmp[i].value = persons[j].value;
- break;
- }
- }
- }
- for (int i = 0; i < cardin; i++)
- {
- copyGen(persons[i].gen, personsTmp[i].gen);
- persons[i].value = personsTmp[i].value;
- }
- }
- int main()
- {
- //f(x)=ax^2+bx+c
- const unsigned int populationNumber = 15;
- const unsigned int populationSize = 10;
- const float probHybird = 0.8;
- const float probMutation = 0.1;
- unsigned int NOS = 40;
- double a = 4.0;
- double b = 7.0;
- double c = 2.0;
- clear("wynik.txt");
- cout << "Obliczam wspolczynnik a = 4, b = 7 i c = 2 rownania f(x)=ax^2+bx+c ...." << endl;
- Sleep(2000);
- cout << "Zaczynam krzyzowanie 40 razy, aby znalezc najlepszego!" << endl;
- Sleep(1000);
- if (populationSize % 2 != 0)
- {
- cout << "Liczebnosc populacji musi byc parzysta!" << endl;
- return 1;
- }
- Person persons[populationSize];
- initPersons(persons, populationSize);
- for (int k = 0; k < NOS; k++)
- {
- cout << endl
- << endl
- << "Program nr: " << k + 1 << endl;
- for (int i = 0; i < populationNumber; i++)
- {
- cout << endl
- << "Populacja nr: " << i + 1 << endl;
- typePersons(persons, populationSize);
- hybrid(persons, populationSize, probHybird);
- for (int j = 0; j < populationSize; j++) {
- mutation(persons[j].gen, probMutation);
- }
- selection(persons, populationSize, a, b, c);
- bindValue(persons, populationSize);
- if (i == populationNumber - 1) {
- best(persons, populationSize, a, b, c);
- }
- }
- }
- return 0;
- }