贪心算法 之 装箱问题

贪心算法  之  装箱问题(可得到最优解的近似解)

1.贪婪准则:
1>贪婪准则设计算法的每一步的最优解(局部最优)
2>贪心准则一旦设好,中途不变
2.贪婪准则并不一定能得到最优解:

装箱问题:
有若干个体积为V的箱子;
有N个物品体积为:v0,v1,v2,v3…….
要求:
将所有的物品装入箱子中,使得打开的箱子最少;

贪婪准则:
1.将所有物品按照体积降序排列;
2.每次取出一个物品(当前没有装入箱子的体积最大的);
3.遍历所有已打开的箱子,放入一个较早打开的箱子,如果放不下便开一个新箱子;

实现(由伪代码描述):
1.存储:

2.类型声明:

物品信息:

typedef struct{             
int gnum;  //物品编号
int gv;      //物品体积
}ElemG;

物品信息集合:假设有n个物品;

ElemG  *g;
g=(ELemG *)malloc(n*sizeof(ElemG));

物品信息初始化:
for(int i;i<n;i++){

}
物品节点:

typedef struct node{
int gnum;
struct node *link;
}Goods;
箱子节点:

typedef struct box{
int Remainder;
struct Goods *
struct box *next;
}

算法描述:
1.创建物品信息数组,并初始化;
2.将所以有物品按体积降序排列;
3.装箱;
4.输出;

装箱:
遍历所有已排序的数组;
for(i=0;i<n;i++){

}
for(p=hbox;p&&p->remainder<g[i].gv;p=p->next);   遍历箱子链表
//跑完后,得到要放入的箱子;
if(!p){            //p为^,则需要打开新箱子;(正向建链)
创建箱子节点,初始化箱子。(注意放入第一个箱子的分支)
}
放入物品{
建物品节点;
if(是新箱子){

}
else{
for(q=p->hg;q->next;q=q->next;    //找到箱子链表的最后
}
}
代码实现:c代码

/*
装箱问题:
有若干个体积为V的箱子;
有N个物品体积为:v0,v1,v2,v3.......
要求:
将所有的物品装入箱子中,使得打开的箱子最少;
*/

#include <stdio.h>
#include <stdlib.h>

typedef struct{             //物品信息
 int Goodsnum;
 int gv;
}Goods;

typedef struct nod{                    //物品结点
 int Goodsnum;
 struct nod *next;
}Goodnode;

typedef struct node{                  //箱子结点
 int boxv;
 Goodnode *goodlink;
 struct node *next;
}Boxnode;



void print (Goods *a, int n);
void getgoods(Goods *a,int n);
void Sortd (Goods *a,int n);
Boxnode* Putgoods (Goods *a,int n);
void printbox (Boxnode *boxs);

int main (void){
 double n=50;
 Boxnode *boxs;
 Goods* a=(Goods*)malloc(10*sizeof(Goods));
 getgoods(a,10);
 print(a,10);
 Sortd(a,10);
 print(a,10);
 boxs=Putgoods(a,10);
 printbox(boxs); 
}

void getgoods (Goods *a,int n){         //输入物品数组
 printf("请输入物品信息:");
 for(int i=0;i<n;i++){
  scanf("%d",&a[i].gv);
  a[i].Goodsnum=i+1;
 }
}

void Sortd (Goods *a,int n){               //将物品数组按物品的体积排序
 Goods t;
 for(int i=0;i<n;i++){
  for(int j=i+1;j<n;j++){
   if(a[i].gv<a[j].gv){
    t=a[i];
    a[i]=a[j];
    a[j]=t;
   }
  }
 }
}

Boxnode* Putgoods (Goods *a,int n){
 Boxnode *boxs=NULL,*p,*tail;
 Goodnode *gi,*g;                        //gi用来跑链表     g用来分配单元做节点
 for(int i=0;i<n;i++){    //i遍历物品数组
  for(p=boxs;p&&p->boxv<a[i].gv;p=p->next);               //得到需要放入的箱子p
  if(!p){    //需要打开新箱子的情况
   p=(Boxnode*)malloc(sizeof(Boxnode));           //创建箱子结点
   p->next=NULL;
   p->goodlink=NULL;
   p->boxv=50;
   if(!boxs) {    //需要打开第一个箱子的情况
    boxs=tail=p;
   }
   else{
    tail=tail->next=p;         //挂尾链  挪尾指针
   }
  }
  p->boxv-=a[i].gv;                   //放入物品,体积减小
  for(gi=p->goodlink;gi&&gi->next;gi=gi->next);       //遍历物品链表,得到要挂链的位置gi或gi->next
  g=(Goodnode*)malloc(sizeof(Goodnode));              //创建了物品结点
  g->Goodsnum=a[i].Goodsnum;
  g->next=NULL;
  if(!gi){       //如果物品链表不存在
   p->goodlink=g;
  }
  else{
   gi->next=g;
  }
 }
 return boxs;
}

void printbox (Boxnode *boxs){
 Boxnode *i;
 Goodnode *j;
 int cnt=1;
 for(i=boxs;i;i=i->next,cnt++){
  printf("这是第%d个箱子:\t",cnt);
  for(j=i->goodlink;j;j=j->next){
   printf("%d\t",j->Goodsnum);
  }
  printf("\n");
 }
}

void print (Goods *a,int n){
 printf("物品信息表:\t");
 for(int i=0;i<n;i++){
  printf("%d,%d\t",a[i].Goodsnum,a[i].gv);
 }
 printf("\n");
}

 

    原文作者:贪心算法
    原文地址: https://blog.csdn.net/zuo_h_dr/article/details/81167466
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