Advertisement
patryk

Genetic Algorithm

Jan 10th, 2015
515
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 50.79 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <conio.h>
  3. #include <math.h>
  4. #include <fstream>
  5. #include <cstdlib>
  6. #include <time.h>
  7. #include <string.h>
  8. #include <cstdlib>
  9. #include <iostream>
  10. #include <windows.h>
  11.  
  12.  
  13. using namespace std;
  14.  
  15.  
  16. /*###########__STRUCTURES__#############*/
  17.  
  18. //----------TASK-STRUCTURE----------
  19. struct Task{
  20.     int start_time;
  21.     int time_length;
  22.     int real_number;
  23.     bool isPause;
  24.     Task *next;
  25.  
  26.     Task();
  27.     void add(int start_time, int time_length, int real_number, bool isPause, Task * &head);
  28. };
  29.  
  30. Task::Task() {}
  31.  
  32. void Task::add(int start_time, int time_length, int real_number, bool isPause, Task * &head) {
  33.     Task *new_task = new Task;
  34.     Task *temp;
  35.  
  36.     new_task->start_time = start_time;
  37.     new_task->time_length = time_length;
  38.     new_task->real_number = real_number;
  39.     new_task->isPause = isPause;
  40.     new_task->next = NULL;
  41.  
  42.     temp = head;
  43.     if(temp) {
  44.         while(temp->next) temp = temp->next;
  45.         temp->next = new_task;
  46.     } else head = new_task;
  47. }
  48.  
  49.  
  50. //----------SOLUTION-STRUCTURE----------
  51. struct Solution {
  52.     Task *machine_1_sequence;
  53.     Task *machine_2_sequence;
  54.     int fitness_value;
  55.     Solution *next;
  56.  
  57.     Solution();
  58.     void add(Solution * &head);
  59. };
  60.  
  61. Solution::Solution() {}
  62.  
  63. void Solution::add(Solution * &head) {
  64.     Solution *new_solution = new Solution;
  65.     Solution *temp;
  66.  
  67.     new_solution->machine_1_sequence = NULL;
  68.     new_solution->machine_2_sequence = NULL;
  69.     new_solution->fitness_value = 0;
  70.  
  71.  
  72.     new_solution->next = NULL;
  73.  
  74.     temp = head;
  75.     if(temp) {
  76.         while(temp->next) temp = temp->next;
  77.         temp->next = new_solution;
  78.     } else head = new_solution;
  79. }
  80.  
  81.  
  82. //----------POPULATION-STRUCTURE----------
  83. struct Population {
  84.     Solution *solution;
  85.  
  86.     Population();
  87.     void add_solution(Solution * &old_solution);
  88.     int population_size();
  89. };
  90.  
  91. Population::Population() {
  92.     solution = NULL;
  93. }
  94.  
  95. void Population::add_solution(Solution * &old_solution) {
  96.     Task *machine1_task = old_solution->machine_1_sequence;
  97.     Task *machine2_task = old_solution->machine_2_sequence;
  98.  
  99.     solution->add(solution);
  100.     Solution *new_solution = solution;
  101.  
  102.     while(new_solution->next) new_solution = new_solution->next;
  103.  
  104.     while(machine1_task) {
  105.         new_solution->machine_1_sequence->add(machine1_task->start_time, machine1_task->time_length, machine1_task->real_number, false, new_solution->machine_1_sequence);
  106.         machine1_task = machine1_task->next;
  107.     }
  108.  
  109.     while(machine2_task) {
  110.         new_solution->machine_2_sequence->add(machine2_task->start_time, machine2_task->time_length, machine2_task->real_number, false, new_solution->machine_2_sequence);
  111.         machine2_task = machine2_task->next;
  112.     }
  113.     new_solution->fitness_value = old_solution->fitness_value;
  114. }
  115.  
  116. int Population::population_size() {
  117.     Solution *temp_solution = solution;
  118.     int population_size = 0;
  119.  
  120.     while(temp_solution) {
  121.         population_size++;
  122.         temp_solution = temp_solution->next;
  123.     }
  124.  
  125.     return population_size;
  126. }
  127.  
  128.  
  129. //---------GLOBAL-VARIABLES----------------
  130. Task *machine1_operations;
  131. Task *machine2_operations;
  132.  
  133. Task *machine1_pauses;
  134. Task *machine2_pauses;
  135.  
  136.  
  137. /*###########__ALGORITHM-FUNCTIONS__#############*/
  138.  
  139. /**
  140.     Funkcja ta zamienia miejscami dwa zadania.
  141.     Jest ona używana w procesie mutacji.
  142.  
  143.     @param sequence wskaźnik na początek uszeregowania (pierwsze zadanie w szeregu)
  144.     @param task1 wskaźnik na pierwsze zadanie do zamiany
  145.     @param task2 wskaźnik na drugie zadanie do zamiany
  146. */
  147. void swapTasks(Task *sequence, Task *task1, Task *task2) {
  148.  
  149.     Task *temp_sequence = sequence;
  150.     Task *task1_prev, *task2_prev;
  151.     Task *temp_task;
  152.  
  153. //--ZAMIANA-GDY-ZADANIE-PIERWSZE-JEST-NA-PIERWSZYM-MIEJSCU-USZEREGOWANIA
  154.     if(task1->real_number == temp_sequence->real_number) {
  155.  
  156.          if(task1->next == task2) {
  157.  
  158.             task1->next = task2->next;
  159.             task2->next = task1;
  160.             sequence = task2;
  161.  
  162.             int tempStartTime = task1->start_time;
  163.             task1->start_time = task2->start_time;
  164.             task2->start_time = tempStartTime;
  165.             return;
  166.         }
  167.  
  168.         while(temp_sequence) {
  169.             if(temp_sequence->next->real_number == task2->real_number) {
  170.                 task2_prev = temp_sequence;
  171.                     break;
  172.             }
  173.             temp_sequence = temp_sequence->next;
  174.         }
  175.  
  176.         temp_task = task1->next;
  177.         task1->next = task2->next;
  178.         task2->next = temp_task;
  179.  
  180.         task2_prev->next = task1;
  181.         sequence = task2;
  182.  
  183.         int tempStartTime = task1->start_time;
  184.         task1->start_time = task2->start_time;
  185.         task2->start_time = tempStartTime;
  186.         return;
  187.     }
  188.  
  189. //--ZAMIANA-GDY-ZADANIE-DRUGIE-JEST-NA-PIERWSZYM-MIEJSCU-USZEREGOWANIA
  190.     if(task2->real_number == temp_sequence->real_number) {
  191.  
  192.         if(task2->next == task1) {
  193.  
  194.             task2->next = task1->next;
  195.             task1->next = task2;
  196.             sequence = task1;
  197.  
  198.             int tempStartTime = task1->start_time;
  199.             task1->start_time = task2->start_time;
  200.             task2->start_time = tempStartTime;
  201.             return;
  202.         }
  203.  
  204.         while(temp_sequence) {
  205.                 if(temp_sequence->next->real_number == task1->real_number) {
  206.                     task1_prev = temp_sequence;
  207.                     break;
  208.                 }
  209.             temp_sequence = temp_sequence->next;
  210.         }
  211.  
  212.         temp_task = task1->next;
  213.         task1->next = task2->next;
  214.         task2->next = temp_task;
  215.  
  216.         task1_prev->next = task2;
  217.         sequence = task1;
  218.  
  219.         int tempStartTime = task1->start_time;
  220.         task1->start_time = task2->start_time;
  221.         task2->start_time = tempStartTime;
  222.         return;
  223.     }
  224.  
  225. //--ZAMIANA-GDY-ZADANIA-NASTEPUJA-JEDEN-PO-DRUGIM
  226.     if(task1->next == task2) {
  227.         while(temp_sequence) {
  228.             if (temp_sequence->next->real_number == task1->real_number) {
  229.                 task1_prev = temp_sequence;
  230.                 break;
  231.             }
  232.             temp_sequence = temp_sequence->next;
  233.         }
  234.         task1_prev->next = task2;
  235.  
  236.         temp_task = task2->next;
  237.         task2->next = task1;
  238.         task1->next = temp_task;
  239.  
  240.         int tempStartTime = task1->start_time;
  241.         task1->start_time = task2->start_time;
  242.         task2->start_time = tempStartTime;
  243.         return;
  244.     }
  245.  
  246.     if(task2->next == task1) {
  247.         while(temp_sequence) {
  248.             if (temp_sequence->next->real_number == task2->real_number) {
  249.                 task2_prev = temp_sequence;
  250.                 break;
  251.             }
  252.             temp_sequence = temp_sequence->next;
  253.         }
  254.         task2_prev->next = task1;
  255.  
  256.         temp_task = task1->next;
  257.         task1->next = task2;
  258.         task2->next = temp_task;
  259.  
  260.         int tempStartTime = task1->start_time;
  261.         task1->start_time = task2->start_time;
  262.         task2->start_time = tempStartTime;
  263.         return;
  264.     }
  265.  
  266. //--ZAMIANA-W-KAZDYM-INNYM-PRZYPADKU
  267.     while(temp_sequence) {
  268.  
  269.         if(!temp_sequence->next) break;
  270.         if(temp_sequence->next->real_number == task1->real_number) task1_prev = temp_sequence;
  271.         if(temp_sequence->next->real_number == task2->real_number) task2_prev = temp_sequence;
  272.  
  273.         temp_sequence = temp_sequence->next;
  274.     }
  275.  
  276.     task1_prev->next = task2;
  277.     task2_prev->next = task1;
  278.  
  279.     temp_task = task1->next;
  280.     task1->next = task2->next;
  281.     task2->next = temp_task;
  282.  
  283.     int tempStartTime = task1->start_time;
  284.     task1->start_time = task2->start_time;
  285.     task2->start_time = tempStartTime;
  286. }
  287.  
  288.  
  289. /**
  290.     Funkcja ta zwraca wskaźnik na zadanie znajdujące się w rozwiązaniu.
  291.  
  292.     @param sequence wskaźnik na uszeregowanie (pierwsze zadanie w szeregu)
  293.     @param task2 wskaźnik na poszukiwane zadanie
  294.  
  295.     @return wskaźnik na poszukiwane zadanie dla danego uszeregowania
  296. */
  297. Task *takeFromSequence(Task *sequence, Task *task2){
  298.  
  299.     Task *temp;
  300.     Task *takenTask;
  301.     temp = sequence;
  302.  
  303.     if(task2 == sequence){
  304.         if(sequence){
  305.             takenTask = sequence;
  306.             sequence = sequence->next;
  307.         }
  308.  
  309.     } else {
  310.  
  311.         while(temp->next != task2){
  312.             temp = temp->next;
  313.         }
  314.  
  315.         takenTask = temp->next;
  316.         temp->next = task2->next;
  317.  
  318.     }
  319.     return takenTask;
  320. }
  321.  
  322.  
  323. /**
  324.     Funkcja sprawdza czy zadanie koliduje z przerwą konserwującą.
  325.  
  326.     @param task wskaźnik na zadanie, które będzie porównywane
  327.     @param pauses wskaźnik na listę przerw
  328.  
  329.     @return true or false, w zależności od tego czy koliduje zadanie z pauzą czy nie
  330. */
  331. bool isCollideWithPause(Task *task, Task *pauses){
  332.  
  333.     Task *pause = pauses;
  334.  
  335.     while(pause){
  336.         for(int i = task->start_time ; i <= task->start_time + task->time_length ; i++) {
  337.             if(i > pause->start_time && i < pause->start_time + pause->time_length) {
  338.                 return true;
  339.             }
  340.         }
  341.         pause = pause->next;
  342.     }
  343.  
  344.     return false;
  345. }
  346.  
  347.  
  348. /**
  349.     Funkcja zwracająca możliwy czas startu zadania.
  350.     Używana jest tylko, gdy badamy czas startu operacji drugiej zadania.
  351.  
  352.     @param solution wskaźnik na dane uszeregowanie (pierwsze zadanie w uszeregowaniu).
  353.     @param task wskaźnik na zadanie, dla którego znajdujemy najbliższy możliwy czas startu.
  354.  
  355.     @return możliwy czas startu podanego zadania.
  356. */
  357. int returnPossibleStartTime(Solution *solution, Task *task){
  358.  
  359.     Task *next_task = solution->machine_1_sequence;
  360.  
  361.     while (next_task->real_number != task->real_number) {
  362.         next_task = next_task->next;
  363.         if(!next_task) return 0;
  364.  
  365.     }
  366.     return next_task->start_time + next_task->time_length;
  367.  
  368. }
  369.  
  370.  
  371. /**
  372.     Funkcja ta wstawia nowe zadanie w najbliższe możliwe miejsce uwzględniająć wszystkie
  373.     kryteria problemu szeregowania zadań.
  374.  
  375.     @param solution wskaźnik na dane uszeregowanie do którego ma zostać dodane nowe zadanie.
  376.     @param task wskaźnik na zadanie, które ma zostać dodane.
  377.     @param machine_number numer maszyny zgodnej z danym uszeregowaniem.
  378. */
  379. void insertToSequence(Solution *solution, Task *task, int machine_number) {
  380.  
  381.     if(machine_number == 1) {
  382.  
  383.         int task_start_time = 0;
  384.         int task_finish_time = task_start_time + task->time_length;
  385.         bool checkEverythingAgain = true;
  386.  
  387.         while(checkEverythingAgain) {
  388.             checkEverythingAgain = false;
  389.  
  390.             bool checkTasksAgain = true;
  391.             while(checkTasksAgain) {
  392.                 Task *solution_task = solution->machine_1_sequence;
  393.                 while(solution_task) {
  394.                     for(int i = task_start_time ; i <= task_finish_time ; i++) {
  395.                         if(i > solution_task->start_time && i < solution_task->start_time + solution_task->time_length) {
  396.                             task_start_time = solution_task->start_time + solution_task->time_length;
  397.                             task_finish_time = task_start_time + task->time_length;
  398.                             checkTasksAgain = true;
  399.                             checkEverythingAgain = true;
  400.                             break;
  401.                         }
  402.                     }
  403.                     checkTasksAgain = false;
  404.                     solution_task = solution_task->next;
  405.                 }
  406.             }
  407.  
  408.             bool checkPausesAgain = true;
  409.             while(checkPausesAgain) {
  410.                 Task *pauseM1 = machine1_pauses;
  411.                 while(pauseM1) {
  412.                     for(int i = task_start_time ; i <= task_finish_time ; i++) {
  413.                         if(i > pauseM1->start_time && i < pauseM1->start_time + pauseM1->time_length) {
  414.                             task_start_time = pauseM1->start_time + pauseM1->time_length;
  415.                             task_finish_time = task_start_time + task->time_length;
  416.                             checkPausesAgain = true;
  417.                             checkEverythingAgain = true;
  418.                             break;
  419.                         }
  420.                     }
  421.                     checkPausesAgain = false;
  422.                     pauseM1 = pauseM1->next;
  423.                 }
  424.             }
  425.         }
  426.  
  427.         Task *solution_task = solution->machine_1_sequence;
  428.         Task *new_task = new Task;
  429.         new_task->start_time = task_start_time;
  430.         new_task->real_number = task->real_number;
  431.         new_task->isPause = false;
  432.         new_task->time_length = task->time_length;
  433.         new_task->next=NULL;
  434.  
  435.         if(task_start_time < solution_task->start_time) {
  436.  
  437.             new_task->next = solution_task;
  438.             solution->machine_1_sequence = new_task;
  439.  
  440.         } else {
  441.             while(solution_task) {
  442.                 if(!solution_task->next) {
  443.                     solution_task->next = new_task;
  444.                     break;
  445.                 }
  446.  
  447.                 if(solution_task->next->start_time > task_start_time) {
  448.  
  449.                     Task *temp_task = solution_task->next;
  450.                     solution_task->next = new_task;
  451.                     new_task->next = temp_task;
  452.                     break;
  453.                 }
  454.                 solution_task = solution_task->next;
  455.             }
  456.         }
  457.  
  458.     } else if(machine_number == 2) {
  459.  
  460.         int task_start_time = returnPossibleStartTime(solution, task);
  461.         int task_finish_time = task_start_time + task->time_length;
  462.         bool checkEverythingAgain = true;
  463.  
  464.         while(checkEverythingAgain) {
  465.             checkEverythingAgain = false;
  466.  
  467.             bool checkTasksAgain = true;
  468.             while(checkTasksAgain) {
  469.                 Task *solution_task = solution->machine_2_sequence;
  470.                 while(solution_task) {
  471.                     for(int i = task_start_time ; i <= task_finish_time ; i++) {
  472.                         if(i > solution_task->start_time && i < solution_task->start_time + solution_task->time_length) {
  473.                             task_start_time = solution_task->start_time + solution_task->time_length;
  474.                             task_finish_time = task_start_time + task->time_length;
  475.                             checkTasksAgain = true;
  476.                             checkEverythingAgain = true;
  477.                             break;
  478.                         }
  479.                     }
  480.                     checkTasksAgain = false;
  481.                     solution_task = solution_task->next;
  482.                 }
  483.             }
  484.  
  485.             bool checkPausesAgain = true;
  486.             while(checkPausesAgain) {
  487.                 Task *pauseM2 = machine2_pauses;
  488.                 while(pauseM2) {
  489.                     for(int i = task_start_time ; i <= task_finish_time ; i++) {
  490.                         if(i > pauseM2->start_time && i < pauseM2->start_time + pauseM2->time_length) {
  491.                             task_start_time = pauseM2->start_time + pauseM2->time_length;
  492.                             task_finish_time = task_start_time + task->time_length;
  493.                             checkPausesAgain = true;
  494.                             checkEverythingAgain = true;
  495.                             break;
  496.                         }
  497.                     }
  498.                     checkPausesAgain = false;
  499.                     pauseM2 = pauseM2->next;
  500.                 }
  501.             }
  502.         }
  503.  
  504.         Task *solution_task = solution->machine_2_sequence;
  505.         Task *new_task = new Task;
  506.         new_task->start_time = task_start_time;
  507.         new_task->real_number = task->real_number;
  508.         new_task->isPause = false;
  509.         new_task->time_length = task->time_length;
  510.         new_task->next=NULL;
  511.  
  512.  
  513.         if(task_start_time < solution_task->start_time) {
  514.  
  515.            new_task->next = solution_task;
  516.             solution->machine_2_sequence = new_task;
  517.  
  518.         } else {
  519.             while(solution_task) {
  520.                 if(!solution_task->next) {
  521.                     solution_task->next = new_task;
  522.                     break;
  523.                 }
  524.  
  525.                 if(solution_task->next->start_time > task_start_time) {
  526.  
  527.                     Task *temp_task = solution_task->next;
  528.                     solution_task->next = new_task;
  529.                     new_task->next = temp_task;
  530.                     break;
  531.                 }
  532.                 solution_task = solution_task->next;
  533.             }
  534.         }
  535.     }
  536.  
  537. }
  538.  
  539.  
  540. /**
  541.     Funkcja odpowiedzialna za naprawę ewentualnych błędów w osobniku
  542.     powstałych w wyniku operacji mutacji i krzyżowania.
  543.  
  544.     @param solution wskaźnik na rozwiązanie, które ma zostać sprawdzone i naprawione.
  545.     @param numberOfTasks liczba zadań dla danego uszeregowania.
  546. */
  547. void repair(Solution *solution, int numberOfTasks){
  548.  
  549.     Task *task1;
  550.     Task *temp_task;
  551.     Task *task2;
  552.     bool tasks[numberOfTasks];
  553.  
  554. //--USUWANIE-POWIELEN-NA-MASZYNIE-1
  555.     for(int i = 0 ; i < numberOfTasks ; i++) tasks[i] = false;
  556.  
  557.     task1 = solution->machine_1_sequence;
  558.     while(task1) {
  559.         if(tasks[task1->real_number]){
  560.  
  561.             temp_task = task1->next;
  562.             delete takeFromSequence(solution->machine_1_sequence, task1);
  563.             task1 = temp_task;
  564.  
  565.         } else {
  566.             tasks[task1->real_number] = true;
  567.             task1 = task1->next;
  568.         }
  569.     }
  570.  
  571. //--DOPISYWANIE-BRAKUJACYCH-ZADAN-DO-MASZYNY-1
  572.     for(int i = 0 ; i < numberOfTasks ; i++){
  573.  
  574.         if(!tasks[i]){
  575.  
  576.             task1 = machine1_operations;
  577.  
  578.             while(task1->real_number != i){
  579.                 task1 = task1->next;
  580.             }
  581.  
  582.             insertToSequence(solution, task1, 1);
  583.         }
  584.     }
  585.  
  586. //--USUWANIE-POWIELEN-NA-MASZYNIE-2
  587.     for(int i = 0 ; i < numberOfTasks ; i++) tasks[i] = false;
  588.  
  589.     task1 = solution->machine_2_sequence;
  590.     while(task1) {
  591.         if(tasks[task1->real_number]){
  592.             temp_task = task1->next;
  593.             delete takeFromSequence(solution->machine_2_sequence, task1);
  594.             task1 = temp_task;
  595.         } else {
  596.             tasks[task1->real_number] = true;
  597.             task1 = task1->next;
  598.         }
  599.     }
  600.  
  601. //--DOPISYWANIE-BRAKUJACYCH-ZADAN-NA-MASZYNIE-2
  602.     for(int i = 0 ; i < numberOfTasks ; i++){
  603.  
  604.         if(!tasks[i]) {
  605.             task1 = machine2_operations;
  606.  
  607.             while(task1->real_number != i){
  608.                 task1 = task1->next;
  609.             }
  610.  
  611.             insertToSequence(solution, task1, 2);
  612.         }
  613.     }
  614.  
  615. //--PRZESTAWIANIE-NIEPASUJACYCH-ZADAN-NA-MASZYNIE-1
  616.     task1 = solution->machine_1_sequence;
  617.  
  618.     while(task1->next){
  619.  
  620.         if( (task1->start_time + task1->time_length > task1->next->start_time) || isCollideWithPause(task1, machine1_pauses) ){
  621.             task2 = task1->next;
  622.             temp_task = takeFromSequence(solution->machine_1_sequence, task1);
  623.             Task *global_task=machine1_operations;
  624.  
  625.             while(global_task->real_number != temp_task->real_number) global_task = global_task->next;
  626.  
  627.             insertToSequence(solution, global_task, 1);
  628.             //delete temp_task;
  629.  
  630.             task1 = task2;
  631.  
  632.         } else task1=task1->next;
  633.  
  634.     }
  635.  
  636. //--PRZESTAWIANIE-NIEPASUJACYCH-ZADAN-NA-MASZYNIE-2
  637.     task1 = solution->machine_2_sequence;
  638.     while(task1->next){
  639.  
  640.         if( (task1->start_time + task1->time_length > task1->next->start_time) || isCollideWithPause(task1, machine2_pauses) || returnPossibleStartTime(solution, task1) < task1->start_time){
  641.             task2 = task1->next;
  642.             temp_task = takeFromSequence(solution->machine_2_sequence, task1);
  643.  
  644.             Task *global_task=machine2_operations;
  645.  
  646.             while(global_task->real_number != temp_task->real_number) global_task = global_task->next;
  647.  
  648.             insertToSequence(solution, global_task, 2);
  649.             //delete temp_task;
  650.  
  651.             task1 = task2;
  652.         } else task1 = task1->next;
  653.     }
  654.  
  655. }
  656.  
  657.  
  658. /**
  659.     Operator algorytmu genetycznego - mutacja. Odpowiedzialny za zamianę ze sobą dwóch
  660.     zadań w rozwiązaniu (ang. bit swap mutation).
  661.  
  662.     @param old_solution wskaźnik na stare rozwiązanie
  663.     @param numberOfTasks liczba zadań w danej instancji problemu.
  664.     @param population wskaźnik na całą nową populację, do której zostanie dodane nowe rozwiązanie.
  665. */
  666. void mutate(Solution *old_solution, int numberOfTasks, Population *population) {
  667.  
  668.     population->add_solution(old_solution);
  669.     Solution *new_solution = population->solution;
  670.     while(new_solution->next) new_solution = new_solution->next;
  671.  
  672.     Task *z1_op1 = new_solution->machine_1_sequence;                //---WSKAZNIK-NA-ZADANIE-1-NA-MASZYNIE-1
  673.     Task *z2_op1 = new_solution->machine_1_sequence;                //---WSKAZNIK-NA-ZADANIE-2-NA-MASZYNIE-1
  674.     Task *z1_op2 = new_solution->machine_2_sequence;                //---WSKAZNIK-NA-ZADANIE-1-NA-MASZYNIE-2
  675.     Task *z2_op2 = new_solution->machine_2_sequence;                //---WSKAZNIK-NA-ZADANIE-2-NA-MASZYNIE-2
  676.  
  677.     int z1_rand = rand() % (numberOfTasks - 2) + 1;                           //---LOSOWANIE-NUMERU-ZADANIA-1-NA-MASZYNIE-1
  678.     for(int i = 0 ; i < z1_rand ; i++) z1_op1 = z1_op1->next;             //---PRZESUNIECIE-WSKAZNIKA-DO-TEGO-ZADANIA
  679.  
  680.  
  681.     int z2_rand = rand() % (numberOfTasks - 2) + 1;                               //---LOSOWANIE-NUMERU-ZADANIA-2-NA-MASZYNIE-1
  682.     while (z1_rand == z2_rand) z2_rand = rand() % (numberOfTasks - 2) + 1;         //---SPRAWDZANIE-CZY-NIE-WYLOSOWANO-TEGO-SAMEGO-ZADANIA
  683.  
  684.     for(int i = 0 ; i < z2_rand ; i++) z2_op1 = z2_op1->next;             //---PRZESUNIECIE-WSKAZNIKA-DO-TEGO-ZADANIA
  685.  
  686. //--WYSZUKANIE-TYCH-ZADAN-NA-MASZYNIE-DRUGIEJ-I-USTAWIENIE-WSKAZNIKA
  687.     while(z1_op2->real_number != z1_op1->real_number) z1_op2 = z1_op2->next;
  688.     while(z2_op2->real_number != z2_op1->real_number) z2_op2 = z2_op2->next;
  689.  
  690.     swapTasks(new_solution->machine_1_sequence, z1_op1, z2_op1);            //---ZAMIANA-ZADAN-NA-MASZYNIE-1
  691.     swapTasks(new_solution->machine_2_sequence, z1_op2, z2_op2);            //---ZAMIANA-ZADAN-NA-MASZYNIE-2
  692.  
  693.     repair(new_solution, numberOfTasks);               //---NAPRAWIENIE-EWENTUALNIE-POWSTALYCH-BLEDOW-USZEREGOWANIA
  694. }
  695.  
  696.  
  697. /**
  698.     Operator algorytmu genetycznego - krzyżowanie. Krzyżowanie jest wykonywane
  699.     w dwóch punktach, co oznacza, że losowany jest przedział, który będzie punktem
  700.     podziału dwóch starych rozwiązań, w dwa nowe.
  701.  
  702.     @param old_solution1 wskaźnik na pierwsze stare rozwiązanie (rodzic 1).
  703.     @param old_population wskaźnik na starą populację rozwiązań.
  704.     @param numberOfTasks liczba zadań dla danego problemu.
  705.     @param population wskaźnik na nową populację do której zostaną dodane nowe rozwiązania.
  706. */
  707. void crossover(Solution *old_solution1, Population *old_population, int numberOfTasks, Population *population) {
  708.  
  709. //--SZUKANIE-DRUGIEGO-,-INNEGO-ROZWIAZANIA-ZE-STAREJ-POPULACJI
  710.     Solution *old_solution2;
  711.     do {
  712.         old_solution2 = old_population->solution;
  713.         int rand_second_solution = rand() % (old_population->population_size() - 1);
  714.         for(int i = 0 ; i < rand_second_solution ; i++) old_solution2 = old_solution2->next;
  715.     } while (old_solution1->fitness_value == old_solution2->fitness_value);
  716.  
  717. //--DODANIE-PIERWSZEGO-STAREGO-ROZWIAZANIA-DO-NOWEJ-POPULLACJI-I-ZNALEZIENIE-GO
  718.     population->add_solution(old_solution1);
  719.     Solution *new_solution1 = population->solution;
  720.     while(new_solution1->next) new_solution1 = new_solution1->next;
  721.  
  722. //--DODANIE-DRUGIEGO-STAREGO-ROZWIAZANIA-DO-NOWEJ-POPULACJI-I-ZNALEZIENIE-GO
  723.     population->add_solution(old_solution2);
  724.     Solution *new_solution2 = population->solution;
  725.     while(new_solution2->next) new_solution2 = new_solution2->next;
  726.  
  727. /*KRZYZOWANIE-NA-MASZYNIE-1*/
  728.     Task *start_task1 = new_solution1->machine_1_sequence;
  729.     Task *over_task1 = new_solution1->machine_1_sequence;
  730.     Task *start_task2 = new_solution2->machine_1_sequence;
  731.     Task *over_task2 = new_solution2->machine_1_sequence;
  732.     Task *before_start_task1 = new_solution1->machine_1_sequence;
  733.     Task *before_start_task2 = new_solution2->machine_1_sequence;
  734.     Task *after_over_task1;
  735.     Task *after_over_task2;
  736.  
  737.     int task_start_time;
  738.     int rand_start_range;
  739.     int rand_over_range;
  740.  
  741.  
  742.     do {
  743.         rand_start_range = rand() % (numberOfTasks - 2) + 1;
  744.         rand_over_range = rand() % (numberOfTasks - 2) + 1;
  745.     } while(rand_start_range == rand_over_range || rand_start_range == rand_over_range + 1 || rand_start_range == rand_over_range - 1);
  746.  
  747.     if(rand_start_range > rand_over_range) {
  748.         int temp = rand_start_range;
  749.         rand_start_range = rand_over_range;
  750.         rand_over_range = temp;
  751.     }
  752.  
  753. //--PRZESUNIECIE-WSKAZNIKA-NA-POCZATEK-ZAKRESU
  754.     for(int i = 0 ; i < rand_start_range ; i++){
  755.         start_task1 = start_task1->next;
  756.         start_task2 = start_task2->next;
  757.     }
  758.  
  759. //--PRZESUNIECIE-WSKAZNIKA-NA-KONIEC-ZAKRESU
  760.     for(int i = 0 ; i < rand_over_range ; i++){
  761.         over_task1 = over_task1->next;
  762.         over_task2 = over_task2->next;
  763.     }
  764.  
  765.     while(before_start_task1->next != start_task1) before_start_task1 = before_start_task1->next;
  766.     while(before_start_task2->next != start_task2) before_start_task2 = before_start_task2->next;
  767.  
  768.     after_over_task1 = over_task1->next;
  769.     after_over_task2 = over_task2->next;
  770.  
  771.     task_start_time = start_task1->start_time;
  772.     start_task1->start_time = start_task2->start_time;
  773.     start_task2->start_time = task_start_time;
  774.  
  775.     before_start_task1->next = start_task2;
  776.     before_start_task2->next = start_task1;
  777.     over_task1->next = after_over_task2;
  778.     over_task2->next = after_over_task1;
  779.  
  780. //--AKTUALIZACJA-CZASOW-ROZPOCZECIA
  781.     before_start_task1 = start_task1;
  782.     while(before_start_task1 != over_task1) {
  783.         before_start_task1->next->start_time = before_start_task1->start_time + before_start_task1->time_length;
  784.         before_start_task1 = before_start_task1->next;
  785.     }
  786.  
  787.     before_start_task2 = start_task2;
  788.     while(before_start_task2 != over_task2) {
  789.         before_start_task2->next->start_time = before_start_task2->start_time + before_start_task2->time_length;
  790.         before_start_task2 = before_start_task2->next;
  791.     }
  792.  
  793. /*KRZYZOWANIE-NA-MASZYNIE-2*/
  794.     start_task1 = new_solution1->machine_2_sequence;
  795.     start_task2 = new_solution2->machine_2_sequence;
  796.     before_start_task1 = new_solution1->machine_2_sequence;
  797.     before_start_task2 = new_solution2->machine_2_sequence;
  798.     over_task1=new_solution1->machine_2_sequence;
  799.     over_task2=new_solution2->machine_2_sequence;
  800. //--PRZESUNIECIE-WSKAZNIKA-NA-POCZATEK-ZAKRESU
  801.     for(int i = 0 ; i < rand_start_range ; i++){
  802.         start_task1 = start_task1->next;
  803.         start_task2 = start_task2->next;
  804.     }
  805.  
  806. //--PRZESUNIECIE-WSKAZNIKA-NA-KONIEC-ZAKRESU
  807.     for(int i = 0 ; i < rand_over_range ; i++){
  808.         over_task1 = over_task1->next;
  809.         over_task2 = over_task2->next;
  810.     }
  811.  
  812.     while(before_start_task1->next != start_task1) before_start_task1 = before_start_task1->next;
  813.     while(before_start_task2->next != start_task2) before_start_task2=before_start_task2->next;
  814.  
  815.     after_over_task1 = over_task1->next;
  816.     after_over_task2 = over_task2->next;
  817.  
  818.     task_start_time = start_task1->start_time;
  819.     start_task1->start_time = start_task2->start_time;
  820.     start_task2->start_time = task_start_time;
  821.  
  822.     over_task1->next = after_over_task2;
  823.     over_task2->next = after_over_task1;
  824.     before_start_task1->next = start_task2;
  825.     before_start_task2->next = start_task1;
  826.  
  827. //--AKTUALIZACJA-CZASOW-ROZPOCZECIA
  828.     before_start_task1 = start_task1;
  829.     while(before_start_task1 != over_task1){
  830.         before_start_task1->next->start_time = before_start_task1->start_time + before_start_task1->time_length;
  831.         before_start_task1 = before_start_task1->next;
  832.     }
  833.  
  834.     before_start_task2=start_task2;
  835.     while(before_start_task2 != over_task2){
  836.         before_start_task2->next->start_time = before_start_task2->start_time + before_start_task2->time_length;
  837.         before_start_task2 = before_start_task2->next;
  838.     }
  839.  
  840.     repair(new_solution1, numberOfTasks);
  841.     repair(new_solution2, numberOfTasks);
  842. }
  843.  
  844.  
  845. //---------------------SELECTION-OPERATOR---------------------------
  846.  
  847.  
  848. /**
  849.     Funkcja wyliczająca wartość funkcji celu, dla każdego rozwiązania
  850.     w populacji.
  851.  
  852.     @param population wskaźnik na populację, dla której ma zostać wyliczona wartość funkcji celu.
  853. */
  854. void calculate_fitness(Population *population) {
  855.     Solution *solution = population->solution;                                      //---WSKAZNIK-NA-PIERWSZE-ROZWIAZANIE-W-POPULACJI
  856.     int maxFitnessValue = 0;                                                        //---ZMIENNA-PRZECHOWUJACA-WARTOSC-NAJWIEKSZEJ-FUNKCJI
  857.  
  858. //--DLA-KAZDEGO-ROZWIAZANIA-WYLICZANA-JEST-WARTOSC-FUNKCJI-CELU-(IM-WIEKSZA-WARTOSC-TYM-LEPSZE-USZEREGOWANIE)
  859.     while(solution) {
  860.         Task *machine1_task = solution->machine_1_sequence;                         //---WSKAZNIK-NA-ZADANIE-DLA-DANEGO-ROZWIAZANIA-DLA-MASZYNY-1
  861.         Task *machine2_task = solution->machine_2_sequence;                         //---WSKAZNIK-NA-ZADANIE-DLA-DANEGO-ROZWIAZANIA-DLA-MASZYNY-2
  862.         int fitnessValue = 0;                               //---WARTOSC-FUNKCJI-CELU
  863.  
  864. //------SUMOWANIE-CZASOW-ZAKONCZENIA-OPERACJI-DLA-MASZYNY-1
  865.         while(machine1_task) {
  866.             fitnessValue += machine1_task->start_time + machine1_task->time_length;
  867.             machine1_task = machine1_task->next;
  868.         }
  869.  
  870. //------SUMOWANIE-CZASOW-ZAKONCZENIA-OPERACJI-DLA-MASZYNY-2
  871.         while(machine2_task) {
  872.             fitnessValue += machine2_task->start_time + machine2_task->time_length;
  873.             machine2_task = machine2_task->next;
  874.         }
  875.  
  876. //------SPRAWDZANIE-CZY-AKTUALNA-WARTOSC-FUNKCJI-CELU-JEST-NAJWIEKSZA
  877.         if(fitnessValue > maxFitnessValue) {
  878.             maxFitnessValue = fitnessValue + 1;
  879.         }
  880.  
  881.         solution->fitness_value = fitnessValue;     //---ZAPISANIE-WARTOSCI-FUNKCJI-CELU-(TU-JESZCZE-WIEKSZA-WARTOSC-JEST-GORSZYM-USZEREGOWANIEM)
  882.         solution = solution->next;
  883.     }
  884.     solution = population->solution;
  885.  
  886. //--ZAMIANA-WARTOSCI-FUNKCJI-CELU-(IM-WIEKSZA-TERAZ-JEST-LEPSZYM-USZEREGOWANIEM)
  887.     while(solution) {
  888.         solution->fitness_value = maxFitnessValue - solution->fitness_value;
  889.         solution = solution->next;
  890.     }
  891. }
  892.  
  893.  
  894. /**
  895.     Funkcja odpowiedzialna za przeprowadzenie selekcji metodą turniejową.
  896.  
  897.     @param population wskaźnik na populację dla której ma zostać przeprowadzona selekcje turniejowa.
  898.     @param new_population wskaźnik na nową populację do której będą dodawane wybrane rozwiązania.
  899.     @param new_population_size rozmiar nowej powstałej populacji.
  900. */
  901. void tournament_selection(Population *population, Population *new_population, int new_population_size) {
  902.     Solution *solution1;
  903.     Solution *solution2;
  904.     int population_size = population->population_size();
  905.     int solution1_number;
  906.     int solution2_number;
  907.  
  908.     int popArray[population_size];
  909.     for(int i = 0 ; i < population_size ; i++) {
  910.         popArray[i] = 0;
  911.     }
  912.  
  913.     for(int i = 0 ; i < new_population_size ; i++) {
  914.  
  915.         solution1 = population->solution;
  916.         solution2 = population->solution;
  917.  
  918.         while(true) {
  919.             solution1_number = rand() % (population_size - 1);
  920.             if(popArray[solution1_number] == 0) {
  921.                 popArray[solution1_number] = 1;
  922.                 break;
  923.             }
  924.         }
  925.  
  926.         while(true) {
  927.             solution2_number = rand() % (population_size - 1);
  928.             if(popArray[solution2_number] == 0) {
  929.                 popArray[solution2_number] = 1;
  930.                 break;
  931.             }
  932.         }
  933.  
  934.         for(int i = 0 ; i < solution1_number ; i++) solution1 = solution1->next;
  935.         for(int i = 0 ; i < solution2_number ; i++) solution2 = solution2->next;
  936.  
  937.         if(solution1->fitness_value > solution2->fitness_value) {
  938.             popArray[solution2_number] = 0;
  939.             new_population->add_solution(solution1);
  940.         } else {
  941.             popArray[solution1_number] = 0;
  942.             new_population->add_solution(solution2);
  943.         }
  944.     }
  945. }
  946.  
  947.  
  948. /**
  949.     Operator algorytmu genetycznego - selekcja.
  950.  
  951.     @param population wskaźnik na populację dla której ma zostać przeprowadzona selekcja.
  952.     @param new_population wskaźnik na nową populację do której zostaną dodane wybrane rozwiązania.
  953.     @param new_population_size rozmiar nowej populacji.
  954. */
  955. void selection(Population *population, Population* new_population, int new_population_size) {
  956.  
  957.     calculate_fitness(population);
  958.     tournament_selection(population, new_population, new_population_size);
  959. }
  960.  
  961.  
  962. /**
  963.     Funkcja generująca startową populację.
  964.  
  965.     @param numberOfTasks liczba zadań w danej instancji.
  966.     @param sizeOfPopulation rozmiar populacji startowej
  967.     @param population wskaźnik na populację do której będą dodawane wygenerowane rozwiązania.
  968.  
  969.     @return liczbę zadań, dla danej instancji.
  970. */
  971. int generate_population(int numberOfTasks, int sizeOfPopulation, Population *population) {
  972.     for(int i = 0 ; i < sizeOfPopulation ; i++) {
  973.  
  974.         population->solution->add(population->solution);            //---DODANIE-NOWEGO-ROZWIAZANIA-DO-LISTY-ROZWIAZAŃ
  975.         Solution *solution = population->solution;
  976.         for(int j = 0 ; j < i; j++) solution = solution->next;      //---PRZESUNIECIE-WSKAZNNIKA-DO-AKTUALNIE-GENEROWANEGO-ROZWIAZANIA
  977.  
  978.         int taskOrder[numberOfTasks], usedTasks[numberOfTasks];
  979.         for(int j = 0 ; j < numberOfTasks ; j++) usedTasks[j] = 0;
  980.  
  981. //------GENEROWANIE-KOLEJNOŚCI-ZADAŃ-NA-PIERWSZEJ-MASZYNIE
  982.         for(int j = 0 ; j < numberOfTasks ; j++) {
  983.             while(true){
  984.                 int taskNumber =(int) (rand()% numberOfTasks);
  985.                 if(usedTasks[taskNumber] == 0) {
  986.                     usedTasks[taskNumber] = 1;
  987.                     taskOrder[j] = taskNumber;
  988.                     break;
  989.                 }
  990.             }
  991.         }
  992.  
  993. //------DODAWANIE-TASKÓW-DO-AKTUALNIE-GENEROWANEGO-ROZWIAZANIA
  994.         for(int j = 0 ; j < numberOfTasks ; j++) {
  995.  
  996.  
  997.  
  998. /*__________GENEROWANIE-USZEREGOWANIA-DLA-MASZYNY-1*/
  999.             int taskNumber = taskOrder[j];                  //---RZECZYWISTY-NUMER-ZADANIA-KTORE-MA-ZOSTAC-DODANE-DO-ROZWIAZANIA
  1000.             int task_start_timeM1 = 0;                      //---MOMENT-CZASU-W-KTORYM-AKTUALNIE-DODAWANE-ZADANIE-MOZE-ROZPOCZAC-WYKONYWANIE
  1001.             Task *machine1Task, *sequenceM1;
  1002.  
  1003.             machine1Task = machine1_operations;             //---WSKAŹNIK-NA-ZADANIE-Z-LISTY-ZADAŃ-WCZYTANYCH-Z-PLIKU
  1004.             sequenceM1 = solution->machine_1_sequence;      //---WSKAŹNIK-POMOCNICZY-NA-AKTUALNIE-GENEROWANE-ROZWIAZANIE-DLA-MASZYNY-PIERWSZEJ
  1005.  
  1006. //----------PRZESUNIECIE-WSKAZNIKA-NA-POZYCJE-KTOREMU-ODPOWIADA-WCZESNIEJ-WYGENEROWANY-NUMER-ZADANIA
  1007.             for(int k = 0; k < taskNumber ; k++) {
  1008.                 machine1Task = machine1Task->next;
  1009.             }
  1010.  
  1011. //----------ZNALEZIENIE-NAJBLIZSZEGO-MOZLIWEGO-CZASU-KIEDY-ZADANIE-MOZE-ROZPOCZAC-WYKONYWANIE
  1012.             while(sequenceM1) {
  1013.                 task_start_timeM1 = sequenceM1->start_time + sequenceM1->time_length;
  1014.                 sequenceM1 = sequenceM1->next;
  1015.             }
  1016.  
  1017.             Task *pauseM1;                                  //---WSKAZNIK-NA-LISTE-PRZERW-DLA-MASZYNY-1
  1018.             bool checkAgain = true;
  1019.  
  1020. //----------ZNAJDOWANIE-NOWEGO-MOZLIWEGO-CZASU-ROZPOCZECIA-WYKONYWANIA-ZADANIA-W-ZALEZNOSCI-OD-PRZERW
  1021.             while(checkAgain){
  1022.                 pauseM1 = machine1_pauses;
  1023.                 while(pauseM1) {
  1024.                     for(int k = task_start_timeM1 ; k <= task_start_timeM1 + machine1Task->time_length ; k++) {
  1025.                         if(k > pauseM1->start_time && k < pauseM1->start_time + pauseM1->time_length) {
  1026.                             task_start_timeM1 = pauseM1->start_time + pauseM1->time_length;
  1027.                             checkAgain = true;
  1028.                             break;
  1029.                         }
  1030.                     }
  1031.                     checkAgain = false;
  1032.                     pauseM1 = pauseM1->next;
  1033.                 }
  1034.             }
  1035.             solution->machine_1_sequence->add(task_start_timeM1, machine1Task->time_length, machine1Task->real_number, false, solution->machine_1_sequence);
  1036.  
  1037.  
  1038.  
  1039. /*__________GENEROWANIE-USZEREGOWANIA-DLA-MASZYNY-2*/
  1040.             Task *machine2Task, *sequenceM2;
  1041.             int task_start_timeM2 = 0;                      //---MOMENT-CZASU-W-KTORYM-AKTUALNIE-DODAWANE-ZADANIE-MOZE-ROZPOCZAC-WYKONYWANIE
  1042.  
  1043.             machine2Task = machine2_operations;             //---WSKAZNIK-NA-ZADANIE-Z-LISTY-ZADAN-WCZYTANYCH-Z-PLIKU
  1044.             sequenceM2 = solution->machine_2_sequence;      //---WSKAZNIK-POMOCNICZY-NA-AKTUALNIE-GENEROWANE-ROZWIAZANIE-DLA-MASZYNY-DRUGIEJ
  1045.  
  1046. //---------PRZESUNIECIE-WSKAZNIKA-NA-POZYCJE-KTOREMU-ODPOWIADA-WCZESNIEJ-WYGENEROWANY-NUMER-ZADANIA
  1047.             for(int k = 0 ; k < taskNumber ; k++) {
  1048.                 machine2Task = machine2Task->next;
  1049.             }
  1050.  
  1051. //---------ZNALEZIENIE-NAJBLIZSZEGO-MOZLIWEGO-CZASU-KIEDY-ZADANIE-MOZE-ROZPOCZAC-WYKONYWANIE
  1052.             while(sequenceM2) {
  1053.                 task_start_timeM2 = sequenceM2->start_time + sequenceM2->time_length;
  1054.                 sequenceM2 = sequenceM2->next;
  1055.             }
  1056.  
  1057. //----------SPRAWDZENIE-CZY-ZADANIE-NA-MASZYNIE-2-NIE-ZACZYNA-SIE-SZYBCIEJ-NIZ-KONCZY-SIE-ZADANIE-NA-MASZYNIE-1
  1058.             if(task_start_timeM2 <= task_start_timeM1 + machine1Task->time_length) {
  1059.                 task_start_timeM2 = task_start_timeM1 + machine1Task->time_length;
  1060.             }
  1061.  
  1062.             Task *pauseM2;                      //---WSKAZNIK-NA-LISTE-PRZERW-DLA-MASZYNY-2
  1063.             checkAgain = true;
  1064.  
  1065. //----------ZNAJDOWANIE-NOWEGO-MOZLIWEGO-CZASU-ROZPOCZECIA-WYKONYWANIA-ZADANIA-W-ZALEZNOSCI-OD-PRZERW
  1066.             while(checkAgain){
  1067.                 pauseM2 = machine2_pauses;
  1068.                 while(pauseM2) {
  1069.                     for(int k = task_start_timeM2 ; k <= task_start_timeM2 + machine2Task->time_length ; k++) {
  1070.                         if(k > pauseM2->start_time && k < pauseM2->start_time + pauseM2->time_length) {
  1071.                             task_start_timeM2 = pauseM2->start_time + pauseM2->time_length;
  1072.                             checkAgain = true;
  1073.                             break;
  1074.                         }
  1075.                     }
  1076.                     checkAgain = false;
  1077.                     pauseM2 = pauseM2->next;
  1078.                 }
  1079.             }
  1080.  
  1081.             solution->machine_2_sequence->add(task_start_timeM2, machine2Task->time_length, machine2Task->real_number, false, solution->machine_2_sequence);
  1082.         }
  1083.     }
  1084.     return numberOfTasks;
  1085. }
  1086.  
  1087.  
  1088. /**
  1089.     Funkcja wczytująca instantcje problem z pliku tekstowego.
  1090.     A następnie dodająca je do globalnej listy zadań.
  1091.    
  1092.     @param fileName nazwa pliku, z którego mają zostać wczytane dane.
  1093.    
  1094.     @return liczba zadań dla danej instancji.
  1095. */
  1096. int load_instance(char fileName[20]) {
  1097.     char buf[100];                  //---ZMIENNA-POMOCNICZA-PRZECHOWUJACA-DANE-NA-TEMAT-ZADAN-I-PRZERW
  1098.     int numberOfTasks;              //---ILOSC-ZDAN-KTORE-WYSTEPUJA-W-DANEJ-INSTANCJI-PROBLEMU
  1099.     fstream plik;
  1100.  
  1101.     plik.open(fileName, ios::in);
  1102.  
  1103.     if(plik.good()) {
  1104.         plik.getline(buf, 6);
  1105.         numberOfTasks = atoi(buf);  //---WCZYTANIE-ILOSCI-ZADAN-(PIERWSZY-WIERSZ-PLIKU)
  1106.  
  1107. //------WCZYTANIE-I-DODANIE-WSZYSTKICH-ZADAN-DO-LISTY-ZADAN
  1108.         for(int i = 0 ; i < numberOfTasks ; i++) {
  1109.             int machine1_task, machine2_task;
  1110.  
  1111.             plik.getline(buf, 10, ';');
  1112.             machine1_task = atoi(buf);
  1113.             plik.getline(buf, 10);
  1114.             machine2_task = atoi(buf);
  1115.  
  1116.             machine1_operations->add(0, machine1_task, i, false, machine1_operations);
  1117.             machine2_operations->add(0, machine2_task, i, false, machine2_operations);
  1118.         }
  1119.  
  1120. //------WCZYTANIE-I-DODANIE-PRZERW-DO-LISTY-PRZERW
  1121.         while(!plik.eof()) {
  1122.             int pauseNumber, machineNumber, timeForPause, whenPauseStart;
  1123.  
  1124.             plik.getline(buf, 10, ';');
  1125.             pauseNumber = atoi(buf);
  1126.             plik.getline(buf, 10, ';');
  1127.             machineNumber = atoi(buf);
  1128.             plik.getline(buf, 10, ';');
  1129.             timeForPause = atoi(buf);
  1130.             plik.getline(buf, 10);
  1131.             whenPauseStart = atoi(buf);
  1132.  
  1133.             if(timeForPause == 0 && machineNumber == 0 && whenPauseStart == 0) break;
  1134.  
  1135.             if(machineNumber == 0) machine1_pauses->add(whenPauseStart, timeForPause, pauseNumber, true, machine1_pauses);
  1136.             if(machineNumber == 1) machine2_pauses->add(whenPauseStart, timeForPause, pauseNumber, true, machine2_pauses);
  1137.         }
  1138.  
  1139.     } else cout << "Ups...Something went wrong.";
  1140.  
  1141.     plik.close();
  1142.  
  1143.     return numberOfTasks;
  1144. }
  1145.  
  1146.  
  1147. /**
  1148.     Funkcja zapisująca najlepszy wynik powstały z przeprowadzenia algorytmu
  1149.     genetycznego do pliku tekstowego.
  1150.    
  1151.     @param population wskaźnik na populację, z której zostanie wybrane najlepsze rozwiązanie.
  1152.     @param fileName nazwa pliku do jakiej zostanie zapisane rozwiązanie.
  1153. */
  1154. void save_results(Population *population, char fileName[20]) {
  1155.     char new_fileName[30] ="solution/";
  1156.     strncat(new_fileName, fileName, 20);
  1157.     calculate_fitness(population);
  1158.  
  1159.     Solution *best_solution = population->solution;
  1160.     Solution *solution = population->solution;
  1161.  
  1162.     while(solution) {
  1163.         if(solution->fitness_value > best_solution->fitness_value) {
  1164.             best_solution = solution;
  1165.         }
  1166.         solution = solution->next;
  1167.     }
  1168.  
  1169.     Task *machine1_seq = best_solution->machine_1_sequence;
  1170.     Task *machine2_seq = best_solution->machine_2_sequence;
  1171.     int fitness_value = 0;
  1172.     int maximum_time;
  1173.  
  1174.     while(machine1_seq) {
  1175.         fitness_value += machine1_seq->start_time + machine1_seq->time_length;
  1176.         machine1_seq = machine1_seq->next;
  1177.     }
  1178.  
  1179.     while(machine2_seq) {
  1180.         fitness_value += machine2_seq->start_time + machine2_seq->time_length;
  1181.         maximum_time = machine2_seq->start_time + machine2_seq->time_length;
  1182.         machine2_seq = machine2_seq->next;
  1183.     }
  1184.  
  1185.     machine1_seq = best_solution->machine_1_sequence;
  1186.     machine2_seq = best_solution->machine_2_sequence;
  1187.  
  1188.     int a = 0, b = 0;
  1189.     while(machine1_seq) {
  1190.         cout << a++ << "   " << machine1_seq->start_time << " : " << machine1_seq->start_time + machine1_seq->time_length << endl;
  1191.         machine1_seq = machine1_seq->next;
  1192.     }
  1193.  
  1194.     while(machine2_seq) {
  1195.                 cout << b++ << "   " << machine2_seq->start_time << " : " << machine2_seq->start_time + machine2_seq->time_length << endl;
  1196.         machine2_seq = machine2_seq->next;
  1197.     }
  1198.     getch();
  1199.     machine1_seq = best_solution->machine_1_sequence;
  1200.     machine2_seq = best_solution->machine_2_sequence;
  1201.  
  1202.     fstream plik;
  1203.     plik.open(new_fileName, ios::out);
  1204.  
  1205.     plik << maximum_time << ";" << fitness_value << endl;
  1206.  
  1207. //-----------WPISYWANIE-USZEREGOWANIA-NA-MASZYNIE-1
  1208.     int actuallTimeMoment = 0;
  1209.     int pause_number_M1 = 1;
  1210.     int idle_pause_number_M1 = 1;
  1211.     int sum_pause_M1 = 0;
  1212.     int sum_idle_pause_M1 = 0;
  1213.  
  1214.     plik << "M1:";
  1215.     while(machine1_seq) {
  1216.         bool idle = true;
  1217.  
  1218.         if(machine1_seq->start_time == actuallTimeMoment) {
  1219.             plik << "o1_z" << machine1_seq->real_number << "," << machine1_seq->start_time << "," << machine1_seq->time_length << ";";
  1220.             actuallTimeMoment = machine1_seq->start_time + machine1_seq->time_length;
  1221.             machine1_seq = machine1_seq->next;
  1222.             idle = false;
  1223.         }
  1224.  
  1225.         Task *machine1_p = machine1_pauses;
  1226.         while(machine1_p) {
  1227.             if(machine1_p->start_time == actuallTimeMoment) {
  1228.                 plik << "maint" << pause_number_M1 << "_M1," << machine1_p->start_time << "," << machine1_p->time_length << ";";
  1229.                 pause_number_M1++;
  1230.                 sum_pause_M1 += machine1_p->time_length;
  1231.                 actuallTimeMoment = machine1_p->start_time + machine1_p->time_length;
  1232.                 idle = false;
  1233.             }
  1234.             machine1_p = machine1_p->next;
  1235.         }
  1236.         if(idle) {
  1237.             machine1_p = machine1_pauses;
  1238.             int closest_Pause = MAXINTATOM;
  1239.             int closest_Task = MAXINTATOM;
  1240.  
  1241.             Task *temp_machine1_seq = best_solution->machine_1_sequence;
  1242.             while(temp_machine1_seq) {
  1243.                 if(temp_machine1_seq->start_time >= actuallTimeMoment) {
  1244.                     closest_Task = temp_machine1_seq->start_time;
  1245.                     break;
  1246.                 }
  1247.                 temp_machine1_seq = temp_machine1_seq->next;
  1248.             }
  1249.  
  1250.             while(machine1_p) {
  1251.                 if(machine1_p->start_time < closest_Pause && machine1_p->start_time >= actuallTimeMoment) closest_Pause = machine1_p->start_time;
  1252.                 machine1_p = machine1_p->next;
  1253.             }
  1254.  
  1255.             if(closest_Task < closest_Pause) {
  1256.                 plik << "idle" << idle_pause_number_M1 << "_M1," << actuallTimeMoment << "," << closest_Task - actuallTimeMoment << ";";
  1257.                 idle_pause_number_M1++;
  1258.                 sum_idle_pause_M1 += closest_Task - actuallTimeMoment;
  1259.                 actuallTimeMoment = closest_Task;
  1260.             } else {
  1261.                 plik << "idle" << idle_pause_number_M1 << "_M1," << actuallTimeMoment << "," << closest_Pause - actuallTimeMoment << ";";
  1262.                 idle_pause_number_M1++;
  1263.                 sum_idle_pause_M1 += closest_Pause - actuallTimeMoment;
  1264.                 actuallTimeMoment = closest_Pause;
  1265.             }
  1266.         }
  1267.     }
  1268.     plik << endl;
  1269.  
  1270.  
  1271. //-----------WPISYWANIE-USZEREGOWANIA-NA-MASZYNIE-2
  1272.     actuallTimeMoment = 0;
  1273.     int pause_number_M2 = 1;
  1274.     int idle_pause_number_M2 = 1;
  1275.     int sum_pause_M2 = 0;
  1276.     int sum_idle_pause_M2 = 0;
  1277.  
  1278.     plik << "M2:";
  1279.     while(machine2_seq) {
  1280.         bool idle = true;
  1281.  
  1282.         if(machine2_seq->start_time == actuallTimeMoment) {
  1283.             plik << "o2_z" << machine2_seq->real_number << "," << machine2_seq->start_time << "," << machine2_seq->time_length << ";";
  1284.             actuallTimeMoment = machine2_seq->start_time + machine2_seq->time_length;
  1285.             machine2_seq = machine2_seq->next;
  1286.             idle = false;
  1287.         }
  1288.  
  1289.         Task *machine2_p = machine2_pauses;
  1290.  
  1291.         while(machine2_p) {
  1292.             if(machine2_p->start_time == actuallTimeMoment) {
  1293.                 plik << "maint" << pause_number_M2 << "_M2," << machine2_p->start_time << "," << machine2_p->time_length << ";";
  1294.                 pause_number_M2++;
  1295.                 sum_pause_M2 += machine2_p->time_length;
  1296.                 actuallTimeMoment = machine2_p->start_time + machine2_p->time_length;
  1297.                 idle = false;
  1298.             }
  1299.             machine2_p = machine2_p->next;
  1300.         }
  1301.         if(idle) {
  1302.             machine2_p = machine2_pauses;
  1303.             int closest_Pause = MAXINTATOM;
  1304.             int closest_Task = MAXINTATOM;
  1305.  
  1306.             Task *temp_machine2_seq = best_solution->machine_2_sequence;
  1307.             while(temp_machine2_seq) {
  1308.                 if(temp_machine2_seq->start_time >= actuallTimeMoment) {
  1309.                     closest_Task = temp_machine2_seq->start_time;
  1310.                     break;
  1311.                 }
  1312.                 temp_machine2_seq = temp_machine2_seq->next;
  1313.             }
  1314.  
  1315.             while(machine2_p) {
  1316.                 if(machine2_p->start_time < closest_Pause && machine2_p->start_time >= actuallTimeMoment) closest_Pause = machine2_p->start_time;
  1317.                 machine2_p = machine2_p->next;
  1318.             }
  1319.  
  1320.             if(closest_Task < closest_Pause) {
  1321.                 plik << "idle" << idle_pause_number_M2 << "_M2," << actuallTimeMoment << "," << closest_Task - actuallTimeMoment << ";";
  1322.                 idle_pause_number_M2++;
  1323.                 sum_idle_pause_M2 += closest_Task - actuallTimeMoment;
  1324.                 actuallTimeMoment = closest_Task;
  1325.             } else {
  1326.                 plik << "idle" << idle_pause_number_M2 << "_M2," << actuallTimeMoment << "," << closest_Pause - actuallTimeMoment << ";";
  1327.                 idle_pause_number_M2++;
  1328.                 sum_idle_pause_M2 += closest_Task - actuallTimeMoment;
  1329.                 actuallTimeMoment = closest_Pause;
  1330.             }
  1331.         }
  1332.     }
  1333.     plik << endl;
  1334.     plik << pause_number_M1 << "," << sum_pause_M1 << endl;
  1335.     plik << pause_number_M2 << "," << sum_pause_M2 << endl;
  1336.     plik << idle_pause_number_M1 << "," << sum_idle_pause_M1 << endl;
  1337.     plik << idle_pause_number_M2 << "," << sum_idle_pause_M2;
  1338.     plik.close();
  1339. }
  1340.  
  1341.  
  1342. /**
  1343.     Funkcja zwracająca dany moment czasu.
  1344.    
  1345.     @return dany moment czasu.
  1346. */
  1347. double getTime() {
  1348.   long long f, t;
  1349.   QueryPerformanceFrequency( (PLARGE_INTEGER) & f );
  1350.   QueryPerformanceCounter( (PLARGE_INTEGER) & t);
  1351.   return (double)t / (double)f;
  1352. }
  1353.  
  1354.  
  1355. /**
  1356.     Główna funkcja programu.
  1357.     @author Patryk Gliszczyński
  1358.     @author Krzysztof Prajs
  1359. */
  1360. int main() {
  1361.  
  1362.     #define START_POPULATION_SIZE  200                   //---ROZMIAR-POPULACJI-STARTOWEJ
  1363.     #define MAIN_POPULATION_SIZE  100                    //---ROZMIAR-POPULACJI-DO-KTOREGO-ROZMIARU-OPERATOR-SELEKCJI-BEDZIE-ZMNIEJSZAC
  1364.     #define CROSSOVER_PROPABILITY 70                    //---PRAWDOPODOBIENSTWO-WYSTAPIENIA-KRZYZOWANIA
  1365.     #define MUTATION_PROPABILITY 50                     //---PRAWDOPODOBIENSTWO-WYSTAPIENIA-MUTACJI
  1366.  
  1367.     srand(time(NULL));
  1368.     char fileName[30] = "100RANDOM.txt";
  1369.  
  1370.  
  1371.     Population *population = new Population;            //---WSKAZNIK-NA-POPULACJE-STARTOWA
  1372.  
  1373.  
  1374.     int numberOfTasks = generate_population(load_instance(fileName), START_POPULATION_SIZE, population);            //---GENEROWANIE-STARTOWEJ-POPULACJI
  1375.     double startTime = getTime();
  1376.     double currentTime;
  1377.     int generationNumber = 0;
  1378. //------PRZEZ-OKRESLONY-CZAS-WYKONYWANE-SA-OPERACJE-MUTACJI-KRZYZOWANIA-I-SELEKCJI
  1379.     do {
  1380.         Population *new_population = new Population;                            //---UTWORZENIE-NOWEGO-MIEJSCA-W-PAMIECI-DLA-NOWEJ-POPULACJI
  1381.         selection(population, new_population, MAIN_POPULATION_SIZE);            //---SELEKCJA-STAREJ-POPULACJI-W-NOWA-POPULACJE
  1382.         delete population;
  1383.         population = new Population;
  1384.  
  1385. //----------WYKONWANIE-OPERACJI-MUTACJI-I-KRZYZOWANIA-DLA-KAZDEGO-ZADANIA
  1386.         Solution *solution = new_population->solution;
  1387.  
  1388.         while(solution) {
  1389.  
  1390.             int crossoverPropability = (rand() % 100) + 1;
  1391.             if(crossoverPropability <= CROSSOVER_PROPABILITY) crossover(solution, new_population, numberOfTasks, population);
  1392.  
  1393.             int mutationPropability = (rand() % 100) + 1;
  1394.             if(mutationPropability <= MUTATION_PROPABILITY) mutate(solution, numberOfTasks, population);
  1395.  
  1396.             solution = solution->next;
  1397.         }
  1398.         cout << "generation: " << generationNumber++ << endl;
  1399.         delete new_population;
  1400.  
  1401.         currentTime = getTime();
  1402.     } while(currentTime - startTime < 300);
  1403.  
  1404.     save_results(population, fileName);         //---ZAPISANIE-WYNIKU-PRZEPROWADZENIA-ALGORYTMU-DO-PLIKU-TEKSTOWEGO
  1405.  
  1406.     return 0;
  1407. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement