GA解决TSP问题

来源:互联网 发布:拳击 知乎 编辑:程序博客网 时间:2024/05/23 01:18

以下是GA(遗传算法)解决TSP(旅行商问题)源码:

#include <iostream>#include <vector>#include <ctime>#include <algorithm>#include <cmath>using namespace std;#define INF 1000typedef struct individual{    vector<int> chrom;    double fit;    double percentage;    int pathL;};bool compare(individual a, individual b){ return a.percentage > b.percentage; }class SGA{public:    SGA();    SGA(int psize, int gen, int maxgen, double c, double m) :popsize(psize), Genlen(gen), maxgener(maxgen), pc(c), pm(m){}    ~SGA();    void Initial(int** a);    void Select(int** a);    void Variation();    void mutation();    void evolution(int** a);    void print();    void updateData(int** a);private:    vector<individual > matingpool;    int popsize;//种群大小    int Genlen;//基因长度,也即城市个数    int maxgener;//迭代代数    double pc;    double pm;    bool IsNotExit(individual vc, int start, int end, int value);    vector<int> BuildRandomSequence(int len);};SGA::SGA(){}bool SGA::IsNotExit(individual vc, int start, int len, int value){    for (size_t t = start; t != start + len; t++) if (vc.chrom[t] == value) return false;    return true;}//随机产生序列,也即随机产生个体vector<int> SGA::BuildRandomSequence(int length){    vector<int> vc;    int i;    for (i = 0; i < length; i++)  vc.push_back(i);    int x = 0, tmp = 0;    for (i = length - 1; i > 0; i--) {        //x = random.Next(0, i + 1);        x = rand() % (i + 1);        tmp = vc[i];        vc[i] = vc[x];        vc[x] = tmp;    }    return vc;}//更新每个个体的fitnessvoid SGA::updateData(int** a){    double ftotal = 0;    int path = 0;    for (size_t t = 0; t < matingpool.size(); t++)    {        for (size_t x = 1; x < Genlen; x++)             path += *((int*)a + Genlen*matingpool[t].chrom[x - 1] + matingpool[t].chrom[x]);        path += *((int*)a + Genlen*matingpool[t].chrom[0] + matingpool[t].chrom[Genlen-1]);        matingpool[t].pathL = path;        matingpool[t].fit = 1.0 / path;        path = 0;        ftotal += matingpool[t].fit;    }    for (size_t tt = 0; tt < matingpool.size(); tt++)    {        matingpool[tt].percentage = matingpool[tt].fit / ftotal;    }}//初始化种群void SGA::Initial(int** a){    int i, j=1;    individual ida;    int path = 0;    for (j = 0; j < popsize; j++)    {        ida.chrom = BuildRandomSequence(Genlen);        matingpool.push_back(ida);    }    updateData(a);}void SGA::Select(int** a){    //选择个体加入 mating pool,可能重复    vector<individual> vcida;    updateData(a);    for (size_t i = 0; i < matingpool.size(); i++)    {        vcida.push_back(matingpool[i]);    }    matingpool.clear();    double rate;    double ff = 0.0;    srand((unsigned)time(NULL));    while (1)    {        rate = rand()*1.0 / RAND_MAX;        for (int i = 0; i < popsize; i++)        {            if (rate>ff && rate <= vcida[i].percentage + ff)            {                matingpool.push_back(vcida[i]);                break;            }            ff += vcida[i].percentage;        }        ff = 0.0;        if (matingpool.size() == popsize) break;    }    updateData(a);}void SGA::Variation(){    //Parent交叉产生Offspring,pc为交叉率,即参加交叉运算的染色体数占全部染色体总数的百分比    int pcd = popsize / 2 * pc;    vector<individual> crw;    sort(matingpool.begin(), matingpool.end(), compare);    int cnt = 0;    for (size_t i = popsize-1; cnt!=2*pcd; i--,cnt++)    {        crw.push_back(matingpool[i]);    }     int i,j;    srand((unsigned)time(NULL));    int start = rand() % (Genlen - 3);    int length = rand() % (Genlen - start);    individual a, b,o1,o2;    vector<int> ttp;    for (i = 0; i != 2 * pcd; i+=2)    {        a = crw[i];        b = crw[i+1];        o1 = a;        o2 = b;        ttp.clear();        for (j = 0; j != Genlen; j++)        {            if (IsNotExit(o1, start, length, b.chrom[j]))                ttp.push_back(b.chrom[j]);        }        for (j = 0; j < start; j++)        {            o1.chrom[j] = ttp[j];        }        for (j = start+length; j < Genlen; j++)        {            o1.chrom[j] = ttp[j - start - length ];        }        ttp.clear();        for (j = 0; j != Genlen; j++)        {            if (IsNotExit(o2, start, length, a.chrom[j]))                ttp.push_back(a.chrom[j]);        }        for (j = 0; j < start; j++)        {            o2.chrom[j] = ttp[j];        }        for (j = start + length ; j < Genlen; j++)        {            o2.chrom[j] = ttp[j - start - length ];        }        matingpool.push_back(o1);        matingpool.push_back(o2);    }    crw.clear();    ttp.clear();}//突变操作void SGA::mutation(){    int pcd = popsize * pm;    int i, pos1,pos2, tp,tt;    srand((unsigned)time(NULL));    for (i = 0; i < pcd; i++)    {        tp = rand() % matingpool.size();        pos1 = rand() % Genlen;        pos2 = rand() % Genlen;        tt = matingpool[tp].chrom[pos1];        matingpool[tp].chrom[pos1]= matingpool[tp].chrom[pos2];        matingpool[tp].chrom[pos2] = tt;    }}//进化操作void SGA::evolution(int** a){    int gen = 0;    while (gen != maxgener)    {        Variation();        mutation();        Select(a);        gen++;    }}void SGA::print(){    int i,k, P=10000;    for (i = 0; i < popsize; i++)    {        if (matingpool[i].pathL < P)        {            P = matingpool[i].pathL;            k = i;        }    }    cout << "最短距离: " << matingpool[k].pathL << endl;    cout << "最短路径: " ;    for (i = 0; i < Genlen; i++) cout << matingpool[k].chrom[i] << " ";    cout << matingpool[k].chrom[0];    cout << endl;}SGA::~SGA(){}
0 0
原创粉丝点击