当前位置:   article > 正文

算法与程序设计(六):分支限界法_分支限界法单源最短路径代码和运行结果c语言

分支限界法单源最短路径代码和运行结果c语言

目录

一、概念

1.1 分支限界法的基本思想

1.2 分支限界法与回溯法的不同

1.3 分支限界法的搜索方式

1.4 常见的两种分支限界法

二、举例

2.1 单源最短路径问题

三、代码实现

3.1 源程序

3.2 运行结果


一、概念

1.1 分支限界法的基本思想


1.2 分支限界法与回溯法的不同


1.3 分支限界法的搜索方式


1.4 常见的两种分支限界法


二、举例

2.1 单源最短路径问题

下图是用优先队列式(FIFO)分支限界法解有向图G的单源最短路径问题的解空间树;其中,每一个结点旁边的数字表示该结点所对应的当前路长。

找到一条路径:

目前的最短路径是8,一旦发现某个结点的下界不小于这个最短路径,则剪枝:

同一个结点选择最短的到达路径:

剪枝的策略:

1、在算法扩展结点的过程中,一旦发现一个结点的下界不小于当前找到的最短路长,则算法剪去以该结点为根的子树。

2、在算法中,利用结点间的控制关系进行剪枝。从源顶点s出发,2条不同路径到达图G的同一顶点。由于两条路径的路长不同,因此可以将路长较长的路径所对应的树中的结点为根的子树剪去。

最终结果:

所以从源顶点到终点的最短路径值为8,最短路径为:0 2 6 9 10。


三、代码实现

