zoukankan      html  css  js  c++  java
  • 遗传算法解决排序问题

    遗传算法最重要的几个步骤

     1.编码。

      一般可采用二进制编码。本题使用和tsp相同的符号编码(可使用一个数组保存)

     2.选择。根据个体的评分进行选择,涉及到累计概率。

     3.交叉。通过互换基因,从而产生新的个体。

     4.变异。产生新的个体。

      1 #include <stdio.h>
      2 #include <vector>
      3 #include <time.h>
      4 #include <stdlib.h>
      5 #include <algorithm>
      6 
      7 using namespace std;
      8 
      9 vector<vector<int>> population;
     10 vector<int> best_body;
     11 int min_pair = INT_MAX;//最小的逆序对
     12 
     13 int scale;//种群规模
     14 int arrNum;//基因个数
     15 
     16 int MAX_ROUND;//循环次数
     17 int mutation_times;
     18 
     19 float crossover_p;//交叉概率
     20 float mutation_p;//变异概率
     21 
     22 
     23 //初始化
     24 void init() {
     25     for (int i = 0; i < arrNum; ++i) {
     26         best_body.push_back(0);
     27     }
     28     srand(time(NULL));
     29     for (int i = 0; i < scale; ++i) {
     30         vector<int> temp;
     31         for (int j = 0; j < arrNum;) {
     32             int p = int(((double) rand() / RAND_MAX) * arrNum);
     33             if (find(temp.begin(), temp.end(), p) == temp.end()) {//不存在
     34                 temp.push_back(p);
     35                 ++j;
     36             }
     37         }
     38         population.push_back(temp);
     39     }
     40 
     41 }
     42 
     43 
     44 //逆序对
     45 int reverse_order_pair(vector<int> &vec) {
     46     int sz = vec.size();
     47     int sm = 0;
     48     for (int i = 0; i < sz; ++i) {
     49         for (int j = i + 1; j < sz; ++j) {
     50             if (vec[i] > vec[j]) {
     51                 ++sm;
     52             }
     53         }
     54     }
     55     return sm;
     56 }
     57 
     58 
     59 void copy(vector<int> &v1, vector<int> &v2) {
     60     for (int i = 0; i < arrNum; ++i) {
     61         v1[i] = v2[i];
     62     }
     63 }
     64 
     65 //计算评分 基于逆序对
     66 vector<int> score(vector<vector<int>> &vec) {
     67     vector<int> res;
     68     int temp = INT_MAX;
     69     int index = 0;
     70     for (int i = 0; i < scale; ++i) {
     71         int pairs = reverse_order_pair(vec[i]);
     72         if (pairs < temp) {
     73             temp = pairs;
     74             index = i;
     75         }
     76         res.push_back(pairs);
     77     }
     78 
     79     if (temp < min_pair) {
     80         min_pair = temp;
     81         copy(best_body, vec[index]);
     82     }
     83     return res;
     84 }
     85 
     86 //计算积累概率
     87 vector<double> cumulatePro(vector<int> &score) {
     88     vector<double> res(scale);
     89     double sm = 0;
     90     for (double p:score) {
     91         sm += 1 / (double) p;
     92     }
     93     res[0] = 1 / (double) score[0] / sm;
     94 
     95     for (int i = 1; i < scale; ++i) {
     96         res[i] = 1 / (double) score[i] / sm + res[i - 1];
     97     }
     98     return res;
     99 }
    100 
    101 //选择
    102 vector<vector<int>> choose(vector<double> &cumPro) {
    103     vector<vector<int>> res;
    104     for (int i = 0; i < scale; ++i) {
    105         res.push_back(vector<int>(arrNum));
    106     }
    107     for (int i = 0; i < scale - 1; ++i) {
    108         double temp = (double) rand() / RAND_MAX;
    109 
    110         if (cumPro[0] >= temp) {
    111             copy(res[i], population[0]);
    112         } else {
    113             for (int j = 1; j < scale; ++j) {
    114                 if (cumPro[j - 1] < temp && temp <= cumPro[j]) {
    115                     copy(res[i], population[j]);
    116                     break;
    117                 }
    118             }
    119         }
    120     }
    121     copy(res[scale - 1], best_body);
    122     return res;
    123 }
    124 
    125 
    126 //交叉
    127 //交替位置交叉法
    128 void crossover(vector<int> &v1, vector<int> &v2) {
    129     vector<int> t1;
    130     vector<int> t2;
    131     int i = 0, j = 0;
    132     while (i < v1.size() || j < v2.size()) {
    133         if (find(t1.begin(), t1.end(), v1[i]) == t1.end()) {
    134             t1.push_back(v1[i]);
    135             ++i;
    136         } else if (i < v1.size()) {
    137             t2.push_back(v1[i]);
    138             ++i;
    139         }
    140 
    141         if (find(t1.begin(), t1.end(), v2[j]) == t1.end()) {
    142             t1.push_back(v2[j]);
    143             ++j;
    144         } else if (j < v2.size()) {
    145             t2.push_back(v2[j]);
    146             ++j;
    147         }
    148     }
    149     copy(v1, t1);
    150     copy(v2, t2);
    151 }
    152 
    153 //变异
    154 void mutation(vector<int> &body) {
    155     srand(time(NULL));
    156     for (int i = 0; i < mutation_times; ++i) {
    157         int r1 = (int) ((double) rand() / RAND_MAX * arrNum);
    158         int r2 = (int) ((double) rand() / RAND_MAX * arrNum);
    159         while (r1 == r2) {
    160             r2 = (int) ((double) rand() / RAND_MAX * arrNum);
    161         }
    162         swap(body[r1], body[r2]);
    163     }
    164 }
    165 
    166 
    167 void crossAndMutation(vector<vector<int>> &newPop) {
    168     srand(time(NULL));
    169     for (int i = 0; i < scale - 1; i += 2) {
    170         float p1 = (float) rand() / RAND_MAX;
    171         if (p1 > crossover_p) {//交叉
    172             crossover(newPop[i], newPop[i + 1]);
    173         }
    174     }
    175     //变异
    176     for (int i = 0; i < scale; ++i) {
    177         float p1 = (float) rand() / RAND_MAX;
    178         if (p1 > mutation_p) {
    179             mutation(newPop[i]);
    180         }
    181     }
    182 }
    183 
    184 //修正 将上一代最优的替换新一代最差的
    185 void fixUp(vector<vector<int>> &newPop) {
    186     int index = 0;
    187     int pairs = 0;
    188     for (int i = 0; i < scale; ++i) {
    189         if (reverse_order_pair(newPop[i]) > pairs) {
    190             pairs = reverse_order_pair(newPop[i]);
    191             index = i;
    192         }
    193     }
    194     copy(newPop[index], best_body);
    195 }
    196 
    197 
    198 int main() {
    199     scale = 50;//种群规模
    200     arrNum = 7;//基因个数
    201     MAX_ROUND = 100;//循环次数
    202     mutation_times = 4;//变异次数
    203     crossover_p = 0.6;//交叉概率
    204     mutation_p = 0.4;//变异概率
    205     init();
    206     for (int i = 0; i < MAX_ROUND; ++i) {
    207         vector<int> scoreVec = score(population);//评分
    208         vector<double> pArr = cumulatePro(scoreVec);//积累概率
    209         vector<vector<int>> newPop = choose(pArr);//选择
    210         crossAndMutation(newPop);//交叉和变异
    211         fixUp(newPop);//修正
    212         population = newPop;
    213     }
    214     for (int temp:best_body) {
    215         printf("%d ", temp);
    216     }
    217     return 0;
    218 }

    最开始没有精英策略,算法很不稳定,加入精英策略之后,算法变得比较稳定。

    实例代码执行结果:

    0 1 2 3 4 5 6

  • 相关阅读:
    HDU 2196 Computer
    HDU 1520 Anniversary party
    POJ 1217 FOUR QUARTERS
    POJ 2184 Cow Exhibition
    HDU 2639 Bone Collector II
    POJ 3181 Dollar Dayz
    POJ 1787 Charlie's Change
    POJ 2063 Investment
    HDU 1114 Piggy-Bank
    Lca hdu 2874 Connections between cities
  • 原文地址:https://www.cnblogs.com/oldBook/p/9866734.html
Copyright © 2011-2022 走看看