1.算法设计
一.回溯法是一个搜索了所有的解空间的算法,在搜索的过程中通过具体问题条件不断选优判断,最后达到一个合适的目标或者全部搜索仍无想要的答案。它是通过分步的方法进行搜索,当当前这一步无法达到目标解,就回退一步,尝试其他的路径就像搜索目标解,这个搜索的过程就叫做回溯法。
在本题中搜索所有集装箱装载的方法,在这过程中当满足不超过容量且在相等重量时,取装载集装箱个数少的装载,此为本提的搜索所有解空间的选优判断。
体现在在程序中为:
void dfs(int a [],int M,int n,int i,int tw,int count,int invisible []){ //此方法
int j;
if(i>n){
if(tw <= M && ( tw > maxW || (tw == maxW && count < countMin))){ //两层判断:
countMin = count; // 1: 当当前容量不超过最大值,但是
maxW = tw; //又比最佳容量大时,条件成立,执行if语句主题代码
for(j = 1; j <= n; j++){ // 2: 当当前容量不超过最大值,由于最
x[j] = invisible[j]; //佳容量相等时,而且装载集装箱次数要小于最佳装
} //载集装箱次数,同样执行IF语句主题代码
}
}else{
if(tw + a[i] < M){ //左剪枝
invisible[i] = 1;
dfs(a,M,n,i+1,tw+a[i-1],count+1,invisible);
}
invisible[i] = 0;
if(count <= 2){ //右剪枝 ,当count小于等于2,装载集装箱个数大于等于3时,才执行if语句主体
dfs(a,M,n,i+1,tw,count,invisible);
}
}
}
2.程序清单
#include <stdio.h>
#define MAXN 20
int countMin = 65535; //设置装载次数的最大值
int maxW; //设置最佳不超过装载容量的最大重量
int x [MAXN];//设置都有哪些集装箱被装上
void dfs(int a [],int M,int n,int i,int tw,int count,int invisible []){ //此方法
int j;
if(i>n){
if(tw <= M && ( tw > maxW || (tw == maxW && count < countMin))){ //两层判断:
countMin = count; // 1: 当当前容量不超过最大值,但是
maxW = tw; //又比最佳容量大时,条件成立,执行if语句主题代码
for(j = 1; j <= n; j++){ // 2: 当当前容量不超过最大值,由于最
x[j] = invisible[j]; //佳容量相等时,而且装载集装箱次数要小于最佳装
} //载集装箱次数,同样执行IF语句主题代码
}
}else{
if(tw + a[i] < M){ //左剪枝
invisible[i] = 1;
dfs(a,M,n,i+1,tw+a[i-1],count+1,invisible);
}
invisible[i] = 0;
if(count <= 2){ //右剪枝 ,当count小于等于2,装载集装箱个数大于等于3时,才执行if语句主体
dfs(a,M,n,i+1,tw,count,invisible);
}
}
}
void disp(int n){ //输出装载情况
int j;
printf("要装入的集装箱:");
for(j = 1; j <= n; j++){
if(x[j] == 1)
printf("%d ",j);
}
printf(" 装入的集装箱个数:%d",countMin);
}
int main(){
int n = 5;
int W = 10;
int a [] = {5,2,6,4,3};
int invisible[MAXN];
df(a,W,n,1,0,0,invisible);
disp(n);
}
3.运行结果