算法數據結構之貪心算法

貪心算法
貪心算法是一種不追求最優解,只想得到較爲滿意的解的方法,貪心法一般可以快速得到較爲滿意的解,因而省去了爲了找到最優解而要窮盡所有可能必須耗費的大量時間.貪心算法常以當前情況爲基礎做出最優選擇,而不需要考慮各種可能的整體情況,所以貪心算法不需要回溯!

  1. 貪婪準則
    ①、算法的每一步都要求最優解(即局部最優)
    ②、貪婪準則一旦設定好,中途不能改變
  2. 貪婪準則並不一定可以獲得絕對最優解,只是局部最優

貪心算法之裝箱問題
  • 問題描述:
    裝箱問題:
    A>.有若干個體積爲V的箱子
    B>.有n個物品,v0,v1,v2… …vn,體積互不相同
    要求:將所有的物品都裝入箱子裏,使打開的箱子儘可能的少
  • 設置貪心準則
    I、將所有的物品按照體積降序排列
    II、每次取出一個物品(爲當前未裝箱的體積最大的),遍歷所有已經打開的箱子,將該物品裝入一個較早打開的箱子
    III、如果都裝不下,就打開一個新箱子裝入物品

  • 這是存儲示意圖

這裏寫圖片描述


  • 類型聲明
//聲明物品信息
typedef struct{
    int gnum;//物品編號
    int gv;//物品體積
}ElemG;
//物品節點
typedef struct node{
    int gnum;//物品編號
    struct node *link;//這是放入箱子的物品的指針
}GoodsLink;
//聲明箱子的類型
typedef struct box{
    int Rem;
    struct box *next;//這是箱子的指針
    GoodsLink *hg;//這是箱子中放入物品的頭指針
}BoxLink;//這是箱子的指針

  • 具體代碼實現 :

#include<iostream>
#include<iomanip>
using namespace std;

#define N 10                    //物品數量
#define V 50                    //箱子容積

                                //聲明物品信息
typedef struct{
    int gnum;                   //物品編號
    int gv;                     //物品體積
}ElemG;

                                //物品節點
typedef struct node{
    int gnum;                   //物品編號
    struct node *link;          //這是放入箱子的物品的指針
}GoodsLink;

                                //聲明箱子的類型
typedef struct box{
    int Rem;
    struct box *next;           //這是箱子的指針
    GoodsLink *hg;              //這是箱子中放入物品的頭指針
}BoxLink;                       //這是箱子的指針

//插入排序算法
void InsertSort(ElemG *g)
{       
    int i,j;
    ElemG x;
    for(i =1;i<N;i++)
    {
        if(g[i].gv>g[i-1].gv)
        {
            x= g[i];
            j= i-1;
            while(x.gv>g[j].gv)
            {
                g[j+1]=g[j];
                j--;
                if(!(j+1)) break;
            }
            g[j+1]= x;          //將原來那個g[i]放到前面某處那個剛好比自己大的單元后面
        }
    }
}

//裝箱程序
void packingBox(ElemG * g)
{
    GoodsLink *q,*newg;
    int i,j;
    BoxLink *p,*hbox,*tail;
    hbox= tail= NULL;
    for(i=0;i<N;i++)
    {
        for(p= hbox;p&&p->Rem<g[i].gv;p=p->next);//遍歷所有箱子,遍歷到尾部或者遍歷到能放下物品的那個箱子停下
        if(!p){
            p= (BoxLink *)malloc(sizeof(BoxLink));//如果遍歷到尾部,就打開一個新箱子放g[i]
            p->Rem=V;
            p->hg=NULL;
            p->next=NULL;
            if(!hbox) hbox=tail=p;      //如果還未打開任何箱子,就打開一個P放在hbox 後面
            else tail=tail->next=p;     //否則,將p掛到尾節點
    }
            p->Rem-=g[i].gv;            //箱子的剩餘空間減去放入的物品的體積
        newg= (GoodsLink *)malloc(sizeof(GoodsLink));
        newg->gnum= g[i].gnum;
        newg->link= NULL;
        for(q=p->hg;q&&q->link;q=q->link);
        if(!q)
            p->hg= newg;
        else 
            q->link= newg;
    }

    //輸出放置好物品的箱子鏈
    for( j =1,p= hbox;p;p=p->next,j++)
    {
        cout<<"輸出箱子編號:"<<j;
        for(q=p->hg;q;q=q->link)
            cout<<"_________"<<"輸出物品鏈:"<<q->gnum<<"_";
        cout<<"輸出箱子剩餘體積:"<<p->Rem<<";↓"<<endl;
    }
}

int main(void)
{
    ElemG g[N];
    int val;
    cout<<"_____________________________________________________<請輸入十個物品的體積>_____________________________________________________"<<endl;
    for(int ii= 0; ii<N;ii++)
    {
        g[ii].gnum= ii+1;           //編號從1開始,到10
        cin>>val;
        g[ii].gv= val;
    }
    cout<<"_____________________________________________________<十個物品體積輸入完成>_____________________________________________________"<<endl;
    cout<<"_____________________________________________________<輸出剛纔所輸物品信息>_____________________________________________________"<<endl;
    for(int k=0;k<N;k++)
        cout<<"物品編號:"<<g[k].gnum<<"___"<<setw(15)<<"物品體積:"<<setw(3)<<g[k].gv<<">>>"<<endl;
    //對輸入物品按照降序排序
    InsertSort(g);          
    cout<<"_____________________________________________________<輸出排序完成物品信息>_____________________________________________________"<<endl;
    for(k=0;k<N;k++)
        cout<<"物品編號:"<<g[k].gnum<<"___"<<setw(15)<<"物品體積:"<<setw(3)<<g[k].gv<<">>>"<<endl;
    packingBox(g);                  //裝箱程序
    return 0;
}

這裏寫圖片描述

發佈了31 篇原創文章 · 獲贊 17 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章