最短路径问题

最短路径问题

已知无向网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

运行结果

部分代码展示




  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值