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 个盒子,同时 BOX 00009 正是我需要的东西,而且工作量很小。

总而言之,我需要多少箱子才能满足我的必需品?我找不到构建查询的起点或某种代码解决了这个问题。任何帮助将不胜感激。

先感谢您。

4

1 回答 1

0

以下将在 SQL-Server 上工作以解决您的问题。它通过使用递归 CTE 来确定所有框组合的每个尺寸的数量(对于大量框,这可能会变得很麻烦并且需要MAXRECURSION更改)。然后它确定这些组合中的哪些满足每个尺寸的最小数量的标准,然后按照所需的盒子数量的顺序排列剩余的组合,然后是为了满足最小标准而浪费的总数。在函数中更改 order byRANK()将更改解决方案的排名方式。

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 回答