从多个供应商(供应商)订购多个项目(部件)的最佳选择

时间:2013-01-22 05:13:03

标签: sql sql-server combinations combinatorics purchase-order

此处的任务是定义供应商订购商品(部件)的最佳方式(详见下文)。

表模式的相关部分(带有一些示例数据)是

ID  NUMBER
1   Item0001
2   Item0002
3   Item0003

ID  NAME         DELIVERY DISCOUNT
1   Supplier0001 0        0
2   Supplier0002 0        0.025
3   Supplier0003 20       0

DELIVERY是该供应商在每次交货时征收的运费(以美元计)。 DISCOUNT是该供应商允许按时付款的结算折扣(以百分比表示,即ID=2为2.5%)。

SupplierItems

SUPPLIER_ID ITEM_ID PRICE
1           2       21.67
1           5       45.54
1           7       32.97

这是供应商和商品之间的多对多连接,供应商为该商品收取的价格(以美元计)。每个项目至少有一个供应商,但有些供应商不止一个。供应商可能没有物品。

PartsRequests

ID ITEM_ID QUANTITY LOCATION_ID ORDER_ID
1  59      4        2           (null)
2  89      5        2           (null)
3  42      4        2           (null)

此表是来自现场站点的请求,供供应商订购和交付给该站点的部件。向网站交付任意数量的商品会收取运费。订购部件后,ORDER_ID会插入到表格中,因此我们只关注那些ORDER_ID IS NULL

的部分

问题是,为每个“LOCATION”订购这些零件的最佳方式是什么,其中有3个最佳解决方案需要呈现给用户以供选择。

  1. 订单与供应商数量最少的组合
  2. 总成本最低的订单组合,即每个订单的QUANTITY*PRICE加上每个订单的DELIVERY总和忽略DISCOUNT的所有订单
  3. 作为第2项,但占DISCOUNT
  4. 显然,我需要确定可用订单的组合,然后确定最佳订单的组合变得微不足道,但我有点坚持以有效的方式来处理构建组合。

    我在SQL Server 2008中使用随机数据构建了一些SQL小提琴。 This one有100个项目,10个供应商和100个请求。 This one有1000个项目,50个供应商和250个请求。表模式是相同的。

    更新

    我推断解决方案必须是递归的,我构建了一个很好的表值函数来获取但是我在SQL Server中遇到了递归的32个硬限制。无论如何我对它感到不舒服,因为它暗示了一种程序性语言解决方案而不是RDMS。

    所以我现在正在玩CTE递归。

    根查询是:

    SELECT DISTINCT
           '' SOLUTION_ID
          ,LOCATION_ID
          ,SUPPLIER_ID
          ,(subquery I haven't quite worked out) SOLE_SUPPLIER
    FROM PartsRequests pr
         INNER JOIN
         SupplierItems si ON pr.ITEM_ID=si.ITEM_ID
    WHERE pr.ORDER_ID IS NULL
    

    这使得所有能够提供所需物品的供应商肯定是一种解决方案,可能并非最佳。如果供应商是该位置所需的任何产品的唯一供应商,则子查询设置标记;如果是这样,他们必须成为任何解决方案的一部分。

    递归部分是通过CTE.SUPPLIER_ID<> CTE.SUPPLIER_ID逐个删除供应商,如果它们仍覆盖所有项目,则添加它们。 SOLUTION_ID将是已删除供应商的CSV列表,部分用于唯一标识每个解决方案,部分用于检查,因此我得到组合而不是排列。

    仍然致力于细节,这次更新的目的是让社区说“耶,看起来那样会起作用”,或者“你好白痴,那不会起作用,因为......”

    由于

1 个答案:

答案 0 :(得分:2)

这是一个更通用的答案(如在sql中),因为我认为解决这个问题需要更强大的功能。您的第一个方案是选择最少数量的供应商。这个问题可以看作是set cover problem,因为您试图满足供应商对每个站点的所有需求。这个问题已经完成NP了。

您的第三种情况似乎与第二种情况基本相同。您只需在价格中考虑折扣,假设您按时支付每笔订单。

第二种情况至少是NP难度,因为我发现与facility location problem有很多相似之处。您正在尝试根据价格和交付成本(开放成本)决定使用(开放)哪些供应商(设施)来满足您的订单(需求)。

列举您的可能解决方案似乎不可行,因为有10家供应商,您有2 ^ 10种使用它们的可能性,进一步复杂化内部需求分配。

我建议一些动态编程,首先选择你必须使用的供应商(=他们是唯一提供特定产品的供应商),消除一些可能性(如果供应商A +交付的成本A<成本为供应商B)然后尝试扩展您的可能解决方案集。线性规划也是一种有效的思路。