获得最佳组合的算法

时间:2016-09-30 12:27:27

标签: c++ c algorithm go

我的ID为1, 3, 4, 5, 6, 7的商品。现在我有如下数据。 每行都有一个offerId。 Array of Ids由数组中ID的组合组成。 DiscountofferId

的值
offerId : Array of Ids     : Discount
o1      : [1]              : 45
o2      : [1 3 4]          : 100
o3      : [3 5]            : 55
o4      : [5]              : 40
o5      : [6]              : 30
o6      : [6 7]            : 20

现在我必须选择所有offerIds,它给我最好的ID组合,即最大总折扣。

例如,在上述情况中:可能的结果可能是:

[o2,o4,o5]最高折扣为170(100 + 40 + 30)

请注意。结果offerId应该是Ids不重复的结果。 o2,o4,o6 id的例子[1,3,4],[5],[6]都是不同的。

其他组合可以是: o1, o3, 06其中id为[1],[3,5],[6,7]但总数为120(45 + 55 + 20),与前一种情况相比小于170

我需要一个算法/代码来帮助我识别combination of offerIds哪个会给出maximum discount,考虑到每个商品应该包含不同的Ids

注意我正在用go语言编写代码。但任何语言的解决方案/逻辑都会有所帮助。

注意:我希望我能够正确解释我的要求。如果需要任何额外信息,请发表评论。感谢。

1 个答案:

答案 0 :(得分:2)

这是一个动态编程解决方案,对于每个可能的ID子集,找到最大可能折扣的商品组合。 这将是伪代码。

我们的优惠是包含字段offerNumbersetOfItemsdiscount的结构。 出于实现的目的,我们首先按整数从0到不同可能项(例如k)减去1的整数重新计算可能的项目。 之后,我们可以用长度为setOfItems的二进制数表示k。 例如,如果k = 6且setOfItems = 101110 2 ,则此集合包括项目5,3,2和1,并且排除项目4和0,因为位5, 3,2和1是1,位4和0是零。

现在让f[s]成为我们可以使用精确设置s项目获得的最佳折扣。 这里,s可以是0到2 k -1之间的任何整数,表示2个 k 可能子集中的一个。 此外,让p[s]成为优惠列表,这些优惠允许我们为商品f[s]获取折扣s。 算法如下:

initialize f[0] to zero, p[0] to empty list
initialize f[>0] to minus infinity
initialize bestF to 0, bestP to empty list
for each s from 0 to 2^k - 1:
    for each o in offers:
        if s & o.setOfItems == o.setOfItems:  // o.setOfItems is a subset of s
            if f[s] < f[s - o.setOfItems] + o.discount:  // minus is set subtraction
                f[s] = f[s - o.setOfItems] + o.discount
                p[s] = p[s - o.setOfItems] append o.offerNumber
                if bestF < f[s]:
                    bestF = f[s]
                    bestP = p[s]

在此之后,bestF是最佳折扣,而bestP是可以获得折扣的优惠列表。

复杂性为O(| offers | * 2 k ),其中k是项目总数。

这是另一种渐近相同的实现,但在大多数子集无法访问时实际上可能更快。 它是&#34;前进&#34;而不是&#34;落后&#34;动态编程。

initialize f[0] to zero, p[0] to empty list
initialize f[>0] to -1
initialize bestF to 0, bestP to empty list
for each s from 0 to 2^k - 1:
    if f[s] >= 0:  // only for reachable s
        if bestF < f[s]:
            bestF = f[s]
            bestP = p[s]
        for each o in offers:
            if s & o.setOfItems == 0:  // s and o.setOfItems don't intersect
                if f[s + o.setOfItems] < f[s] + o.discount:  // plus is set addition
                    f[s + o.setOfItems] = f[s] + o.discount
                    p[s + o.setOfItems] = p[s] append o.offerNumber