Advertisement
Kaidul

Memory Leak Resolved

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