#include #include #include #include #include #include #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(rand()) / static_cast(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; }