2

同じ商品が異なるサイズの箱に入っています。

  Boxes             S   M   L   XL  XXL

00001               2   4   4       
00002                           4   2
00003               8               
00004                   8           
00005                       8   8   
00006                               8
00007               1   2   2   2   2
00008               1   2   2   2   
00009               2   4   4   4   2
00010               3   5   4   4   2
00011               2   3   4   4   2

ここで、モデルを次のサイズで取得する必要があります。

                    S   M   L   XL  XXL
                    2   4   4   4   2

必需品を入れるにはどの箱が必要ですか?

ボックス 00003、00004、00005、00006 を使用すると、次のように収集できます。

                    S   M   L   XL  XXL
                   8   8    8   8   8

しかし、多くのアイテムが無駄になります。

ボックス 00007、00008 を使用して、次のように取得することもできます。

                    S   M   L   XL  XXL
                   2   4    4   4   2

これは私に合っていますが、それでも 2 つのボックスを移動する必要があります。その間、ボックス 00009 には最小限の労力で必要なものが正確に含まれています。

要約すると、必需品を入れるために最低限必要な箱の数は? クエリを作成するための開始点が見つからないか、何らかのコードでこれを解決できません。どんな助けでも大歓迎です。

前もって感謝します。

4

1 に答える 1

0

以下は、問題を解決するために SQL-Server で動作します。再帰的な CTE を使用して、ボックスのすべての組み合わせの各サイズの数を決定することで機能します (大量のボックスの場合、これは面倒になり、MAXRECURSION変更が必要になる場合があります)。次に、これらの組み合わせのどれが各サイズの最小数の基準を満たすかを判断し、必要な箱の数の順に残りの組み合わせをランク付けし、次に最小基準を満たすために無駄になった合計数をランク付けします。関数の順序RANK()を変更すると、ソリューションのランク付け方法が変わります。

DECLARE @S INT = 2,
        @M INT = 4,
        @L INT = 4,
        @XL INT = 4,
        @XXL INT = 2


CREATE TABLE #Boxes (Model VARCHAR(5), S INT, M INT, L INT, XL INT, XXL INT)
INSERT #Boxes VALUES
    ('00001', 2, 4, 4, 0, 0),
    ('00002', 0, 0, 0, 4, 2),
    ('00003', 8, 0, 0, 0, 0),
    ('00004', 0, 8, 0, 0, 0),
    ('00005', 2, 0, 8, 8, 0),
    ('00006', 2, 0, 0, 0, 8),
    ('00007', 1, 2, 2, 2, 2),
    ('00008', 1, 2, 2, 2, 0),
    ('00009', 2, 4, 4, 4, 2),
    ('00010', 3, 5, 4, 4, 2),
    ('00011', 2, 3, 4, 4, 2)

;WITH CTE AS
(   SELECT  *, CONVERT(VARCHAR(1000), Model + ';') [Models], 1 [Boxes]
    FROM    #Boxes
    UNION ALL
    SELECT  a.Model, 
            a.S + b.S, 
            a.M + b.M, 
            a.L + b.L, 
            a.XL + b.XL,
            a.XXL + b.XXL,
            CONVERT(VARCHAR(1000), b.Models + a.Model + ';'), 
            Boxes + 1
    FROM    #Boxes a
            INNER JOIN CTE b
                ON a.Model > b.Model
), CTE2 AS
(   SELECT  Models, 
            S, 
            M, 
            L, 
            XL, 
            XXL, 
            Boxes, 
            (S + M + L + XL + XXL) - (@S + @M + @L + @XL + @XXL) [Wasted]
    FROM    CTE
    WHERE   S >= @S
    AND     M >= @M
    AND     L >= @L
    AND     XL >= @XL
    AND     XXL >= @XXL
)
SELECT  *,
        RANK() OVER(ORDER BY Boxes, Wasted) [Rank]
FROM    CTE2

DROP TABLE #Boxes
于 2012-04-04T10:38:31.003 に答える