Genetic Algorithm Primary

Genetic algorithm is an algorithm which imitate the law of natural selection.

The main step:

Step 1:      Initialization     (Set Max evolutionary algebra and Create new individuals randomly)

Step 2:      Individual evaluation (Evaluate the fitness of each individuals using a fitness function)

Step 3:      Selection (Pick the proper individuals according to fitness)

Step 4:      Crossover (The most important part of GA)

Step 5:    Mutation (Accelerating convergence of the optimal solution)

Worth mentioning, in most function, GA has to be stochastic realization. For example, in selection part, the larger an individual’s fitness is, the greater the chance of an individual to survive instead of individuals which has a larger survival rate survive certainly.

To realize the randomness, there lots of methods we can choose. A good way is roulette wheel selection. We can first figure out the survival rate of an individual like this:

And then, we produce a random number and find out which part of it. Implement code:

    Genome GenAlg:: GetChromoRoulette()  

    {  

        //产生一个0到人口总适应性评分总和之间的随机数.  

        //中m_dTotalFitness记录了整个种群的适应性分数总和)  

        double Slice = (random()) * totalFitness;  

        //这个基因将承载转盘所选出来的那个个体.  

        Genome TheChosenOne;  

        //累计适应性分数的和.  

        double FitnessSoFar = 0;  

        //遍历总人口里面的每一条染色体。  

        for (int i=0; i<popSize; ++i)  

        {  

            //累计适应性分数.  

            FitnessSoFar += vecPop[i].fitness;  

            //如果累计分数大于随机数,就选择此时的基因.  

            if (FitnessSoFar >= Slice)  

            {  

                TheChosenOne = vecPop[i];  

                break;  

            }  

        }  

        //返回转盘选出来的个体基因  

        return TheChosenOne;  

    }  

This weekend, I just learn a little of the GA, understanding the process of this algorithm. And take TSP problem as an example, simulating the process of GA roughly. Due to the lack of the main optimization algorithm, my GA code seem to be useless. My first GA code only reflect the idea of random, but not the idea of optimization and convergence. But my understanding of GA is deepen through this problem.

Here is my code:

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<fstream>
#include<cmath>
#include<ctime>
using namespace std;
typedef long long LL;
/************************City Set************************/
string filename = "berlin52.txt";
#define runs 10
#define groupNum 10
#define cnt 52 //城市数量
const double pc = 0.65;//交配概率
const double mp = 0.35;//变异概率
/*********************************************************/
double edge[cnt][cnt];
double best_tsp = 1e7;
int trace[cnt];

struct City{
    double x, y;
}city[cnt];

struct Group{
    int cities[cnt];
    double tsp;
    double fit;
}group[groupNum], groupt[groupNum];

void init(){
    int num = 0;
    ifstream fin(filename);
    while(fin>>num){
        fin>>city[num-1].x>>city[num-1].y;
        //cout<<num-1<<" "<<city[num-1].x<<" "<<city[num-1].y<<endl;
    }
    //构造邻接矩阵
    for(int i =0 ; i< cnt ; ++i){
        edge[i][i] = 0;
        for(int j =i+1 ; j< cnt ; ++j){
            edge[j][i] = edge[i][j] = sqrt((city[i].x-city[j].x)*(city[i].x-city[j].x) + (city[i].y-city[j].y)*(city[i].y-city[j].y));
        }
    }
    /*cout<<"邻接矩阵为"<<endl;
    for(int i=0 ; i<cnt ; ++i){
        for(int j =0 ; j<cnt ; ++j){
            cout<<edge[i][j]<<" ";
        }
        cout<<endl;
    }*/
}

void print(){
    for(int i =0 ; i<groupNum ;++i){
        cout<<"Group"<<i<<":";
        for(int j= 0 ; j<cnt ; ++j)    cout<<" "<<group[i].cities[j];
        cout<<endl;
    }
}

