背包问题实验报告(C语言实现、文件输入及文件输出)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
背包问题
实验题目:背包问题
问题描述:假设有一个能装入总体积为T的背包和n件体积分别为w
1, w
2, … , w
n的物品,能否从n件物品中挑选若干件恰好装满背包,即使w
1+w
2+…+ w
n=T,要求找出所有满足上述条件的解。
例如:当T=10,各件物品的体积{1,8,4,3,5,2}时,可找到下列4组解:(1,4,3,2)
(1,4,5)
(8,2)
(3,5,2)。
概要设计:
采用栈数据结构,利用回溯法的设计思想来解决背包问题。
首先将物品排成一列,然后顺序选取物品装入背包,假设已选取了前i件物品之后背包还没有装满,则继续选取第i+1件物品,若该件物品“太大”不能装入,则弃之而继续选取下一件,直至背包装满为止。但如果在剩余的物品中找不到合适的物品以填满背包,则说明“刚刚”装入背包的那件物品“不合适”,应将它取出“弃之一边”,继续再从“它之后”的物品中选取,如此重复,直至求得满足条件的解,或者无解。
ADT Stack {
数据对象:D={ ai | ai∈ElemSet, i=1,2,...,n,
n≥0 }
数据关系:R1={
约定an端为栈顶,a1端为栈底。
基本操作:
InitStack(&S)
操作结果:构造一个空栈S。
DestroyStack(&S)
初始条件:栈S已存在。
操作结果:栈S被销毁。
ClearStack(&S)
初始条件:栈S已存在。
操作结果:将S清为空栈。
StackEmpty(S)
初始条件:栈S已存在。
操作结果:若栈S为空栈,则返回TRUE,否则FALSE。StackLength(S)
初始条件:栈S已存在。
操作结果:返回S的元素个数,即栈的长度。GetTop(S, &e)
初始条件:栈S已存在且非空。
操作结果:用e返回S的栈顶元素。
Push(&S, e)
初始条件:栈S已存在。操作结果:插入元素e为新的栈顶元素。Pop(&S, &e)
初始条件:栈S已存在且非空。
操作结果:删除S的栈顶元素,并用e返回其值。
} ADT Stack
源代码:
#include
#include
#include
#include
#define OK 1
#define N 20
FILE *fp1,*fp2;//fp1指向数据文件,fp2指向结果文件
typedef struct SqStack{
int *base;
int *top;
int num;
}SqStack;
struct SqStack *S,L;
int InitStack(SqStack *s,int n){
s->base=(int *)malloc(n*sizeof(int)); if(!s->base) exit(0);
s->top=s->base;
s->num=0;
return OK;
}//创建栈
int Push(SqStack *s,int m){
*s->top++=m;
s->num++;
return OK;
}//元素入栈
int Pop(SqStack *s,int *p){
if(s->base==s->top)return 0;
--s->top;
*p=*s->top;
s->num--;
return OK;
}//元素出栈,用指针p返回
int print(SqStack *s,int w[]){
int *p;
p=s->base;
while(p
fprintf(fp2,"%d ",w[*p]);
printf("%d ",w[*p]);
p++;
}
fprintf(fp2,"\n");
printf("\n");
return OK;
}//把栈中元素在文件中输出和在屏幕上输出
int StackEmpty(SqStack *s){
if(s->base==s->top) return 0;
else return 1;
}//栈是否为空
void knapsack (int w[],int T,int n) {
//已知n件物品的体积分别为w[0], w[1],…, w[n],背包的总体积为T,//本算法输出所有恰好能装满背包的物品组合解
int k=0;//从第0件物品考察起
int pint=0;//计算输出结果组数,如果没有,则提示无结果
int *pk=&k;
S=&L;
InitStack(S,n);
if(Pop(S,pk)){//退出栈顶物品
T+=w[k];
k++;//继续考察下一件物品
}
while(T>0&&k if (T-w[k]>=0) {//第k件物品可选,则k入栈Push(S,k); T-=w[k]; } k++;//继续考察下一件物品 if(T==0) { print(S,w); pint++; }//输出第一组解 } } while ((StackEmpty(S))&&(k<=n));//while if(!pint){ fprintf(fp2,”未找到匹配结果”); printf(“未找到匹配结果”);