实验五、优先队列式分支限界法解装载问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验五优先队列式分支限界法解装载问题
09电信实验班I09660118 徐振飞
一、实验题目
实现书本P201所描述的优先队列式分支限界法解装载问题
二、实验目的
(1)掌握并运用分支限界法基本思想
(2)运用优先队列式分支限界法实现装载问题
(3)比较队列式分支限界法和优先队列式分支限界法的优缺点三、实验内容和原理
(1)实验内容
有一批共n个集装箱要装上2艘载重量分别为c1和c2的轮船,
其中集装箱i的重量为Wi,且∑
=
+
≤
n
i
i
c
c
w
1
2
1
,要求确定是否有一个合
理的装载方案可将这n个集装箱装上这2艘轮船。如果有,请给出方案。
(2)实验原理
解装载问题的优先队列式分支限界法用最大优先队列存储活结点表。活结点x在优先队列中的优先级定义为从根结点到结点x的路径所相应的载重量再加上剩余集装箱的重量之和。优先队列中优先级最大的活结点成为下一个扩展结点。优先队列中活结点x的优先级为x.uweight。以结点x为根的子树中所有结点相应的路径的载重量不超过x.uweight。子集树中叶结点所相应的载重量与其优先级相同。因此在优先队列式分支限界法中,一旦有一个叶结点成为当前扩展结
点,则可以断言该叶结点所相应的解即为最优解,此时终止算法。
上述策略可以用两种不同方式来实现。第一种方式在结点优先队列的每一个活结点中保存从解空间树的根结点到该活结点的路径,在算法确定了达到最优值的叶结点时,就在该叶结点处同时得到相应的最优解。第二种方式在算法的搜索进程中保存当前已构造出的部分解空间树,在算法确定了达到最优值的叶结点时,就可以在解空间树中从该叶结点开始向根结点回溯,构造出相应的最优解。在下面的算法中,采用第二种方式。
四、源程序
import parator;
import java.util.Iterator;
import java.util.PriorityQueue;
import java.util.Scanner;
public class test5 {
public void addLiveNode(PriorityQueue
bbnode b = new bbnode(E,ch);
HeapNode N = new HeapNode(b, wt, lev);
H.add(N);
}
public int maxLoading(int w[],int c,int n,boolean bestx[]){
PriorityQueue
/*生成最大堆*/
int[] r = new int[n+1];
r[n] = 0;
for(int j=n-1;j>0;j--){
r[j] = r[j+1] + w[j+1];
}
int i = 1;
bbnode E = new bbnode(null,false);
int Ew = 0;
while(i!=n+1){
if(Ew+w[i]<=c){
addLiveNode(H, E, Ew+w[i]+r[i], true, i+1);
}
addLiveNode(H, E, Ew+r[i], false, i+1);
HeapNode N;
N=H.poll();
i = N.level;
E = N.ptr;
Ew = N.uweight - r[i-1];
}
//构造最优解
for(int j=n;j>0;j--){
bestx[j] = E.Lchild;
E = E.parent;
}
return Ew;
}
public static void main(String[] args){
System.out.println("请输入物品总数:");
Scanner sc1 = new Scanner(System.in);
int n = sc1.nextInt();
int[] w = new int[n+1];
System.out.println("请输入物品重量:");
Scanner sc2 = new Scanner(System.in);
for(int i=1;i<=n;i++){
w[i] = sc2.nextInt();
}
System.out.println("请输入箱子重量:");
Scanner sc3 = new Scanner(System.in);
int c1 = sc3.nextInt();
int c2 = sc3.nextInt();
boolean[] bestx = new boolean[100];
test5 t = new test5();
//处理第一个箱子
System.out.println("first:"+t.maxLoading(w, c1, n, bestx));
System.out.print("可装重为:");
int count = 0;
for(int i=1;i<=n;i++){
if(bestx[i]){
count++;
System.out.print(w[i]+" "); /*输出一个可行方案*/ }
}
System.out.println();
/*处理第二个箱子*/
int m = n - count;