1、用分支定界算法求以下问题:某公司于乙城市的销售点急需一批成品,该公司成品生产基地在甲城市。甲城市与乙城市之间共有 n 座城市,互相以公路连通。甲城市、乙城市以及其它各城市之间的公路连通情况及每段公路的长度由矩阵 M1 给出。每段公路均由地方政府收取不同额度的养路费等费用,具体数额由矩阵 M2 给出。请给出在需付养路费总额不超过 1500 的情况下,该公司货车运送其产品从甲城市到乙城市的最短运送路线。具体数据参见文件:m1.txt: 各城市之间的公路连通情况及每段公路的长度矩阵(有向图); 甲城市为城市 Num.1,乙城市为城市 Num.50。m2.txt: 每段公路收取的费用矩阵(非对称) 。
2、思想:利用 Floyd 算法的基本方法求解。程序实现流程说明:1.将 m1.txt 和 m2.txt 的数据读入两个 5050 的数组。2.用 Floyd 算法求出所有点对之间的最短路径长度和最小费用。3.建立一个堆栈,初始化该堆栈。4.取出栈顶的结点,检查它的相邻的所有结点,确定下一个当前最优路径上的结点,被扩展的结点依次加入堆栈中。在检查的过程中,如果发现超出最短路径长度或者最小费用,则进行”剪枝” ,然后回溯。5.找到一个解后,保存改解,然后重复步骤 4。6.重复步骤 4、5,直到堆栈为空,当前保存的解即为最优解。时间复杂度分析:Floyd 算法的时间复杂度为 ,N 为所有城市的个数。3
3、()O该算法的时间复杂度等于 DFS 的时间复杂度,即 O(N+E)。其中,E 为所有城市构成的有向连通图的边的总数。但是因为采用了剪枝,会使实际运行情况的比较次数远小于 E。求解结果:算法所得结果:甲乙之间最短路线长度是:464最短路线收取的费用是:1448最短路径是:1 3 8 11 15 21 23 26 32 37 39 45 47 50C 源代码(注意把 m1.txt 与 m2.txt 放到与源代码相同的目录下, 下面代码可直接复制运行):#include#include#include#include#define N 50#define MAX 52void input(int
4、aNN,int bNN);void Floyd(int dNN);void fenzhi(int m1NN,int m2NN,int mindistNN,int mincostNN);int visitedN,bestPathN;void main()clock_t start,finish;double duration;int i,j,mindistNN,mincostNN,m1NN,m2NN; /* m1NN和 m2NN分别代表题目所给的距离矩阵和代价矩阵 */ int visitedN,bestPathN;FILE *fp,*fw;/ system(“cls“);time_t ttim
5、e;time(printf(“%s“,ctime(start=clock();for(i=0;i=0) /* 表示遍历开始和结束条件,开始时从甲城市出发,栈空,depth=0 ;结束时遍历完毕,所有节点均被出栈,故栈也为空,depth=0 */* 整个 while()循环体用来实现从当前的城市中寻找一个邻近的城市 */cur=stackdepth; /* 取栈顶节点赋值给 cur,表示当前访问到第 cur 号城市 */next=stackdepth+1; /* next 指向当前所处城市的上一个已经遍历的城市 */for(i=next+1;icostBound)|(currentDist+mi
6、ndistcurN-1=distBound) /* 所试探的城市满足剪枝条件,进行剪枝 */printf(“here1 %d %d %d %d %d %d %dn“,cur,currentCost,mincostcur49,costBound,currentDist,mindistcur49,distBound); getchar();/ printf(“%d %d %d %d %d %d“,cur,i,m1curi,currentCost,mincostcur49,costBound); getchar();continue;if(m1curi=9999) continue; /* 所试探的
7、城市不连通 */if(visitedi=1) continue; /* 所试探的城市已被访问 */if(i1500) continue; /* 如果当前找到的通路的代价之和大于 1500,则放弃这条通路 */printf(“最短路径:%3d,路径代价:%3d,所经历的节点数目:%3d, 所经历的节点如下:n“,shortestDist,minimumCost,bestLength+1); /* 输出找到的通路的结果 */bestPathbestLength=49;for(i=0;i=bestLength;i+) /* 输出所找到的通路所经过的具体的节点 */printf(“%3d “,bestPathi+1);printf(“n“);depth-; /* 连续弹出栈顶的两个值,进行回溯,开始寻找新的可行的通路 */currentDist-=m1stackdepthstackdepth+1;currentCost-=m2stackdepthstackdepth+1;visitedstackdepth+1=0;depth-;currentDist-=m1stackdepthstackdepth+1;currentCost-=m2stackdepthstackdepth+1;visitedstackdepth+1=0;/ getchar();