寻找最佳组合

时间:2017-12-28 17:14:24

标签: python algorithm

我正在寻找解决以下问题的方法。

假设我有这个产品网格。

table = [{'Products': 'Prod1', 'Unit1': 32, 'Unit2': 32, 'Unit3': 27, 'Unit4': 15 },
         {'Products': 'Prod2', 'Unit1': 35, 'Unit2': 12, 'Unit3': 19, 'Unit4': 29 },
         {'Products': 'Prod3', 'Unit1': 37, 'Unit2': 36, 'Unit3': 36, 'Unit4': 19 },
         {'Products': 'Prod4', 'Unit1': 16, 'Unit2': 15, 'Unit3': 18, 'Unit4': 31 },
         {'Products': 'Prod5', 'Unit1': 14, 'Unit2': 32, 'Unit3': 20, 'Unit4': 33 },
         {'Products': 'Prod6', 'Unit1': 10, 'Unit2': 33, 'Unit3': 28, 'Unit4': 36 },
         {'Products': 'Prod7', 'Unit1': 18, 'Unit2': 22, 'Unit3': 27, 'Unit4': 30 },
         {'Products': 'Prod8', 'Unit1': 11, 'Unit2': 13, 'Unit3': 20, 'Unit4': 26 }]

df = pd.DataFrame(table)

每个值都反映了我通过销售此产品获得的最大收入。例如。出售2单位prod1,我将获得32美元。对于每种产品,我最多可以卖4个单位。我总共可以卖出16个单位(4 * 4)。我的目标是最大化总收入。在给出的示例中,我将销售以下组合以最大化我的收入:

{prod1: 2 units (32),
 prod2: 1 unit  (35),
 prod3: 1 unit  (37),
 prod4: 4 units (31),
 prod5: 4 units (33),
 prod6: 4 units (36)}

我的问题是,我如何通过算法来制定它?

1 个答案:

答案 0 :(得分:1)

简单的解决方案是测试所有选项并确定提供最大收益的选项。

可以使用itertools.product生成所有选项:

from itertools import product
options = product(range(5), repeat=8)

每个产品可以销售0,1,2,3或4个单位,因此我使用range(5)作为第一个参数,有8个产品,所以我使用了repeat=8

但是,我们不希望最大化销售的单位数量,但是当销售16个或更少单位时的收入。在这种情况下,我使用maxkey函数。如果销售的单位超过16个,则键功能返回负值,否则根据单词列表和销售单位数量检查收入是多少:

def total_revenue(sales):
    if sum(sales) > 16:  # discard the revenue if more than 16 units are sold.
        return -1
    else: 
        # Sum the revenue based on the sales and the values in the table.
        sum_ = 0
        for idx, num in enumerate(sales):
            if num:
                sum_ += table[idx]['Unit{}'.format(num)]
        return sum_

maximized_revenue = max(options, key=total_revenue)
print(maximized_revenue)
# (1, 1, 1, 4, 2, 2, 1, 4)

这是一个元组,仍然需要转换为所需的字典:

{'prod{}'.format(idx+1): num for idx, num in enumerate(maximized_revenue)}
# {'prod1': 1,
#  'prod2': 1,
#  'prod3': 1,
#  'prod4': 4,
#  'prod5': 2,
#  'prod6': 2,
#  'prod7': 1,
#  'prod8': 4}

还有改进的余地,因为product会产生大量不必要的值(超过16件商品)。您可以使用product参数创建一个与repeat类似的自定义生成器,但如果已售出超过16个单元,则不会生成解决方案。