贪心算法
一、概念:
贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
二、贪婪准则:
(1)贪婪准则设计算法过程的每一步的最优解(局部最优)
(2)贪婪准则一旦设计,中途不改变
(3)贪婪准则不一定得到最优解
三、应用举例
例:装箱问题
1.问题描述:有若干个体积为V的箱子。有n个物品,体积分别为V1…Vn。要求:将所有物品都装入箱子中,使打开的箱子尽可能少
2.设计贪心准则:
(1)将所有物品按体积降序排列
(2)每次取出一件物品(当前未装入箱子的且体积最大的),遍历所有已打开的箱子,若该箱子容量足够放入该物品,则将该物品放入其中
(3)目的:把较早的箱尽量先填满
3.存储方式:链表
4.代码实现
#include<stdio.h>
#include<stdlib.h>
#define V 20//设置箱子容量的值
#define N 10//设置存放的物品总件数
//物品信息
typedef struct{
int gno;//物品编号
int gv;//物品体积
}GoodsMsg;
//物品结点
typedef struct goods{
int gno;
int gv;
struct goods*next;//下一个物品的地址
}GoodsLink;
//箱子结点
typedef struct box{
int remainder;//箱子剩余容量
GoodsLink * ghead;//物品指针
struct box * next;//下一个箱子的地址
}BoxLink;
//将物品按体积降序排列 (这里我用了冒泡排序)
void SortGoodsDesc(GoodsMsg * gm){
int i,j;
int tag = 1;
for(i=0;i<N-1&&tag;i++){
tag = 0;
for(j=N-1;j>i;j–){
if(gm[j].gv>gm[j-1].gv){
GoodsMsg t = gm[j];
gm[j] = gm[j-1];
gm[j-1] = t;
tag = 1;
}
}
}
printf("#物品入箱顺序:\n");
for(i=0;i<N;i++){
printf("物品[编号:%d\t体积:%d]\n",gm[i].gno,gm[i].gv);
}
}
BoxLink* Encasement(GoodsMsg * gm,BoxLink * bhead){
//装箱
int i;
BoxLinkb,btail;
GoodsLinkg,p;
for(i=0;i<N;i++){
//遍历箱子链
for(b=bhead;b&&b->remainder<gm[i].gv;b=b->next);
if(!b){//创建并初始化箱子结点
b = (BoxLink)malloc(sizeof(BoxLink));
b->remainder = V;
b->ghead = NULL;
b->next = NULL;
//挂箱子
if(!bhead)bhead = btail = b;
else btail = btail->next = b;
}
//放物品
b->remainder-=gm[i].gv;//记录剩余容量
//创建并初始化物品结点
g = (GoodsLink)malloc(sizeof(GoodsLink));
g->gno = gm[i].gno;
g->gv = gm[i].gv;
g->next = NULL;
if(!b->ghead){
//是新箱子(新箱子里没有物品,所有其物品指针是空的)
b->ghead = g;
}else{
//是旧箱子
for(p=b->ghead;p->next;p=p->next);//查找物品结点的位置
p->next = g;
}
}
return bhead;
}
//输出箱子的存储情况
void printBoxMsg(BoxLink * bhead){
BoxLink * p;
GoodsLink*q;
int cnt=1;
printf("#储物箱存储信息:\n");
for(p=bhead;p;p=p->next){
printf("箱子%d:",cnt++);
for(q=p->ghead;q;q=q->next){
printf("物品[编号:%d,体积:%d]\t",q->gno,q->gv);
}
printf("\n");
}
}
int main(void){
//13 12 15 8 4 17 6 9 11 3
int i;
BoxLink * bhead = NULL;
GoodsMsg * gm = (GoodsMsg*)malloc(N*sizeof(GoodsMsg));
for(i=0;i<N;i++){
gm[i].gno = i+1;
printf(“请输入第%d件物品的体积:”,i+1);
scanf("%d",&gm[i].gv );
}
SortGoodsDesc(gm);
bhead = Encasement(gm,bhead);
printBoxMsg(bhead);
}
运行结果如下: