Kaidul

Sami

Sep 8th, 2014
291
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.26 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define Max 100
  6.  
  7. #define Iteration 100
  8. #define Elitism true
  9. #define tournamentSize 5
  10. #define Generation 50
  11. #define mutationRate 0.015
  12. #define K 5
  13.  
  14. int N;
  15. vector <int> adj[Max];
  16. int dist[Max][Max];
  17. bool taken[Max * Max];
  18.  
  19. struct Individual {
  20.     int cost;
  21.     vector<int> chromosome;
  22.     Individual(): cost(0) {}
  23. };
  24.  
  25. void printIndividual(const Individual &);
  26.  
  27. void createIndividual(int curr, int& dest, Individual*& population, int pathLength, int& indx, vector<int>& chromosome, int cost) {
  28.     taken[curr] = true;
  29.     chromosome.push_back(curr);
  30.     if(curr == dest) {
  31.         population[indx].cost = cost;
  32.         population[indx].chromosome = chromosome;
  33. //        printIndividual(population[indx]);
  34.         ++indx;
  35.         return;
  36.     }
  37.     if(pathLength == N) return;
  38.  
  39.     int adjSize = (int)adj[curr].size();
  40.     bool block = true;
  41.     for(int i = 0; i < adjSize; ++i) {
  42.         if(!taken[adj[curr][i]]) {
  43.             block = false;
  44.             break;
  45.         }
  46.     }
  47.     if(block) return;
  48.     int idx, next;
  49.     // you buggy whore!! fuck u off now!
  50.     do {
  51.         idx = rand() % adjSize;
  52.         next = adj[curr][idx];
  53.     } while(taken[next]);
  54.     int pathCost = cost + dist[curr][next];
  55.     createIndividual(next, dest, population, pathLength + 1, indx, chromosome, pathCost);
  56.  
  57. }
  58.  
  59. double getFitness(int cost) {
  60.     return (1.0 / (double)cost);
  61. }
  62.  
  63. void printIndividual(const Individual& obj) {
  64.     int n = (int)obj.chromosome.size();
  65.     for(int i = 0; i < n - 1; ++i) {
  66.         printf("%d -> ", obj.chromosome[i]);
  67.     }
  68.     printf("%d ", obj.chromosome[n - 1]);
  69.     printf("(%d)\n", obj.cost);
  70. }
  71.  
  72. int getDistance(const Individual& indv) {
  73.     int cost = 0;
  74.     for(int i = 0, n = indv.chromosome.size(); i < n - 1; ++i) {
  75.         cost += dist[ indv.chromosome[i] ][ indv.chromosome[i + 1] ];
  76.     }
  77.     return cost;
  78. }
  79.  
  80. Individual getFittest(const Individual* Population, int Size) {
  81.     int fittest = 0;
  82.     double best = getFitness(Population[0].cost);
  83.     for(int i = 1; i < Size; ++i) {
  84.         double fitness = getFitness(Population[i].cost);
  85.         if(fitness > best) {
  86.             fittest = i;
  87.             best = fitness;
  88.         }
  89.     }
  90.     return Population[fittest];
  91. }
  92.  
  93. bool mutateUtil(Individual& indv, int u, int &dest, int pathLength) {
  94.     taken[u] = true;
  95.     indv.chromosome.push_back(u);
  96.     if(u == dest) return true;
  97.     if(pathLength == N) return false;
  98.  
  99.     int adjs = (int)adj[u].size();
  100.     bool block = true;
  101.     for(int i = 0; i < adjs; ++i) {
  102.         if(!taken[adj[u][i]]) {
  103.             block = false;
  104.             break;
  105.         }
  106.     }
  107.     if(block) return false;
  108.     int randomIdx, v;
  109.     do {
  110.         randomIdx = rand() % adjs;
  111.         v = adj[u][randomIdx];
  112.     } while(taken[v]);
  113.     indv.cost += dist[u][v];
  114.     return mutateUtil(indv, v, dest, pathLength + 1);
  115. }
  116.  
  117. void mutate(Individual& indv) {
  118.     double mutationProb = ((double) rand() / (RAND_MAX));
  119.     if(mutationProb < mutationRate) {
  120.         int n = (int)indv.chromosome.size();
  121.         int mutationPoint = rand() % n;
  122.         if(mutationPoint == n - 1) return;
  123.         memset(taken, false, sizeof taken);
  124.         int src = indv.chromosome[mutationPoint], dest = indv.chromosome[n - 1];
  125.         Individual newIndv;
  126.         int cost = 0;
  127.         for(int i = 0; i < mutationPoint; ++i) {
  128.             newIndv.chromosome.push_back(indv.chromosome[i]);
  129.             taken[indv.chromosome[i]] = true;
  130.             cost += dist[indv.chromosome[i]][indv.chromosome[i + 1]];
  131.         }
  132.         newIndv.cost = cost;
  133.         bool success = mutateUtil(newIndv, src, dest, mutationPoint + 1);
  134.         if(success) indv = newIndv;
  135.     }
  136. }
  137.  
  138. Individual crossover(const Individual& parent1, const Individual& parent2) {
  139.     Individual child;
  140.     int len1 = parent1.chromosome.size();
  141.     int len2 = parent2.chromosome.size();
  142.     vector< pair<int, int> > crossingSites;
  143.     for(int i = 1; i < len1 - 1; ++i) {
  144.         for(int j = 1; j < len2 - 1; ++j) {
  145.             if(parent1.chromosome[i] == parent2.chromosome[j])
  146.                 crossingSites.push_back( make_pair(i, j) );
  147.         }
  148.     }
  149.  
  150.     if(crossingSites.size() < 1) return parent1.cost >= parent2.cost ? parent1 : parent2;
  151.  
  152.     pair<int, int> randomCS = crossingSites[rand() % crossingSites.size()];
  153.  
  154.     for(int i = 0; i < randomCS.first; ++i)
  155.         child.chromosome.push_back(parent1.chromosome[i]);
  156.     for(int i = randomCS.second; i < len2; ++i)
  157.         child.chromosome.push_back(parent2.chromosome[i]);
  158.  
  159.     child.cost = getDistance(child);
  160.  
  161.     return child;
  162. }
  163.  
  164. Individual tournamentSelection(const Individual* pop) {
  165.     Individual tournament[tournamentSize];
  166.     for(int i = 0; i < tournamentSize; ++i) {
  167.         int randomID = rand() % Iteration;
  168.         tournament[i] = pop[randomID];
  169.     }
  170.     return getFittest(tournament, tournamentSize);
  171.  
  172. }
  173. //main ga process
  174. Individual* evolvePopulation(const Individual* Pop) {
  175.     int elitismOffset = 0;
  176.     // memory leak ?
  177.     Individual *evolvePop = new Individual[Iteration];
  178.  
  179.     if(Elitism) {
  180.         Individual best = getFittest(Pop, Iteration);
  181.         evolvePop[0] = best;
  182.         elitismOffset = 1;
  183.     }
  184.  
  185.     for(int i = elitismOffset; i < Iteration; ++i) {
  186.         Individual parent1 = tournamentSelection(Pop);
  187.         Individual parent2 = tournamentSelection(Pop);
  188.         Individual child = crossover(parent1, parent2);
  189.         evolvePop[i] = child;
  190.     }
  191.  
  192.     for(int i = elitismOffset; i < Iteration; ++i) {
  193.         mutate(evolvePop[i]);
  194.     }
  195.  
  196.     return evolvePop;
  197. }
  198.  
  199. void generatePopulation(int Size, int& source, int& destination, Individual* population) {
  200.     int indx = 0;
  201.     while(indx != Size) {
  202.         vector <int> chromosome;
  203.         memset(taken, false, sizeof taken);
  204.         createIndividual(source, destination, population, 1, indx, chromosome, 0);
  205.     }
  206. }
  207.  
  208. int compare(const void *vI1, const void *vI2) {
  209.     Individual *I1 = (Individual *)vI1;
  210.     Individual *I2 = (Individual *)vI2;
  211.  
  212.     return (*I1).cost > (*I2).cost;
  213. }
  214.  
  215. void k_bestSolution(Individual* pop) {
  216.     qsort(&pop[0], Iteration, sizeof(Individual), compare);
  217.     int k = min(Iteration, K);
  218.     printf("Total Population: %d\n", Iteration);
  219.     printf("%d most optimal solutions:\n", k);
  220.     for(int i = 0; i < k; ++i) {
  221.         printIndividual(pop[i]);
  222.     }
  223. }
  224.  
  225. void buildDifferentRoute(int idx, Individual *pop, int cutPoint) {
  226.     Individual indv = pop[idx];
  227.     int n = (int)indv.chromosome.size();
  228.     if(cutPoint == n - 1) {
  229.         printf("Invalid as its destination\n");
  230.         return;
  231.     }
  232.     if(cutPoint == 0) {
  233.         printf("Invalid as its source\n");
  234.         return;
  235.     }
  236.     memset(taken, false, sizeof taken);
  237.     int src = indv.chromosome[cutPoint - 1], dest = indv.chromosome[n - 1];
  238.     Individual newIndv;
  239.     int cost = 0;
  240.     for(int i = 0; i < cutPoint - 1; ++i) {
  241.         newIndv.chromosome.push_back(indv.chromosome[i]);
  242.         taken[indv.chromosome[i]] = true;
  243.         cost += dist[indv.chromosome[i]][indv.chromosome[i + 1]];
  244.     }
  245.     newIndv.cost = cost;
  246.     bool success = mutateUtil(newIndv, src, dest, cutPoint - 1);
  247.     if(success) {
  248.         printf("Well, There is another route available!\n");
  249.         printIndividual(newIndv);
  250.     } else {
  251.         printf("There is no other route available!\n");
  252.     }
  253.     // they didn't like you. cutie!
  254.     /*
  255.         bool found = false;
  256.         int id;
  257.         for(int j = 0; j < Iteration; ++j) {
  258.             if(j == idx) continue;
  259.             found = true;
  260.             for(int k = 0; k < cutPoint; ++k) {
  261.                 if(pop[idx].chromosome[k] != pop[j].chromosome[k]) {
  262.                     found = false;
  263.                     break;
  264.                 }
  265.                 id = j;
  266.             }
  267.             if(found and pop[idx].chromosome[cutPoint] != pop[j].chromosome[cutPoint])
  268.                 return id;
  269.         }
  270.         return -1;
  271.     */
  272. }
  273.  
  274. int main(void) {
  275.     freopen("input.txt", "r", stdin);
  276. //    freopen("output.txt", "w", stdout);
  277.     int u, v, cost, edge;
  278.     scanf("%d %d", &N, &edge); // N = vertices
  279.     for(int i = 0; i < edge; ++i) {
  280.         scanf("%d %d %d", &u, &v, &cost);
  281.  
  282.         // adjacency list representation
  283.         adj[u].push_back(v);
  284.         adj[v].push_back(u);
  285.  
  286.         // adjacency matrix
  287.         dist[u][v] = dist[v][u] = cost;
  288.     }
  289.     int source, destination;
  290.     int idx, trafficPoint;
  291.  
  292.     while(scanf("%d %d", &source, &destination) == 2) {
  293.         if(!source and !destination) break;
  294.  
  295.         Individual *population = new Individual[Iteration];
  296.         cout << "generating Population .....\n";
  297.         generatePopulation(Iteration, source, destination, population);
  298.         cout << "Population generation success!\n";
  299.  
  300.         Individual *newPopulation = evolvePopulation(population);
  301.  
  302.         delete [] population;
  303.  
  304.         for(int i = 0; i < Generation; ++i) {
  305.             newPopulation = evolvePopulation(newPopulation);
  306.         }
  307.  
  308.         k_bestSolution(newPopulation);
  309.  
  310.         while(scanf("%d %d", &idx, &trafficPoint) == 2) {
  311.             if(!idx and !trafficPoint) break;
  312.             buildDifferentRoute(idx, newPopulation, trafficPoint);
  313.         }
  314.         delete [] newPopulation;
  315.     }
  316.     return 0;
  317. }
Advertisement
Add Comment
Please, Sign In to add comment