3.1 源程序

  1. package SufaLjh.Exp1.Homework_8.Day_6_11;
  2. import SufaLjh.Exp1.Homework_8.Day_6_11.tool.Heap;
  3. import SufaLjh.Exp1.Homework_8.Day_6_11.tool.HeapNode;
  4. /**
  5. * 分支限界法求单源最短路径问题
  6. */
  7. public class E2 {
  8. //定义变量
  9. int heapsize = 0,n=10,inf = 1000;//inf 表示距离为无穷
  10. int c[][] = new int[11][11],dist[]=new int[11],prev[]=new int[11];
  11. /**
  12. * 主方法 程序入口
  13. * @param args
  14. */
  15. public static void main(String[] args) {
  16. new E2();
  17. }
  18. public E2(){
  19. for (int i = 0; i <= n; i++) {
  20. for (int j = 0; j <= n; j++)c[i][j] = inf;
  21. dist[i]=inf;
  22. }
  23. c[0][1]=2;c[0][2]=3;c[0][3]=4;
  24. c[1][2]=3;c[1][4]=7;c[1][5]=2;
  25. c[2][5]=9;c[2][6]=2;
  26. c[3][6]=2;c[4][7]=1;c[4][8]=2;c[5][6]=1;c[5][8]=3;
  27. c[6][8]=5;c[6][9]=1;c[7][10]=2;c[8][10]=2;
  28. c[9][8]=2;c[9][10]=2;
  29. Shostestpaths(0,10);
  30. System.out.printf("从源点到最后一个点的最短路径的值为:%d\n",dist[10]);
  31. print(10);
  32. }
  33. /**
  34. * 分支限界法
  35. * @param v 源点
  36. * @param end 终点
  37. */
  38. private void Shostestpaths(int v,int end){
  39. Heap heap = new Heap();
  40. HeapNode E = new HeapNode(),N = new HeapNode();
  41. E.i=v;E.d=0;
  42. dist[v]=0;
  43. while (true){
  44. for (int j = 1; j <= n; j++) {//找当前节点(下标为E,i)的所有儿子节点
  45. //int d=E.d+c[E.i][j];
  46. //if (c[E.i][j]<inf&&d<dist[j]&&d<dist[end])
  47. if (c[E.i][j]<inf&&E.d+c[E.i][j]<dist[j]&&E.d<dist[end]){
  48. dist[j]=E.d+c[E.i][j];//更新到第j个顶点的最短距离
  49. prev[j]=E.i;//取到第j个顶点的最短距离时,第j个顶点的前一个顶点为E.i
  50. N.i=j;N.d=dist[j];//给堆的新节点赋值
  51. N.key=N.d;//用最短距离作为堆中关键值
  52. heap.minHeapInsert(N);//将所有节点插入堆中
  53. }
  54. }
  55. E=heap.minHeapDelete();//取出堆顶元素作为当前节点
  56. if (E.key==-1)break;//堆为空时退出
  57. }
  58. }
  59. /**
  60. * 打印输出的方法
  61. * @param v 源点
  62. */
  63. private void print(int v) {
  64. int t[] = new int[11];
  65. int i = v,j=0;
  66. while (i>0){
  67. t[j++]=i;i=prev[i];
  68. }
  69. t[j]=0;
  70. System.out.printf("最短路径为:");
  71. for (; j >= 0; j--) {
  72. System.out.printf("%d ",t[j]);
  73. }
  74. }
  75. }
  76. 定义最大堆和最小堆的类文件Heap.java:
  77. package SufaLjh.Exp1.Homework_8.Day_6_11.tool;
  78. //大顶堆
  79. public class Heap {
  80. int heapsize=0;//堆的大小
  81. HeapNode A[]=new HeapNode[1000];//存放堆的数组
  82. /**
  83. * 主方法
  84. * @param args
  85. */
  86. public static void main(String[] args) {
  87. new Heap();
  88. }
  89. /*public Heap(){
  90. }*/
  91. /**
  92. * 构造器
  93. */
  94. public Heap() {
  95. for(int i=0;i<1000;i++)A[i]=new HeapNode();
  96. /*System.out.println("小顶堆:");
  97. //System.out.println("大顶堆: ");
  98. for (int i = 0; i < 10; i++) {
  99. HeapNode heapNode = new HeapNode();
  100. heapNode.key = i;
  101. //maxHeapInsert(heapNode);
  102. minHeapInsert(heapNode);
  103. }*/
  104. //HeapNode E = maxHeapDelete();
  105. HeapNode E = minHeapDelete();
  106. while (E.key!=-1){
  107. System.out.println(E.key+" ");
  108. //E=maxHeapDelete();
  109. E=minHeapDelete();
  110. }
  111. }
  112. //大顶堆插入
  113. public void maxHeapInsert(HeapNode a) {
  114. heapsize++;
  115. int i = heapsize;
  116. while (i > 1 && A[i / 2].key < a.key) {
  117. A[i].clone(A[i/2]);
  118. i=i/2;
  119. }
  120. A[i].clone(a);
  121. }
  122. //大顶堆返回堆顶元素
  123. public HeapNode maxHeapDelete() {
  124. if (heapsize < 1) {
  125. A[0].key = -1;
  126. A[0].i = 0;
  127. return A[0];
  128. }
  129. HeapNode max = new HeapNode();
  130. max.clone(A[1]);
  131. A[1].clone(A[heapsize]);
  132. heapsize--;
  133. maxHeapify(1);//堆化
  134. return max;
  135. }
  136. //大顶堆堆化
  137. public void maxHeapify(int i) {
  138. int L, R, max;
  139. L = 2 * i;
  140. R = 2 * i + 1;
  141. if (L <= heapsize && A[L].key > A[i].key)
  142. max = L;
  143. else
  144. max = i;
  145. if (R <= heapsize && A[R].key > A[max].key)
  146. max = R;
  147. if (max != i) {
  148. HeapNode t = new HeapNode();
  149. t.clone(A[i]);A[i].clone(A[max]);A[max].clone(t);
  150. maxHeapify(max);
  151. }
  152. }
  153. //小顶堆
  154. public void minHeapInsert(HeapNode a)
  155. {
  156. heapsize++;
  157. int i=heapsize;
  158. while(i>1&&A[i/2].key>a.key)
  159. {
  160. A[i].clone(A[i/2]);
  161. i=i/2;
  162. }
  163. A[i].clone(a);
  164. }
  165. public HeapNode minHeapDelete()
  166. {
  167. if(heapsize<1){A[0].key=-1;return A[0];}
  168. HeapNode min=new HeapNode();
  169. min.clone(A[1]);
  170. A[1].clone(A[heapsize]);
  171. heapsize--;
  172. minHeapify(1);
  173. return min;
  174. }
  175. //小顶堆堆化
  176. public void minHeapify(int i)
  177. {
  178. int L,R,min;
  179. L=2*i;
  180. R=2*i+1;
  181. if(L<=heapsize&&A[L].key<A[i].key) min=L;
  182. else min=i;
  183. if(R<=heapsize&&A[R].key<A[min].key) min=R;
  184. if(min!=i)
  185. {
  186. HeapNode t=new HeapNode();
  187. t.clone(A[i]);A[i].clone(A[min]);A[min].clone(t);
  188. minHeapify(min);
  189. }
  190. }
  191. }
  192. 定义堆节点的类文件HeapNode.java:
  193. package SufaLjh.Exp1.Homework_8.Day_6_11.tool;
  194. public class HeapNode {
  195. public int ew,wt,i,x,key,d;
  196. public double p, up;
  197. public void clone(HeapNode t) {
  198. this.i=t.i;
  199. this.ew=t.ew;
  200. this.wt=t.wt;
  201. this.x=t.x;
  202. this.p=t.p;
  203. this.up=t.up;
  204. this.key=t.key;
  205. this.d=t.d;
  206. }
  207. }

3.2 运行结果


算法与程序设计的复习嘻嘻嘻蟹蟹٩('ω')و 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/629988
推荐阅读
相关标签
  

闽ICP备14008679号