贪心算法之装箱问题

贪心算法解决装箱问题
本文介绍了如何使用贪心算法解决装箱问题。贪心准则包括每一步选择最优解且不可中途改变。问题描述是将n个不同体积的物品装入体积为V的箱子中,目标是最小化箱子数量。通过将物品按体积降序排列,每次尝试将最大体积的物品放入已打开的箱子,以此达到优化目标。

贪心准则:1.贪心准则设计算法过程的每一步都是最优解

                 2.贪心准则一旦被设计,中途不可改变

装箱问题:

    问题描述:

            1.有若干个体积为V的箱子

            2.有n个物品,体积分别为:V1,V2,V3…………

            要求:将所有物品都装入箱子中,使箱子尽可能的少

    贪心准则:

            1.将所有物品按照体积降序排列

            2.每次取出一个物品(当前未装入箱子中体积最大的)遍历所有已经打开的箱子,将该物品放入一个较早打开的箱子中

#include<stdio.h>
#include<stdlib.h>
#define V 35
#define N 5
//物品信息
typedef struct{
	int gnum;//物品编号 
	int gv;//物品体积 
}ElemG; 

//物品结点 
typedef struct node{
	int gnum;
	struct node *next;
}GoodsLink; 

//箱子结点
typedef struct box{
	int remainder;  //用来存放剩余体积
	GoodsLink *hg;
	struct box *next; 
}BoxLink;
ElemG *CreateG();
ElemG *BuddleSont(ElemG *g);
BoxLink * Enchase(ElemG *g);
void Print(BoxLink *hbox);


int main(void)
{
	ElemG *g;
	BoxLink *hbox;
	g = CreateG();
	g = BuddleSont(g);
	hbox = Enchase(g);
	Print(hbox);	
}
//创建物品信息数组,然后初始化 
ElemG *CreateG()
{
	ElemG *g;
	int vol = 0; 
	g = (ElemG*)malloc(N*sizeof(ElemG));
	for(int i = 0; i<N; i++)
	{
		g[i].gnum = i+1;
		printf("请输入体积:");
		scanf("%d",&vol);
		g[i].gv = vol;
	}
	return g;
}
//将所有的物品按体积降序排列 
ElemG* BuddleSont(ElemG *g)
{
	int i,j;
	ElemG t;
	int tag = 1;  //标志变量 
	for(i = 0; tag&&i<N-1; i++)
	{
		
		tag = 0;
		for(j = N-1; j>i; j--)
		{
			if(g[j-1].gv<g[j].gv)
			{
				t = g[j-1];
				g[j-1] = g[j];
				g[j] = t;
				tag = 1;
			}
		}
	}
	return g;
}

//装箱子 
BoxLink* Enchase(ElemG *g)
{
	BoxLink *p,*hbox = NULL,*tail; 
	GoodsLink *newGoods,*q; 
 
	for(int i = 0; i<N; i++)
	{
		//遍历箱子链 
		for(p = hbox; p&&p->remainder<g[i].gv; p = p->next);
		if(!p){
			//创建箱子 
			p = (BoxLink*)malloc(sizeof(BoxLink));
			//初始化箱子
			p->remainder = V;
			p->next = NULL;
			p->hg = NULL;
			//挂箱子	
			if(!hbox){
				hbox = tail = p;
			} 
			else{
				tail = tail->next = p;
			}
		}
		p->remainder -=g[i].gv;
		//放物品
		newGoods = (GoodsLink*)malloc(sizeof(GoodsLink));
		newGoods->gnum = g[i].gnum;
		newGoods->next = NULL;
		if(!p->hg){  //新箱子 
			p->hg = newGoods;
		}
		else{  //旧箱子    
			for(q=p->hg;q->next;q = q->next);
				q->next = newGoods;
		}
	}
	return hbox;
}

void Print(BoxLink *hbox)
{
	BoxLink *p;
	GoodsLink *q;
	int cut = 0;
	for(p = hbox; p; p = p->next)
	{
		printf("第%d个箱子",++cut);
		for(q = p->hg; q; q = q->next)
			printf("存放编号为%d的物品,",q->gnum);
		printf("\n");
	}
}

            

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值