贪婪准则:局部最优。贪婪准则一旦确定,中通不能改变。
贪婪算法不一定能找到最优解,但可以近似最优解
经典问题:装箱问题
1.问题描述
有若干个体积为V的箱子。有N个物品,物品的体积分别为V1,V2直到VN。将所有的物品装入箱子,使打开的箱子尽可能的少。
2.贪婪准则:
(1)将物品按体积大小降序排列
(2)每一次取出的物品是未装入箱子中体积最大的
(3)遍历已经打开的箱子,将物体放入第一个可以放入的箱子
分析:
创建两个链表,一个存储打开的箱子,一个存储每个箱子中存储的物品。创建一个结构体以存储物品信息。
代码实现
#include <stdio.h>
#include <stdlib.h>
#define V 10
//物品信息结构体
typedef struct {
int gno;//物品编号
int gv;//物品体积
}ElemG;
//物品链节点
typedef struct node {
int gnu;//物品链上物品编号
struct node * link;//指向下一个物品节点
}GoodsLink;
//箱子链节点
typedef struct box {
int reminder;//箱子剩余空间
GoodsLink * hg;//指向物品链的第一个节点
struct box * next;
}BoxLink;
//对物品按体积进行降序排列
void SortG(ElemG * g, int n)
{
ElemG k;
int i, j;
for (i = 0; i < n - 1; i++)
{
for(j=i+1;j<n;j++)
{
if (g[i].gv < g[j].gv)
{
k = g[i];
g[i] = g[j];
g[j] = k;
}
}
}
}
//实现装箱
BoxLink * Packing(ElemG * g, int n)
{
BoxLink * hbox = NULL, *tail, *p;
GoodsLink * q, *newg;
for (int i = 0; i < n; i++)
{
for (p = hbox; p&&p->reminder < g[i].gv; p = p->next);
if (!p)
{
p = (BoxLink*)malloc(sizeof(BoxLink));
p->reminder = V;
p->hg = NULL;
p->next = NULL;
if (!hbox)
hbox = tail = p;
else
tail = tail->next = p;
}
p->reminder -= g[i].gv;
newg = (GoodsLink*)malloc(sizeof(GoodsLink));
newg->gnu = g[i].gno;
newg->link = NULL;
if (!p->hg)
p->hg = newg;
else
{
for (q = p->hg; p->next; p = p->next);
q->link = newg;
}
}
return hbox;
}
//输出
void PrintBox(BoxLink * h)
{
int i = 0;
BoxLink * p;
GoodsLink * q;
for (p = h; p; p = p->next)
{
printf("第%d个箱子",++i);
for (q = p->hg; q; q = q->link)
printf("%d", q->gnu);
printf("\n");
}
}
int main(void)
{
ElemG * g;
int w;
BoxLink * hbox;
int n;
//初始化物品信息
printf("请输入物品信息");
scanf("%d", &n);
g = (ElemG*)malloc(n * sizeof(ElemG));
for (int i = 0; i < n; i++)
{
g[i].gno = i + 1;
scanf("%d", &w);
g[i].gv = w;
}
//排序
SortG(g, n);
//装箱
hbox = Packing(g, n);
//输出
PrintBox(hbox);
return 0;
}