“裝箱”問題的貪婪法解決演算法

gudesheng發表於2008-01-03
/*
    標題:<<系統設計師>>應試程式設計例項-[遞推演算法程式設計]
    作者:成曉旭
    時間:2002年09月14日(18:20:00-20:18:00)
          實現“裝箱”問題的貪婪演算法實現函式
    時間:2002年09月14日(22:00:00-23:18:00)
          實現“裝箱”問題的貪婪演算法實現函式
    時間:2002年09月14日(18:20:38-22:18:00)
          實現“人民幣找零”問題的貪婪法解決演算法
*/

#include    
"stdio.h"
#include    
"stdlib.h"

//:============================“裝箱”問題的貪婪法解決演算法===========================
/*
    作者:成曉旭
    時間:2002年09月14日(18:20:38-20:00:00)
          完成“裝箱”問題的貪婪法解決演算法
    ===================================================
    問題描述:
            設有編號為0,1,2,...,n-1的n個物品,體積分別為v0,v1,v2,...,vn-1,
        將這n個物品裝到容量都為V的若干個箱子內。約定這n個物品的體積均不超過
        V,即對於0<=i
    程式設計思想:
            假設每隻箱子所裝物品用連結串列來表示,連結串列首節點指標存入一個結構體中,
        結構記錄該箱子尚剩餘的空間量和該箱子所裝物品連結串列的首指標。
    演算法描述:
    {
        輸入箱子的容積;
        輸入物品的種類數;
        按體積從大到小的順序輸入各個物品的體積;
        預置已用箱子鏈為空;
        預置已用箱子計數器box_count為0;
        for(i=0;i        {//物品i按以下步驟裝箱;
            從已用的第一隻箱子開始順序尋找能放入物品i的箱子j;
            if(已用箱子都不能再放物品i)
            {
                另用一隻箱子,並將物品i放入該箱子裡;
                box_count ++;
            }
            else
                將物品i放入箱子j裡;
        }
    }

*/

//物品資訊結構型別定義
#define        RES        struct    RES
RES
{
    
int    order;        //物品編號
    RES * link;        //另一個物品的指標
}
;
//裝箱資訊結構型別定義
#define        BOX        struct    BOX
BOX
{
    
int    remainder;    //箱子剩餘空間
    RES    *r_head;    //箱子所裝物品的物品鏈首節點指標
    BOX    *link;        //箱子鏈的後續箱子節點指標
}
;
void    Encase_Box()
{
    
//箱子計數器,箱子體積,物品種類,迴圈計數器
    int    box_count,box_volume,category,i;
    
int    *array;        //儲存各個物品體積資訊的動態陣列
    
//裝箱連結串列的首節點、尾節點指標,程式處理臨時變數指標
    BOX    *b_head,*b_tail,*box;
    RES    
*p_res,*q_res;        //當前將裝箱的物品節點,指向裝箱連結串列的當前箱子的最後一個物品

    printf(
"輸入箱子的容積: ");
    scanf(
"%d",&box_volume);
    printf(
"輸入物品的種類: ");
    scanf(
"%d",&category);
    array 
= (int *)malloc(category * sizeof(int));
    printf(
"按從大到小的順序輸入各個物品的體積: ");
    
for(i=0;i<category;i++)
    
{
        printf(
"物品[%d]的體積 =  ",i+1);
        scanf(
"%d",array + i);
    }

    b_head 
= b_tail = NULL;        //預置已用箱子連結串列為空
    box_count = 0;                //預置已用箱子計數器
    for(i=0;i<category;i++)
    
{//物品i按以下步驟裝箱
        
//從[已用的]第一隻箱子開始順序尋找能放入物品i的箱子j;
        p_res = (RES *)malloc(sizeof(RES));
        p_res
->order = i;
        p_res
->link = NULL;
        
for(box = b_head;box != NULL;box = box->link)
        
{
            
if(box->remainder >= array[i])
                
break;        //找到還可裝入物品i的箱子[box指標指向它]
        }

        
if(box == NULL)
        
{//已用箱子都不能裝入物品i,或裝箱連結串列為空
            
//建立一個新的空箱子來裝載物品i
            box = (BOX *)malloc(sizeof(BOX));
            box
->remainder = box_volume - array[i];    //計算新箱子的剩餘空間
            box->link = NULL;
            box
->r_head = NULL;        //新箱子尚未裝入一件物品
            if(b_head == NULL)
                b_head 
= b_tail = box;    //本次裝入的物品是當前箱子的第一個物品
            else
                b_tail 
= b_tail->link = box;    //將本次裝入的物品掛接在當前箱子的物品裝箱連結串列的末尾
            box_count ++;    //累加所用箱子計數器
        }

        
else
            box
->remainder = box->remainder - array[i];    //將物品i裝入已用箱子box中
        
//以下11行:將物品i掛接到當前箱子box的物品裝箱連結串列中
        
//讓指標q_res:指向裝箱連結串列中的當前箱子的最後一個物品
        for(q_res = box->r_head;q_res != NULL && q_res->link != NULL;q_res = q_res->link);
        
if(q_res == NULL)
        
{//最後一個物品為空,當前物品i裝入的箱子box是新建立的箱子
            p_res->link = box->r_head;    //物品i的link設為NULL
            box->r_head = p_res;        //新箱子box的物品鏈首節點指標指向物品節點p_res
        }

        
else
        
{
            p_res
->link = NULL;            //物品i的link設為NULL
            q_res->link = p_res;        //物品i掛接到當前箱子box的最後一個物品q_res之後
        }

    }

    
//輸出裝箱問題的處理結果
    printf("用容積這[%d]的箱子[%d]個可裝完以上[%d]件物品!",box_volume,box_count,category);
    printf(
"各箱子所裝物品情況如下: ");
    
for(box = b_head,i=1;box != NULL;box = box->link,i++)
    
{//第i只箱子所裝物品情況
        printf("第%2d只箱子,還剩餘容積%4d,所裝物品有: ",i,box->remainder);
        
for(p_res = box->r_head;p_res != NULL;p_res = p_res->link)
            printf(
" 物品號[%d],物品體積[%d] ",p_res->order + 1,array[p_res->order]);
        printf(
" ");
    }

}

//:============================“裝箱”問題的貪婪法解決演算法===========================

int main(int argc, char* argv[])
{
    
//Encase_Box();
    
//Journey_Horse();
    Run_Give_Change();
    printf(
" 應用程式執行結束! ");
    
return 0;
}



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=935688


相關文章