近似裝箱問題(三種聯機算法實現)

【0】README

0.1) 本文總結於 數據結構與算法分析, 源代碼均爲原創, 旨在 理解 「近似裝箱問題(三種聯機算法實現)」 的idea 並用源代碼加以實現;
0.2) 近似裝箱問題的三種聯機算法 分別是: 下項適合算法 + 首次適合算法 + 最佳適合算法 , 咱們將依次給出源代碼實現+算法描述;
0.2)聯機問題+脫機問題
git

  • version1)聯機裝箱問題: 在這種問題中, 必須將每一件物品放入一個箱子後才處理下一件物品;(英語口語考試, 作完上一題,才能進入下一題做答)
  • version2)脫機裝箱問題:在一個脫機裝箱算法中, 咱們作任何事情 都須要等到全部的輸入數據全被讀入後才進行;(通常的考試,你只須要在規定的時間作完題目便可,作題順序不是咱們所關心的)

【1】近似裝箱問題

1.1)問題描述: 給定N 項物品, 大小爲 s1, s2, ..., sN, 全部的大小都知足 0 < si < = 1 ;問題是要把這些物品裝到最小數目的箱子中去, 已知每一個箱子的容量是1個單位;下圖顯示的是 對N項物品的最優裝箱方法;
這裏寫圖片描述
1.2)有兩種版本的裝箱問題:
github

  • version1)聯機裝箱問題: 在這種問題中, 必須將每一件物品放入一個箱子後才處理下一件物品;(英語口語考試, 作完上一題,才能進入下一題做答)
  • version2)脫機裝箱問題:在一個脫機裝箱算法中, 咱們作任何事情 都須要等到全部的輸入數據全被讀入後才進行;(通常的考試,你只須要在規定的時間作完題目便可,作題順序不是咱們所關心的)

1.3)聯機算法算法

  • 1.3.1)要考慮的第一個問題是: 一個聯機算法即便在容許無限計算的狀況下是否實際上總能給出最優的解答;咱們知道, 即便容許無限計算, 聯機算法也必須先放入一項物品而後才能處理下一件物品而且不能改變決定
  • 1.3.2)咱們能夠證實:聯機算法不總可以給出最優解;

【2】下項適合算法

2.1)算法描述: 當處理任一物品時, 咱們檢查看他是否還能裝進剛剛裝進物品的同一個箱子中去。 若是可以裝進去, 那麼就把它裝入該箱子中, 不然,就開闢一個新箱子;
2.2)看個荔枝:
這裏寫圖片描述
數據結構


2.3)source code + printing resultside

void nextfix(double key, int* index)
{
    int i;
    ElementTypePtr box;
    ElementTypePtr temp;

    box = buildSingleElement();
    box->key = key; // build single box with key over
    
    i = *index;
    for(; i<size; i++)
    {
        if(surplus[i] < key)
            continue;
        temp = boxes[i] ;
        while(temp->next)                   
            temp = temp->next;
        temp->next = box;
        surplus[i] -= key;
        break;
    }
    *index = i;
}
  • 2.3.3)printing results:
    這裏寫圖片描述

【3】首次適合算法

3.0)出現的問題:雖然下項算法有一個合理的性能保證,可是,它的效果在實踐中是不好的,由於在不須要開闢新箱子的時候它卻開闢了新箱子;
3.1)算法描述:首次適合算法的策略是 依序掃描這些箱子但吧新的一項物品放入足夠盛下它的第一個箱子中。所以,只有當先前放置物品的結果已經沒有再容得下當前物品餘地的時候, 咱們纔開闢一個新箱子;(一句話, 這裏是從頭至尾掃描箱子)
3.2)看個荔枝:
這裏寫圖片描述
3.3)能夠斷言:首次適合算法保證其解最多包含最優裝箱數的二倍;由於在任一時刻最多有一個箱子其空出的部分大於箱子的一半,由於如有第二個這樣的箱子, 則它裝的物品就會裝到第一個這樣的箱子中了;
3.4)source code + printing results
性能

void firstFix(double key)
{
    int i;
    ElementTypePtr box;
    ElementTypePtr temp;

    box = buildSingleElement();
    box->key = key; // build single box with key over

    for(i=0; i<size; i++)
    {
        if(surplus[i] < key)
            continue;
        temp = boxes[i] ;
        while(temp->next)                   
            temp = temp->next;
        temp->next = box;
        surplus[i] -= key;
        break;
    }
}
  • 3.4.3)printing results:
    這裏寫圖片描述

【4】最佳適合算法

4.1)算法描述:該方法不是吧一項新物品放入所發現的第一個可以容納它的箱子, 而是放到全部箱子中可以容納它的最滿的箱子中;
4.2)看個荔枝:
這裏寫圖片描述
Attention)
ui

  • A1)大小爲0.3 的項不是放在B2 而是放在了B3, 此時它正好把B3填滿;
  • A2)當須要O(NlogN)的時候, 該算法對隨機的輸入表現得很好;

4.3)source code + printing resultsidea

void bestFix(double key)
{
    int i;
    ElementTypePtr box;
    ElementTypePtr temp;
    double minimum;
    int miniIndex;

    box = buildSingleElement();
    box->key = key; // build single box with key over
    miniIndex = 0;
    minimum = 1.0;

    for(i=0; i<size; i++)
    {
        if(surplus[i] < key)
            continue;
        if(surplus[i] - key < minimum)
        {
            minimum = surplus[i] - key;
            miniIndex = i;
        }
    }

    temp = boxes[miniIndex] ;
    while(temp->next)                   
        temp = temp->next;
    temp->next = box;
    surplus[miniIndex] -= key;  
}
  • 2.3)printing results:
    這裏寫圖片描述
相關文章
相關標籤/搜索