我正在寻找解决以下问题的方法。
假设我有这个产品网格。
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)}
我的问题是,我如何通过算法来制定它?
答案 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个或更少单位时的收入。在这种情况下,我使用max
和key
函数。如果销售的单位超过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个单元,则不会生成解决方案。