void pre_value(){
    srand(time(0));
    /***********************给每个种群初始化**************************/
    for(int i = 0 ; i<groupNum ; ++i){
        int j = 0;
        for(int k = 0 ; k< cnt ; ++k){
            group[i].cities[k] = -1;
        }
        while( j<cnt ){
            int x = rand()%cnt ;
            if(group[i].cities[x] == -1){
                group[i].cities[x] = j;
                ++j;
            }
        }
    }
    /********************打印种群*****************************/
    cout<<"Initial Population:"<<endl;
    for(int i=0 ; i<groupNum ; ++i){
        cout<<"Group"<<i<<":";
        for(int j=0 ;j<cnt ; ++j){
            cout<<group[i].cities[j]<<" ";
        }
        cout<<endl;
    }
    //system("pause");
}

void fitness(){
    /*************************计算种群总路径*****************************/
    double sum_dis = 0;
    for(int i=0 ; i< groupNum ; ++i){
        group[i].tsp = 0;
        group[i].fit = 0;
    }
    for(int i =0 ; i<groupNum ; ++i){
        for(int j=0 ; j<cnt ; ++j){
            if(j == cnt -1){
                group[i].tsp += edge[group[i].cities[cnt-1]][group[i].cities[0]];
            }
            else group[i].tsp += edge[group[i].cities[j]][group[i].cities[j+1]];
        }
        sum_dis += group[i].tsp;
    }
    /*************************计算每个种群的存活几率***********************/
    double sum_fit = 0;
    for(int i=0 ; i<groupNum ; ++i){
        group[i].fit = 1 - group[i].tsp / sum_dis;
        sum_fit += group[i].fit;
    }
    for(int i=0 ; i<groupNum ;++i){
        group[i].fit = group[i].fit/sum_fit;
    }
    int best = 0;
    for(int i= 0; i<groupNum ; ++i){
        if( group[i].tsp < group[best].tsp ){
            best = i;
        }
    }
    /************************************************************************/
    /*cout<<"当前代最好的种群是种群"<<best<<‘:‘<<endl;
    for(int i=0; i<cnt ; ++i){
        cout<<group[best].cities[i]<<" ";
    }*/
    if( group[best].tsp < best_tsp){
        best_tsp = group[best].tsp;
        for(int i=0 ; i< cnt ; ++i){
            trace[i] = group[best].cities[i];
        }
    }
    //cout<<"TSP = "<<group[best].tsp<<endl;
    //system("pause");
}

void select(){
    int chosen[groupNum];
    /*********************轮盘法随机选择种群***************************/
    for(int i =0 ; i<groupNum ; ++i){
        double x = rand()%100;
        x /= 100;
        double fitSofar = 0;
        for(int j=0 ; j< groupNum ; ++j){
            fitSofar += group[j].fit;
            if(fitSofar > x ){
                chosen[i] = j;    break;
            }
        }
    }
    /*************************复制产生新一代种群*************************/
    for(int i=0 ; i<groupNum ; ++i){
        groupt[i] = group[i];
    }
    for(int i=0 ; i<groupNum ;++i){
        group[i] = groupt[ chosen[i] ];
    }
    /*********************************************************************/
    //cout<<"The new generation:"<<endl;
    //print();
    //system("pause");
}

