遗传算法的理解和自编的利用遗传算法进行路径寻优

来源:互联网 发布:政府信用结构优化导向 编辑:程序博客网 时间:2024/06/05 07:05

本博客首先转载了一篇关于遗传算法的文章,通过这个简单的例子来学习遗传算法,然后自编了一个利用遗传算法寻找最小花费路径的程序。

一、遗传算法的手工模拟计算示例(转自 http://blog.csdn.net/b2b160/article/details/4680853/)

 为更好地理解遗传算法的运算过程,下面用手工计算来简单地模拟遗传算法的各个主要执行步骤。

        例:求下述二元函数的最大值:

(1) 个体编码

 遗传算法的运算对象是表示个体的符号串,所以必须把变量 x1, x2 编码为一种符号串。本题中,用无符号二进制整数来表示。
  因 x1, x2 为 0 ~ 7之间的整数,所以分别用3位无符号二进制整数来表示,将它们连接在一起所组成的6位无符号二进制数就形成了个体的基因型,表示一个可行解。
  例如,基因型 X=101110 所对应的表现型是:x=[ 5,6 ]。个体的表现型x和基因型X之间可通过编码和解码程序相互转换。

(2) 初始群体的产生
  遗传算法是对群体进行的进化操作,需要给其淮备一些表示起始搜索点的初始群体数据。
  本例中,群体规模的大小取为4,即群体由4个个体组成,每个个体可通过随机方法产生。
    如:011101,101011,011100,111001

(3) 适应度汁算

   遗传算法中以个体适应度的大小来评定各个个体的优劣程度,从而决定其遗传机会的大小。
    本例中,目标函数总取非负值,并且是以求函数最大值为优化目标,故可直接利用目标函数值作为个体的适应度。

 (4)  选择运算
  选择运算(或称为复制运算)把当前群体中适应度较高的个体按某种规则或模型遗传到下一代群体中。一般要求适应度较高的个体将有更多的机会遗传到下一代群体中。                   
  本例中,我们采用与适应度成正比的概率来确定各个个体复制到下一代群体中的数量。其具体操作过程是:
         •  先计算出群体中所有个体的适应度的总和  fi  ( i=1.2,…,M );
         •  其次计算出每个个体的相对适应度的大小 fi / fi ,它即为每个个体被遗传到下一代群体中的概率,
         •  每个概率值组成一个区域,全部概率值之和为1;
         •  最后再产生一个0到1之间的随机数,依据该随机数出现在上述哪一个概率区
             域内来确定各个个体被选中的次数。

(5)  交叉运算
交叉运算是遗传算法中产生新个体的主要操作过程,它以某一概率相互交换某两个个体之间的部分染色体。
    本例采用单点交叉的方法,其具体操作过程是:
       • 先对群体进行随机配对;
       • 其次随机设置交叉点位置;
       • 最后再相互交换配对染色体之间的部分基因。

(6)  变异运算
         变异运算是对个体的某一个或某一些基因座上的基因值按某一较小的概率进行改变,它也是产生新个体的一种操作方法。
        本例中,我们采用基本位变异的方法来进行变异运算,其具体操作过程是:
        • 首先确定出各个个体的基因变异位置,下表所示为随机产生的变异点位置,
          其中的数字表示变异点设置在该基因座处;
        • 然后依照某一概率将变异点的原有基因值取反。

对群体P(t)进行一轮选择、交叉、变异运算之后可得到新一代的群体p(t+1)。

从上表中可以看出,群体经过一代进化之后,其适应度的最大值、平均值都得到了明显的改进。事实上,这里已经找到了最佳个体“111111”。       
[注意]      
        需要说明的是,表中有些栏的数据是随机产生的。这里为了更好地说明问题,我们特意选择了一些较好的数值以便能够得到较好的结果,而在实际运算过程中有可能需要一定的循环次数才能达到这个最优结果。

二、利用遗传算法进行路径寻优

我们实现的是中兴2017迪杰斯特拉比赛的程序,效果很不好,主要是单纯利用遗传算法收敛速度太慢,但现记录如下,方便以后的复习和参考:

先讲下大致的思路:按照种群初始化->交叉->变异->选择的顺序来做的。但我门牙进行交叉计算,因为设计不出好的交叉方法,反而若进行交叉运算后,联通性又会降低。变异选择了三种方法:

1.移出一个非必经点

2.移入一个非必经点

3..互相交换两点,产生变异基因,不交换必经线上的点

下面是代码:

#include<iostream>#include<time.h>#include<fstream>using namespace std;//定义全局变量// /f相关char g_iFileName[256];//输入文件名,文件中包含题目要求的灵界矩阵// /o相关char g_oFileName[256];//输出文件名,文件中包含选择的路径// /s相关int g_SourcePoint;//源点int g_SourcePoint=0;// /d相关int g_DestPoint;//目标点int g_DestPoint=17;// /g相关int g_GreenPoint[20];//必经点的矩阵(绿点)int g_GreenPoint[20]={7,12}int g_CommandLen;// /g的命令行长度int g_GreenPointLen;//必经点个数,GreenPoint大小,int g_GreenPointLen=2;// /n相关int g_MaxNode;//最多经过的点数int g_MaxNode=12;// /r相关int g_RedLine[20][2];//不可经过的点的矩阵(红线)int g_RedLine[20][2]={{11,12}};int g_RedPoint[40];//红线对应的点的数组int g_RedPoint[20]={11,12}int g_RedLinePointLen;//不可经过线的个数的二倍,统计的是点的个数 int g_RedLinePointLen=2;// /l相关int g_GreenLine[20][2];//必须经过的点的矩阵(绿线)int g_GreenLine[20][2]={{2,4}{13,14}};int g_GreenLinePoint[40];//int g_GreenLinePoint={2,4,13,14}int g_GreenLinePointLen;//必须经过线的个数的二倍,统计的是点的个数 int g_GreenLinePointLen=4;// /t相关int g_TotalPoint;//总共的节点数 int g_TotalPoint=18;struct _GRAPH {char vexs[1000];//定点集合int vexnum;//定点数//int edgnum;//边数int matrix[1000][1000];//邻接矩阵}Graph;//*PGraph#define INF 10000//基因初始化用到的全局变量const int g_InitNum = 80;int g_InitGeneGroup[1000][256];//初始化的基因种群GeneGroupint g_InitGeneLen[1000];//统计每代基因的长度GeneLenint g_unNecNode[100];//非必经点构成的数组int g_NecNode[100];//必经点构成的数组float g_InvalidProportion[9] = { 0.60,0.65,0.70,0.75,0.80,0.85,0.90,0.95,1.0 };//无效边所占的比例int g_InvalidIdx=0;int g_LenofNecNode;//必经点的个数//基因变异用到的全局变量int g_VarGeneGroup[1000][1000];//初始化的基因种群GeneGroup_varint g_VarGeneLen[1000];//统计每代基因的长度GeneLen_var//基因选择用到的全局变量int g_total_score[1000];//保存所有染色体权重的数组int g_total_arc[1000]; //保存所有染色体有效边数的数组int g_init_score[1000];int g_init_arc[1000];//读入txt文件,并存入数据结构中void create_adjmatrix() {ifstream infile(g_iFileName);int array[1024];//存储txt中的矩阵int* ptr = &array[0];int i,j;//先将txt的数据传入到array的一维矩阵中while (!infile.eof()){infile >> *ptr;ptr++;}//然后将array传入到Graph.matrix中//我想在这里实现对txt数据的一些处理/*具体如下:txt文件中,两点之间没有连接的为0,点与自己的距离也为0在这里通过判断语句进行修改*/Graph.vexnum = g_TotalPoint;for (i = 0;i<Graph.vexnum;i++)for (j = 0;j < Graph.vexnum;j++) {if (i == j) {Graph.matrix[i][j] = 0;}else if (array[i * Graph.vexnum + j] == 0)Graph.matrix[i][j] = INF;elseGraph.matrix[i][j] = array[i * 18 + j];}//删除红线int _begin, _end;for (i = 0;i < g_RedLinePointLen / 2;++i) {_begin = g_RedLine[i][0];_end = g_RedLine[i][1];Graph.matrix[_begin][_end] = INF;Graph.matrix[_end][_begin] = INF;}//测试程序/*cout << "****邻接矩阵***********" << endl;for (int i = 0;i < Graph.vexnum;i++) {for (int j = 0;j < Graph.vexnum;j++) {cout << Graph.matrix[i][j] << " ";}cout << '\n';}cout << endl;*/}//初始化非必经点数组void unNecMatrix_init() //类似源程序中的sel_v_init程序{//将必经点写到一个矩阵中g_NecNode,想一想有没有这个必要g_LenofNecNode = g_GreenLinePointLen + g_GreenPointLen;int i;for (i = 0;i < g_GreenPointLen;i++)g_NecNode[i] = g_GreenPoint[i];for (;i<g_LenofNecNode;i++)g_NecNode[i] = g_GreenLinePoint[i - g_GreenPointLen];//测试程序 看NessNode保存到所有必经点了没/*cout << "g_NecNode" << endl;for (int j = 0;j < LenofNecNode;j++)cout << g_NecNode[j] << " ";cout << endl;*///for (int j = 0;j < g_TotalPoint;j++){g_unNecNode[j] = j;}int tempNum;for (int j = 0;j < g_LenofNecNode;j++){tempNum = g_NecNode[j];g_unNecNode[tempNum] = INF;}g_unNecNode[g_SourcePoint] = INF;g_unNecNode[g_DestPoint] = INF;//测试程序/*cout << "g_unNecNode" << endl;for (int j = 0;j <g_TotalPoint;j++)cout << g_unNecNode[j] << "  ";cout << endl;//*/}//返回[_min,_max]之间的一个随机数int _rand(int _min, int _max) {return rand() % (_max - _min + 1) + _min;}//交换两个整数void _swap(int *a, int *b){int t = *a;*a = *b;*b = t;}//查找程序:array数组长度为len,查找num的位置int _find(int*array, int len, int num) {//测试程序/*cout << "传入数组没" << endl;for (int i = 0;i < len;++i)cout << array[i] << " ";cout << endl;*///测试结束for (int i = 0;i < len;++i){if (array[i] == num)return i;}cout << "不可能啊!" << endl;return INF;}//插入程序:arr是数组,len是数组长度,num是要插入的元素,pos是要插入的位置void _insert(int *arr, int len, int num, int pos) {for (int i = len;i > pos;i--)arr[i] = arr[i - 1];arr[pos] = num;}//检查结点连接情况的算法//u,v是两个结点,若连接,则返回1,否则为0int  _checkArc(int u, int v) {if ((Graph.matrix[u][v]) != 0 && ((Graph.matrix[u][v]) != INF))return 1;elsereturn 0;}//染色体初始化void GA_init() {int PerGenLen;//计算基因长度用到的一个变量PerGenLen,gen_lenint node;//选取的结点int oldI = 0;//关于判断初始化的基因合适程度的参数int backAgain = 0;                              /* 某个基因不合格,返工的次数 *///这些变量在程序移动到主程序中,要适当的删减和修改for (int i = 0;i < g_InitNum;i++) {int m = 0;unNecMatrix_init();//初始化非必经点数组,g_InitGeneGroup[i][0] = g_SourcePoint;//源点是初始点++m;//最多可历经的随机非必经点的个数int Max_NoNessNode = g_MaxNode - g_GreenPointLen - g_GreenLinePointLen - 2;int Num_NecNode = _rand(0, Max_NoNessNode);//测试生成随机数1//cout << "随机数: " << i << " " << Num_NoNessNode << endl;//测试结束//统计每代基因的长度PerGenLen = g_GreenPointLen + g_GreenLinePointLen + 2 + Num_NecNode;g_InitGeneLen[i] = PerGenLen;//加入必经点1.加入绿点for (int j = 0;j < g_GreenPointLen;++j){g_InitGeneGroup[i][m] = g_GreenPoint[j];++m;}//加入必经点2.加入绿线上的两个点,只加入两点中的一个for (int j = 0;j < (g_GreenLinePointLen / 2);++j) {g_InitGeneGroup[i][m] = g_GreenLine[j][0];++m;}//加入非必经点for (int j = 0;j < Num_NecNode;++j) {node = _rand(1, g_TotalPoint - 1);while (g_unNecNode[node] == INF) {++node;if (node > g_TotalPoint - 1)node = node - g_TotalPoint;}//cout << "zhang node: " << node << endl;g_InitGeneGroup[i][m] = g_unNecNode[node];g_unNecNode[node] = INF;++m;}//测试g_InitGeneGroup/*cout << "******g_InitGeneGroup*******" << endl;for (int j = 0;j < m;++j)cout << g_InitGeneGroup[i][j] << " ";cout << endl;//*///对必经点和非必经点打乱顺序//分两步:1.先打乱g_InitGeneGroup中的元素顺序,再插入绿线上的点//1.打乱已在g_InitGeneGroup中的元素for (int j = 1;j<m - 1;++j)                   /* 对必经节点和非必经点排列 */{_swap(&g_InitGeneGroup[i][j], &g_InitGeneGroup[i][_rand(j + 1, m - 1)]);}/*//测试g_InitGeneGroup打乱顺序的第一步cout << "******g_InitGeneGroup打乱顺序*******" << endl;for (int j = 0;j < m;++j)cout << g_InitGeneGroup[i][j] << " ";cout << endl;//*///2.插入绿线上的另一点int index;//确定的位置int mode;//随机插入的模式,在之前,或者之后for (int p = 0;p < (g_GreenLinePointLen / 2);++p)//遍历绿线{//在g_InitGeneGroup找到GreenLine[p][0]的位置index = _find(g_InitGeneGroup[i], m, g_GreenLine[p][0]);//cout << "要找的元素" << g_GreenLine[p][0] << endl;//cout << "测试找到位置没" << index << endl;//随机插入位置:在之前或者之后插入mode = _rand(0, 1);index = index + mode;////cout << "改变位置" << index << endl;//根据位置插入元素_insert(g_InitGeneGroup[i], m, g_GreenLine[p][1], index);++m;//测试程序//cout << "********看插入的元素对不对*******" << endl;//cout << "index:" << index << endl;//cout << "m:" << m << endl;//cout << "要插入的元素:" << GreenLine[p][1] << endl;/*for (int j = 0;j < m;++j)cout << g_InitGeneGroup[i][j] << " ";cout << endl;*///测试结束}//插入结束点g_InitGeneGroup[i][m] = g_DestPoint;++m;//m是基因的长度//测试/*cout << "完整的基因顺序" << endl;for (int j = 0;j < m;++j)cout <<g_InitGeneGroup[i][j] << " ";cout << endl;*///统计无效弧的数量int invalid_arc = 0;for (int j = 1;j < m;++j) {if (!_checkArc(g_InitGeneGroup[i][j - 1], g_InitGeneGroup[i][j]))++invalid_arc;}//测试invalid_arc//cout << "计算invalid_arc:" << invalid_arc << endl;//如果无效弧数多于总数的60%,重新生成if (invalid_arc > g_InvalidProportion[g_InvalidIdx] * g_InitGeneLen[i]) {if (i == oldI) {//oldI是上次基因不合适的标签backAgain++;if (backAgain > 3000){g_InvalidIdx++;backAgain = 0;}}else{backAgain = 0;oldI = i;}--i;invalid_arc = 0;}}}//染色体变异void GA_var() {int var_idx;//int glen;//基因除去源点和终点的长度int tempG[6000];//tempG存储的是必经点的标签int tempP[6000];//变异三存储连接线的点int allNec = 0;//是否全部为必经点的标签,1为是,0为否int loc1, loc2, loc3;int temp1 = 0, temp2 = 0, temp3 = 0;for (int i = 0;i < g_InitNum;++i)//g_InitNum是种群的个数{memset(tempG, 0, sizeof(int) * (g_TotalPoint));//cout << "zhangbo 1" << endl;var_idx = 3 * i;for (int j = 0;j < g_LenofNecNode;++j)tempG[g_NecNode[j]] = 1;//必经点设为1tempG[g_SourcePoint] = 1;tempG[g_DestPoint] = 1;//cout << "zhangbo2" << endl;//测试tempG/*cout << "*****tempG*********" << endl;cout << "i: " << i << endl;for (int m = 0;m < TotalPoint;++m)cout << tempG[m] << " ";cout << endl;*/glen = g_InitGeneLen[i] - 2;//基因除去源点和终点的长度if (glen == g_LenofNecNode)allNec = 1;elseallNec = 0;//方式1.移出一个非必经点if (allNec) {//如果全部是必经点,直接存到g_VarGeneGroup数组中memcpy(g_VarGeneGroup[var_idx], g_InitGeneGroup[i], sizeof(int)*g_InitGeneLen[i]);g_VarGeneLen[var_idx] = g_InitGeneLen[i];loc1 = 1;}else {loc1 = _rand(1, glen);temp1 = g_InitGeneGroup[i][loc1];//temp1是loc1位置上的节点号while (tempG[temp1] == 1) {++loc1;if (loc1 > glen)loc1 -= glen;temp1 = g_InitGeneGroup[i][loc1];}for (int j = 0;j < loc1;++j)g_VarGeneGroup[var_idx][j] = g_InitGeneGroup[i][j];for (int j = loc1 + 1;j<g_InitGeneLen[i];++j)g_VarGeneGroup[var_idx][j - 1] = g_InitGeneGroup[i][j];g_VarGeneLen[var_idx] = g_InitGeneLen[i] - 1;}//测试//原基因/*cout << "******源基因******" << endl;for (int m = 0;m < GeneLen[i];++m)cout << GeneGroup[i][m] << " ";cout << endl;cout << "******变异基因1******" << endl;cout << "loc1: " << loc1 << endl;for (int m = 0;m < g_VarGeneLen[var_idx];++m)cout << g_VarGeneGroup[var_idx][m] << " ";cout << endl;*///方式2.移入一个非必经点,进行变异//移入的位置也是随机的,是上面loc1确定的,不必担心插入到必经连线中间if (g_InitGeneLen[i] == g_MaxNode)//已经达到最多点,无法再移入{memcpy(g_VarGeneGroup[var_idx + 1], g_InitGeneGroup[i], sizeof(int)*g_InitGeneLen[i]);g_VarGeneLen[var_idx + 1] = g_InitGeneLen[i];}else{for (int j = 0;j < g_VarGeneLen[i];++j)tempG[g_VarGeneGroup[i][j]] = 1;loc2 = _rand(1, g_TotalPoint - 1);while (tempG[loc2] == 1){++loc2;if (loc2 > g_TotalPoint - 1)loc2 -= g_TotalPoint - 1;}//cout << "loc2: " << loc2 << endl;for (int j = 0;j < loc1;++j)g_VarGeneGroup[var_idx + 1][j] = g_InitGeneGroup[i][j];g_VarGeneGroup[var_idx + 1][loc1] = loc2;for (int j = loc1;j < g_InitGeneLen[i];++j)g_VarGeneGroup[var_idx + 1][j + 1] = g_InitGeneGroup[i][j];g_VarGeneLen[var_idx + 1] = g_InitGeneLen[i] + 1;}//cout << "******变异基因2******" << endl;/*for (int m = 0;m < g_VarGeneLen[var_idx+1];++m)cout << g_VarGeneGroup[var_idx+1][m] << " ";cout << endl;*///方式3.互相交换两点,产生变异基因,不交换绿线上的点memset(tempP, 0, sizeof(int)*(g_TotalPoint + 1));for (int j = 0;j < g_GreenLinePointLen;++j)tempP[g_GreenLinePoint[j]] = 1;/*cout << "******tempP*****" << endl;for (int m = 0;m < TotalPoint;++m)cout << tempP[m] <<" ";cout << endl;*/loc1 = _rand(1, glen);temp1 = g_InitGeneGroup[i][loc1];while (tempP[temp1] == 1){++loc1;if (loc1 > glen)loc1 -= glen;temp1 = g_InitGeneGroup[i][loc1];}loc3 = _rand(1, glen);temp3 = g_InitGeneGroup[i][loc3];while (tempP[temp3] == 1){++loc3;if (loc3 > glen)loc3 -= glen;temp3 = g_InitGeneGroup[i][loc3];}if (loc3 < loc1)_swap(&loc1, &loc3);g_VarGeneGroup[var_idx + 2][loc1] = g_InitGeneGroup[i][loc3];g_VarGeneGroup[var_idx + 2][loc3] = g_InitGeneGroup[i][loc1];for (int j = 0;j<loc1;++j)g_VarGeneGroup[var_idx + 2][j] = g_InitGeneGroup[i][j];for (int j = loc1 + 1;j<loc3;++j)g_VarGeneGroup[var_idx + 2][j] = g_InitGeneGroup[i][j];for (int j = loc3 + 1;j<g_InitGeneLen[i];++j)g_VarGeneGroup[var_idx + 2][j] = g_InitGeneGroup[i][j];g_VarGeneLen[var_idx + 2] = g_InitGeneLen[i];/*cout << "******变异基因3******" << endl;cout << "loc1: " << loc1 << "   " << "loc3: " << loc3 << endl;for (int m = 0;m < g_VarGeneLen[var_idx + 2];++m)cout << g_VarGeneGroup[var_idx + 2][m] << " ";cout << endl;*/}}//计算每条路径的权重int _weight(int *arr, int len) {//测试数据传入了没/*cout << "测试数据传入了没" << endl;for (int i = 0;i < len;++i)cout << arr[i] << " ";cout << endl;return 1;*/int weight = 0;for (int i = 0;i < len - 1;++i)weight += Graph.matrix[arr[i]][arr[i + 1]];return weight;}//用于快速排列的qsort函数int _cmp(const void*a, const void *b) {if (g_total_score[*(int*)a] > g_total_score[*(int *)b])return 1;else if (g_total_score[*(int*)a] < g_total_score[*(int *)b])return -1;elsereturn g_total_arc[*(int*)b] - g_total_arc[*(int*)a];}//基因选择void GA_sel() {int i, j;int valid_arc;int bestG[500];int temp_InitScore[500];//选择了80个基因后的权重数组int temp[500];float delt[320];float prob[320];double gama = 0;double dice;int num_var = 3 * g_InitNum;//240int num_tal = 4 * g_InitNum;//320int temp_VarGeneGroup[500][100];//基因选择用到的int temp_VarGeneLen[500];//排序后的权重和arc的数组int  end_score[1000];int  end_arc[1000];//初始化 g_total_score和g_total_arc;memset(g_total_score, 0, sizeof(int) * 1000);memset(g_total_arc, 0, sizeof(int) * 1000);/*//测试程序cout << "g_VarGeneGroup" << endl;for (int i = 0;i < 320;++i) {cout << i << ":";for (int j = 0;j < g_VarGeneLen[i];++j)cout << g_VarGeneGroup[i][j] << " ";cout << endl;}*///将g_InitGeneGroup的基因转移到g_VarGeneGroup中for (i = num_var, j = 0;i < num_tal;++i, ++j) {memcpy(g_VarGeneGroup[i], g_InitGeneGroup[j], sizeof(int)*g_InitGeneLen[j]);g_VarGeneLen[i] = g_InitGeneLen[j];}//计算所有染色体的有效边数for (i = 0;i < num_tal;++i) {valid_arc = 0;for (j = 0;j < g_VarGeneLen[i] - 1;++j){if (_checkArc(g_VarGeneGroup[i][j], g_VarGeneGroup[i][j + 1]))++valid_arc;}g_total_arc[i] = valid_arc;}//计算所有染色体的权重for (i = 0;i < num_tal;++i) {g_total_score[i] = _weight(g_VarGeneGroup[i], g_VarGeneLen[i]);}/*//测试程序cout << "************排序前的所有基因**********" << endl;for (int i = 0;i < 320;++i) {cout << i << " :";for (int j = 0;j < g_VarGeneLen[i];++j) cout << g_VarGeneGroup[i][j] << " ";cout << "权重为: "<<g_total_score[i]<<"总边数: "<< g_VarGeneLen[i] <<"  有效边数:  "<< g_total_arc[i] <<endl;cout << endl;}//*///初始化bestG数组for (i = 0;i < 320;++i)bestG[i] = i;qsort(bestG, 320, sizeof(bestG[0]), _cmp);//根据bestG重新排列g_VarGeneGroup到temp_VarGeneGroup,g_VarGeneLen到temp_VarGeneLen中for (i = 0;i < 320;++i) {memcpy(temp_VarGeneGroup[i], g_VarGeneGroup[bestG[i]], sizeof(int)*g_VarGeneLen[bestG[i]]);temp_VarGeneLen[i] = g_VarGeneLen[bestG[i]];}/*cout << "****************bestG*****************" << endl;for (int i = 0;i < 320;++i)cout << bestG[i] << endl;*///计算重新排序后所有染色体的权重和有效边数for (i = 0;i < 320;++i) {end_score[i] = g_total_score[bestG[i]];end_arc[i] = g_total_arc[bestG[i]];}/*cout << "************排序后的所有基因**********" << endl;for (int i = 0;i < 320;++i) {cout << i << " :";for (int j = 0;j < temp_VarGeneLen[i];++j)cout << temp_VarGeneGroup[i][j] << " ";cout << "权重为: " << end_score[i] << "总边数: " << temp_VarGeneLen[i] << "  有效边数:  " << end_arc[i] << endl;}*///前10条染色体直接复制到下一代for (i = 0;i < 2;++i) {memcpy(g_InitGeneGroup[i], temp_VarGeneGroup[i], sizeof(int)*temp_VarGeneLen[i]);g_InitGeneLen[i] = temp_VarGeneLen[i];g_init_score[i] = g_total_score[bestG[i]];g_init_arc[i]= g_total_arc[bestG[i]];}//后70条基因通过轮盘赌的方法来选出//计算后面染色体的适应度delt和适应度之和gamafor (i = 10, j = 0;i < 320;++i, ++j) {delt[j] = (float)end_score[0] / end_score[i];gama += delt[j];}//计算后面的个体在轮赌盘中被选择的概率for (j = 0;j < 320-2;++j) {prob[j] = delt[j] / gama;}//求得个体轮盘赌中被选择的随机数范围for (j = 1;j < 320-2;++j) {prob[j] += prob[j - 1];}//选择70条染色体for (i = 10;i < g_InitNum;++i) {dice = rand() / (RAND_MAX + 1.0);j = -1;do {++j;} while (dice > prob[j]);//cout <<"zhangbo" <<j+10 << endl;memcpy(g_InitGeneGroup[i], temp_VarGeneGroup[j+10], sizeof(int)*temp_VarGeneLen[j+10]);g_InitGeneLen[i] = temp_VarGeneLen[j+10];g_init_score[i] = g_total_score[bestG[j+10]];g_init_arc[i] = g_total_arc[bestG[j+10]];}/*//选择的80个基因cout << "*************最终选择的80个染色体*************" << endl;for (int i = 0;i < 80;++i) {cout << i << " :";for (int j = 0;j < g_InitGeneLen[i];++j)cout << g_InitGeneGroup[i][j] << " ";cout <<"权重: "<< g_init_score[i] << " 有效边数:"<< g_init_arc[i] <<"  总边数:"<< g_InitGeneLen[i] <<endl;cout << endl;}*/}//计算结果判断bool GA_result() {int i = 0;bool flag = 0;if (g_init_arc[0] == g_InitGeneLen[0]-1) {flag = 1;cout << "找到了" << endl;for (int i = 0;i < g_InitGeneLen[0];++i)cout << g_InitGeneGroup[0][i] << " ";cout << "g_InitGeneLen: " << g_InitGeneLen[0] << endl;cout << "g_init_arc: " << g_init_arc[0] << endl;cout << "g_init_score: " << g_init_score[0] << endl;cout << endl;}else {flag = 0;cout << "没有找到!" << endl;for (int i = 0;i < g_InitGeneLen[i] - 1;++i)cout << g_InitGeneGroup[0][i] << " ";cout << "g_InitGeneLen: " << g_InitGeneLen[0] << endl;cout << "g_init_arc: " << g_init_arc[0] << endl;cout << "g_init_score: " << g_init_score[0] << endl;cout << endl;}return flag;}//遗传算法void GA() {srand((unsigned int)time(NULL));//染色体初始化//GA_init();//测试程序,看g_InitGeneGroup的成果/*cout << "**********初始化**********" << endl;for (int i = 0;i < g_InitNum;++i) {for (int j = 0;j < g_InitGeneLen[i];++j)cout << g_InitGeneGroup[i][j] << " ";cout << endl;}cout << endl;//*///染色体变异//GA_var();//测试程序/*cout << "*********交叉后的染色体*********" << endl;int k = 0;for (int i = 0;i < 80;++i) {cout << "原基因:" << endl;for (int j = 0;j < g_InitGeneLen[i];++j)cout << g_InitGeneGroup[i][j] << " ";cout << endl;for (int j = 0;j < g_VarGeneLen[k];++j)cout << g_VarGeneGroup[k][j] << " ";cout << endl;++k;for (int j = 0;j < g_VarGeneLen[k];++j)cout << g_VarGeneGroup[k][j] << " ";cout << endl;++k;for (int j = 0;j < g_VarGeneLen[k];++j)cout << g_VarGeneGroup[k][j] << " ";cout << endl;++k;cout << "*****************" << endl;}*///染色体选择//测试程序//GA_sel();//染色体结果//GA_result();int i = 0;srand((unsigned int)time(NULL));GA_init();int flag;do {cout << i << " " << endl;GA_var();//cout << "GA_var" << endl;GA_sel();//cout << "GA_sel" << endl;flag = GA_result();//cout << "GA_result" << endl;} while ((++i < 5000));}int main(int argc, char* argv[]) {///*测试程序,可删除cout << argc << endl;for (int i = 0;i < argc;i++)cout << argv[i] << "\n";cout << endl;//*//*说明通过命令行来传入参数,下面对参数进行说明:/f:拓扑图文件的路径/s:源节点/d:目标节点/g:必须经过的点(green point),输入形式"/g1,5,10"/l:必须经过的线(green line),输入形式"/l4-5,16-27"/r:要避开的线(应该以线的两个端点表示)(red line),输入形式类似"/l"/o:后面表示输出结果文件/n:最多经过n点/t:总共的点数例如如下输出:*///STEP1.检查命令行参数if (argc != 10) {cout << "format: cpath.exe /fInputFileName /sSourceNum /dDestNum /oOutputFileName" << endl;system("pause");return 0;}//cout << "输入正确!" << endl;int tempNum;char tempStr[10];int m = 0, n = 0, p = 0;//循环中用到的参数for (int i = 1;i < 10;++i) {switch (argv[i][1]) {case'f':strcpy_s(g_iFileName, 256, argv[i] + 2);//cout << "f" << iFileName << endl;break;case'o':strcpy_s(g_oFileName, 256, argv[i] + 2);//cout << "o" << oFileName << endl;break;case's':g_SourcePoint = atoi(argv[i] + 2);//cout << "s" << source << endl;break;case'd':g_DestPoint = atoi(argv[i] + 2);//cout << "d" << dest << endl;break;case'n':g_MaxNode = atoi(argv[i] + 2);//cout << "n" << MaxNode << endl;break;case't':g_TotalPoint= atoi(argv[i] + 2);break;case'g':g_CommandLen = strlen(argv[i]);g_GreenPointLen = 0;//for (m = 2;m < g_CommandLen;) {tempNum = atoi(argv[i] + m);_itoa_s(tempNum, tempStr, 10, 10);g_GreenPoint[g_GreenPointLen] = tempNum;++g_GreenPointLen;m += strlen(tempStr) + 1;}break;case'r'://前面是'g'的程序,后面是将一维矩阵转化成二维矩阵g_CommandLen = strlen(argv[i]);g_RedLinePointLen = 0;//p = 0;for (m = 2;m < g_CommandLen;) {tempNum = atoi(argv[i] + m);_itoa_s(tempNum, tempStr, 10, 10);g_RedPoint[g_RedLinePointLen] = tempNum;g_RedLinePointLen++;m += strlen(tempStr) + 1;}//将GreenPoint转化成二维矩阵for (m = 0;m < g_RedLinePointLen / 2;m++)for (int n = 0;n < 2;n++) {g_RedLine[m][n] = g_RedPoint[p];p++;}break;case'l'://前面是'g'的程序,后面是将一维矩阵转化成二维矩阵g_CommandLen = strlen(argv[i]);g_GreenLinePointLen = 0;//p = 0;for (m = 2;m < g_CommandLen;) {tempNum = atoi(argv[i] + m);_itoa_s(tempNum, tempStr, 10, 10);g_GreenLinePoint[g_GreenLinePointLen] = tempNum;g_GreenLinePointLen++;m += strlen(tempStr) + 1;}//将GreenPoint转化成二维矩阵for (m = 0;m < g_GreenLinePointLen / 2;m++)for (int n = 0;n < 2;n++) {g_GreenLine[m][n] = g_GreenLinePoint[p];p++;}break;default:cout << "format: cpath.exe /fInputFileName /sSourceNum /dDestNum /oOutputFileName" << endl;}}/*测试程序,可删除cout << "**********测试结果**********" << endl;cout <<"g_iFileName: "<< g_iFileName << endl;cout <<"g_oFileName: "<< g_oFileName << endl;cout <<"g_SourcePoint: "<< g_SourcePoint << endl;cout << "g_DestPoint: "<< g_DestPoint << endl;cout << "g_MaxNode: " << g_MaxNode << endl;cout << "g_TotalPoint: " << g_TotalPoint << endl;cout << "g_GreenPoint: " <<endl;cout << "g_GreenPointLen: " << g_GreenPointLen <<endl;for (int i = 0;i < g_GreenPointLen;i++)cout << g_GreenPoint[i] << " ";cout << endl;cout << "zhangbo" << endl;cout << "g_RedLinePointLen: " << g_RedLinePointLen << endl;for (int i = 0;i < g_RedLinePointLen;i++)cout << g_RedPoint[i] << " ";cout << endl;for (int i = 0;i < g_RedLinePointLen /2;i++)for(int j=0;j<2;j++)cout << g_RedLine[i][j] << " ";cout << endl;for (int i = 0;i < g_RedLinePointLen;i++)cout << g_GreenLinePoint[i] << " ";cout << endl;for (int i = 0;i < g_GreenLinePointLen / 2;i++)for (int j = 0;j<2;j++)cout << g_GreenLine[i][j] << " ";cout << endl;*///STEP2.构建邻接矩阵的数据结构//创建邻接图矩阵,并删除了红线create_adjmatrix();//STEP3.利用遗传算法求解问题GA();system("pause");return 0;}


原创粉丝点击