3

さまざまなサイズのマテリアルのリストを含む配列があります: {4,3,4,1,7,8}. ただし、ビンはサイズ 10 までの材料を収容できます。配列内のすべての要素をパックするために必要なビンの最小数を調べる必要があります。

上記の配列の場合、3 つのビンにパックして、次のように分割でき{4,4,1}ます。3 本のストック パイプに収まる他の配置も考えられますが、それより少ない数では実行できません。{3,7}{8}

この問題をよりよく理解するために、再帰を通じてこの問題を解決しようとしています。

私はこのDP 処方を使用しています (pdf ファイルの 20 ページ)。

n = ∑nj 項目の入力 (n1;:::;nk) を考える
単一のビンにパックできる k-タプル (入力のサブセット) のセットを決定する
つまり、すべてのタプル (q1;:::; qk) の OPT(q1;:::;qk) = 1
このセットを Q で表す 各 k タプル q について、OPT(q) = 1
となる 再帰を使用して残りの値を計算する : OPT(i1;:: :;ik) = 1 + minOPT(i1 - q1;:::;ik - qk)

私はコードを作成しましたが、小さなデータセットでは問題なく動作します。しかし、配列のサイズを 6 要素以上に増やすと、非常に遅くなります。8 要素を含む配列を解くのに約 25 秒かかります。アルゴリズムに何か問題があるか教えていただけますか? 別の解決策は必要ありません---なぜこれが遅いのか、どうすれば改善できるのかを知りたいだけです

これが私がC++で書いたコードです:

void recCutStock(Vector<int> & requests,  int numStocks)
{
 if (requests.size() == 0)
 {

     if(numStocks <= minSize)
    {
        minSize = numStocks;

    }
//   cout<<"GOT A RESULT : "<<numStocks<<endl;
        return ;
 }
 else
 {
    if(numStocks+1 < minSize) //minSize is a global variable initialized with a big val
    {
     Vector<int> temp ; Vector<Vector<int> > posBins;
     getBins(requests, temp, 0 , posBins); // 2-d array(stored in posBins) containing all possible single bin formations

    for(int i =0; i < posBins.size(); i++)
    {
        Vector<int> subResult;
        reqMinusPos(requests, subResult,  posBins[i]);  // subtracts the initial request array from the subArray
        //displayArr(subResult);


            recCutStock(subResult,  numStocks+1);


    }
    }
    else return;
 }

}

getBins 関数は次のとおりです。

void getBins(Vector<int> & requests, Vector<int> current, int index, Vector<Vector<int> > & bins)

{

if (index == requests.size())

{

if(sum(current,requests) <= stockLength && sum(current, requests)>0 )

        {
                bins.add(current);
            //  printBins(current,requests);
            }
            return ;
        }
        else
        {

        getBins(requests, current, index+1 , bins);
                current.add(index);
            getBins(requests, current, index+1 , bins);
        }
}
4

5 に答える 5

6

動的計画法アルゴリズムはO(n ^ {2k})です。ここで、kは個別のアイテムの数、nはアイテムの総数です。これは、実装に関係なく非常に遅くなる可能性があります。通常、NP困難な問題を解決する場合、速度にはヒューリスティックが必要です。

Coffmanetal。のNextFitDecreasing Height(NFDH)とFirst Fit Decreasing Height(FFDH)を検討することをお勧めします。それらはそれぞれ2最適および17/10最適であり、O(n log n)時間で実行されます。

最初にNFDHを試すことをお勧めします。降順で並べ替え、結果をリンクリストに保存してから、ビンがいっぱいになるか、できるアイテムがなくなるまで、最初からアイテムを繰り返し挿入してみてください(最大値が最初)。挿入されます。次に、次のビンに移動します。

参照

Owen Kaser、Daniel Lemire、タグクラウド描画:クラウド視覚化のアルゴリズム、社会情報組織のタグ付けとメタデータ(WWW 2007)、2007年。(関連する説明についてはセクション5.1を参照してください。)

EG Coffman、Jr.、MR Garey、DS Johnson、およびRETarjan。レベル指向の2次元パッキングアルゴリズムのパフォーマンスの限界。SIAM J. Comput。、9(4):808–826、1980。

于 2011-11-29T15:30:51.247 に答える
1

しかし、配列のサイズを 6 要素以上に増やすと、非常に遅くなります。8 要素を含む配列を解くのに約 25 秒かかります。アルゴリズムに何か問題があるか教えていただけますか?

それは力ずくで正常です。ブルートフォースはまったくスケーリングしません。

于 2011-11-30T16:24:03.290 に答える
1

あなたの場合:ビンサイズ= 30、合計アイテム= 27、少なくとも3つのビンが必要です。最初のフィットの減少を試すことができ、うまくいきます!

改善するその他の方法: 3 つのビンと 27 サイズのユニットを使用すると、3 つのユニットのスペースが残ります。つまり、サイズ 1 のアイテムは無視できます。他のものを 3 つのビンに収めると、どこかに収まります。これにより、26 サイズのユニットが残ります。つまり、1 つのビンに少なくとも 2 つのユニットが空になります。サイズ 2 のアイテムがある場合は、サイズが合うので無視することもできます。サイズ 2 のアイテムが 2 つある場合、サイズ 3 のアイテムも無視できます。

サイズが 7 + 3 のアイテムが 2 つあり、これはビンのサイズとまったく同じです。これら 2 つが同じビンにある最適な解決策は常にあります。「7」が他のアイテムの場合、それらのサイズは 3 以下になるため、別のビンにある場合は「3」と交換できます。

別の方法: k 個のアイテム >= ビン サイズ / 2 がある場合 (この時点でビン サイズ / 2 に等しい 2 つのアイテムを持つことはできません)、k 個のビンが必要です。これにより、最初に見積もったビンの最小数が増える可能性があり、その結果、すべてのビンで保証される空きスペースが増え、1 つのビンの残りのスペースの最小サイズが増えます。j = 1, 2, ..., k の場合、すべてのアイテムを同じビンに収まる可能性のある j 個のビンに収めることができれば、これが最適です。たとえば、サイズ 8、1、1 があり、サイズ 2 がない場合、ビンの 8+1+1 が最適です。8 + 4 + 4 が残っており、8 に適合するものがないため、ビン内の "8" だけが最適です。(サイズ 8、8、8、2、1、1、1 のアイテムがあり、サイズ 2 以外のアイテムがない場合は、3 つのビンに梱包するのが最適です)。

大きなアイテムがある場合に試してほしいこと: 大きなアイテムがあり、それに収まる最大のアイテムが、収まるアイテムの組み合わせと同じかそれより大きい場合は、それらを組み合わせるのが最適です。さらにスペースがある場合は、これを繰り返すことができます。

全体として、少し考えてみると、サイズ 4 と 4 の 2 つのアイテムを 1 つまたは複数のビンに収めることに問題が軽減されました。大きな問題では、少しずつ役に立ちます。

于 2014-04-03T18:21:16.273 に答える
0

ビンパッキング ソリューションを作成しましたが、ランダムな順序で最適に適合することをお勧めします。

于 2011-11-30T16:31:34.207 に答える