void cross(){
    int t=0;
    int crossp[groupNum];
    memset(crossp, 0, sizeof(crossp));
    /*********************确定交配种群个数***********************/
    for(int i=0 ; i< groupNum ; ++i){
        double x = rand()%100;
        x /= 100;
        if( x<pc ){
            crossp[t++] = i;
        }
    }
    //t = t/2*2;  //保证t为偶数
    /************************开始交配**************************/
    for(int j=0 ; j+1<t ; j+=2){
        int temp1 = j, temp2 = j+1;
        int map1[cnt], map2[cnt];
        int point1, point2;
        point1 = rand()%cnt;    point2 = rand()%cnt;
        if(point2<point1)    swap(point1, point2);
        //两头直接交换
        for(int i=0 ; i<point1; ++i){
            swap(group[temp1].cities[i], group[temp2].cities[i]);
        }
        for(int i=point2+1 ; i<cnt; ++i){
            swap(group[temp1].cities[i], group[temp2].cities[i]);
        }
        //中间产生映射, 处理冲突
        memset(map1, 0, sizeof(map1));
        memset(map2, 0, sizeof(map2));
        for(int i=point1 ; i<=point2; ++i){
            map1[group[temp1].cities[i]] = group[temp2].cities[i];
            map2[group[temp2].cities[i]] = group[temp1].cities[i];
        }
        //处理temp1的冲突
        for(int k = 0 ; k < point1; ++k){
            for(int kk = point1; kk<=point2; ++kk){
                if(group[temp1].cities[k] == group[temp1].cities[kk]){
                    group[temp1].cities[k] = map1[group[temp1].cities[kk]];
                    kk=point1-1;
                    //cout<<"kk = "<<kk<<" ";    system("pause");
                }
            }
        }
        for(int k = point2+1 ; k < cnt; ++k){
            for(int kk = point1; kk<=point2; ++kk){
                if(group[temp1].cities[k] == group[temp1].cities[kk]){
                    group[temp1].cities[k] = map1[group[temp1].cities[kk]];
                    kk=point1-1;
                }
            }
        }
        //处理temp2的冲突
        for(int k = 0 ; k < point1; ++k){
            for(int kk = point1; kk<=point2; ++kk){
                if(group[temp2].cities[k] == group[temp2].cities[kk]){
                    group[temp2].cities[k] = map2[group[temp2].cities[kk]];
                    kk=point1-1;
                }
            }
        }
        for(int k = point2+1 ; k < cnt; ++k){
            for(int kk = point1; kk<=point2; ++kk){
                if(group[temp2].cities[k] == group[temp2].cities[kk]){
                    group[temp2].cities[k] = map2[group[temp2].cities[kk]];
                    kk=point1-1;
                }
            }
        }
    }
    //cout<<"After crossover:"<<endl;
    //print();
}

void mutate(){
    int mutatep[groupNum];
    int t=0;//变异个数
    srand(time(0));
    memset(mutatep, 0, sizeof(mutatep));
    for(int i=0 ; i<groupNum ; ++i){
        double x = rand()%100;
        x /= 100;
        if( x< mp){
            mutatep[t++] = i;
        }
    }
    //开始变异,即随机交换一对城市
    for(int i =0 ; i<t; ++i){
        int temp = mutatep[i];
        int point1 = rand()%cnt;
        int point2 = rand()%cnt;
        swap(group[temp].cities[point1], group[temp].cities[point2]);
    }

    //cout<<"After mutation:"<<endl;
    //print();
}

int main(){
    init();
    pre_value();
    int counter = 0;
    while(counter++ < runs){
        fitness();
        select();
        cross();
        mutate();
    }
    print();
    cout<<"Best tsp = "<<best_tsp<<endl;
    cout<<"Trace:"<<endl;
    for(int i=0 ; i<cnt ; ++i){
        cout<<trace[i]<<" ";
    }
    cout<<endl;
    system("pause");
    return 0;
}
时间: 2024-10-04 17:50:34

Genetic Algorithm Primary的相关文章

2. Genetic Algorithm(1) ——进化算法

本篇博文讲述基因算法(Genetic Algorithm),基因算法是最著名的进化算法. 内容依然来自博主的听课记录和教授的PPT. Outline 简单基因算法 个体表示 变异 重组 1. 简单基因算法(Simple Genetic Algorithm) Holland's早期的基因算法被认为是“简单的基因算法”或是“权威的基因算法”.(simple genetic algorithm or canonical genetic algorithm) 1. 直接举例说明 问题描述:利用遗传算法求

Genetic Algorithm遗传算法学习

