最短路径问题
已知无向网G=(V,E),V={A,B,C,D},E={(A,B,3),(B,C,6),(B,D,2),(A,D,8),(C,D,1)},请求出A顶点到D顶点的最短路径及距离,并提供解题思想和步骤。
第一种算法(Dijkstra算法)
算法思想:
(1)通过Dijkstra计算要指定起点s(即从指定s开始计算)
(2)引进两个集合S和U。S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求出最短路径的顶点(以及该顶点到起点s的距离)
(3)初始时,S中只有起点s;U中是除s之外的顶点,并且U中顶点的路径是”起点s到该顶点的路径”。然后,从U中找出路径最短的顶点,并将其加入到S中;接着,更新U中的顶点和顶点对应的路径。 然后,再从U中找出路径最短的顶点,并将其加入到S中;接着,更新U中的顶点和顶点对应的路径。 … 重复该操作,直到遍历完所有顶点
代码展示:
#include<stdio.h>
int main()
{ //采用邻接矩阵来存储图
int a[100][100],point,i,j,k,number,t1,t2,t3,u,v,min,book[10]={0},dis[10]
int inf=99999999; //假设这个数表示无穷大
scanf("%d %d\n",&point,&number);
for(i=1;i<=point;i++) //用a[1]来表示第一个顶点
for(j=1;j<=point;j++){
if(i==j){
a[i][j]=0;//初始化,当每个顶点到自身时,距离为0,否则为无穷大
}else{
a[i][j]=inf;
}
}
for(i=1;i<=number;i++){
scanf("%d %d %d",&t1,&t2,&t3);
a[t1][t2]=t3;
}
for(i=1;i<=point;i++){
dis[i]=a[1][i];
}
book[1]=1;//标记第一个顶点已经是最短距离
//Dijkstra算法开始
for(i=1;i<=point-1;i++){
min=inf;
for(j=1;j<=point;j++){ //求出当前最短的距离下标
if(book[j]==0 && dis[j]<min){
min=dis[j];
u=j;//记下这个点的下标
}
}
book[u]=1;
for(k=1;k<=point;k++){
if(a[u][k]<inf){
if(dis[k]>dis[u]+a[u][k]){
dis[k]=dis[u]+a[u][k];
}
}
} //若有更优距离,则替换掉
}
for(i=1;i<=point;i++){
printf("1号顶点到%d号顶点的最短距离为------>%d\n",i,dis[i]);
}
return 0;
}
第二种算法(遗传算法)
算法思想:遗传算法模拟一个人工种群的进化过程,通过选择、交叉以及变异等机制,在每次迭代中都保留一组候选个体,重复此过程,种群经过若干代进化后,理想情况下其适应度达到近似最优的状态。
算法流程图
分析
该题目类似于旅行商问题(TSP),既从一个城市出发,经过所有城市后又重新回到起始点,且每个城市有且只能访问一次,求最短路径。该题有四个顶点,任意两个顶点都有边,除了A–C之间没有边。根据题目的要求必须是从A点出发,终点是D,但并没有要求所有顶点都要经过,所以在初始化种群和得到最优解的时候,可以限制条件。
参数的设置
- 交叉概率:0.8
- 变异概率:0.8
步骤
(1)首先初始化种群
类似于二进制编码,将A、B、C、D四个顶点分别编码为:1、2、3、4。但起点是A,每个个体的第一维决策变量为1,第二维决策变量不能为3,其他决策变量是2、3、4的排列,这样每个个体就是一条路径。初始化种群大小为50个。
(2)评估种群的适应度值
计算每个个体的适应度值,即计算每条路径的长度
(3)选择
选择操作就是用来确定如何从父代群体中按某种方法选取那些个体,以便遗传到下一代群体。选择用来确定重组或交叉个体,以及被选个体将产生多少个子代个体。
采用轮盘赌的方式选择
选择流程:
1、将所有适度值相加,计算适度值比例,即每个个体的选择概率
2、计算每个个体的累积概率,第i个个体的累积概率就是前i项选择概率之和
3、随机生成r∈[0,1],若 qi>r,则选择个体xi
(4)交叉
遗传算法的交叉操作是指对两个相互配对的染色体按某种方式相互交换其部分基因,从而形成两个新的个体。
例如
1234
1423
交叉位置为2
则交叉后个体为
1434
1223
(5)变异
遗传算法的变异操作是指将个体染色体编码串中的某些基因座上的基因值用该基因座上的其它等位基因来替换,从而形成新的个体。
1423
变异位置为2,3
变异后个体为
1243
运行结果
部分代码展示