参考资料:http://blog.csdn.net/b2b160/article/details/4680853/#comments(冒昧的用了链接下的几张图) 百度百科:http://baike.baidu.com/link?url=FcwTBx_yPcD5DDEnN1FqvTkG4QNllkB7Yis6qFOL65wpn6EdT5LXFxUCmv4JlUfV3LUPHQGdYbGj8kHVs3GuaK 算法介绍 遗传算法是模拟达尔文生物进化论的自然选择和遗传学进化机理的计算模型.运用到了生物

使用遗传算法实现迷宫游戏(genetic maze)

强烈推荐一本书 <游戏编程中的人工智能技术>(AI.Techniques.for.Game.Programming).(美)Mat.Buckland 一.缘起 在之前的c印记系列当中有有一个迷宫小游戏,算是一个关于数组应用的例子. 其中有通过接收按键(人工操作)的方式来走出迷宫,也有使用递归算法或非递归算法的方式来实现自动(AI操作)走出迷宫. 后来我对近两三年比较火的人工智能,机器学习,深度学习之类的比较感兴趣了.于是乎,我找了很多书籍或网上的文章来看.但基本上都是两个类别的,其中一类就是一

启发式算法(Heuristic Algorithm)

背景: 李航的<统计学习方法>一书中提到:决策树算法通常采用启发式算法,故了解之 问题解答: 时间有限,这里也只是将算法和启发式算法的区别和简单发展摘录如下: 一.算法和启发式方法之间的差别很微妙,两个术语的意思也有一些重叠.就本书的目的而言,它们之间的差别就在于其距离最终解决办法的间接程度:算法直接给你解决问题的指导,而启发式方法则告诉你该如何发现这些指导信息,或者至少到哪里去寻找它们. 二.发展 40年代:由于实际需要,提出了启发式算法(快速有效). 50年代:逐步繁荣,其中贪婪算法和局部

[Evolutionary Algorithm] 进化算法简介

进化算法,也被成为是演化算法(evolutionary algorithms,简称EAs),它不是一个具体的算法,而是一个“算法簇”.进化算法的产生的灵感借鉴了大自然中生物的进化操作,它一般包括基因编码,种群初始化,交叉变异算子,经营保留机制等基本操作.与传统的基于微积分的方法和穷举方法等优化算法(具体介绍见博客[Math] 常见的几种最优化方法中的其他数学优化方法)相比,进化计算是一种成熟的具有高鲁棒性和广泛适用性的全局优化方法,具有自组织.自适应.自学习的特性,能够不受问题性质的限制,有效地

Multiobjective Optimisation with Evolutionary Algorithm - 1. 序言

多目标优化与单目标优化 优化问题广泛存在于我们的生活之中.当可利用的资源有限时,我们总想要用最有效率的方法来解决问题.从工程问题到科学研究,再到商业决策,都可以找到优化问题的影子.由此可见,优化问题是重要的. 当优化问题只拥有一个需要优化的目标时,就被称为单目标优化(Single-objective Optimisation).这类问题的解决方法早在二战期间就已经被学者们进行研究.当优化问题具有多个需要优化的目标时,就被称为多目标优化(Multi-objective Optimisation).

科技文献检索

The Fundamentals of Three-Phase Power Measurements Application Note Introduction Although single-phase electricity is used to supply common domestic and office electrical appliances, three-phase alternating current (a.c.) systems are almost universal

.NET 开源开发项目

本文列出了 .NET 开源开发项目(open source developer projects).意在包括对开发过程的所有方面有所帮组的项目.对于消费项目(consumerprojects),请参阅.NET开源消费项目清单. 下面按字母排序,并提供一行文字说明.GitHub/CodePlex(或其他)链接优先. .NET 实现 .NET Core - Core .NET 框架 C# Native – 把 C# 编译成本地代码. Cosmos - C# 开源的管理操作系统,一个操作系统是"con

C++开源库集合

| Main | Site Index | Download | mimetic A free/GPL C++ MIME Library mimetic is a free/GPL Email library (MIME) written in C++ designed to be easy to use and integrate but yet fast and efficient. It is based on the C++ standard library and heavily us