纸浆优化不重复排列组合

问题描述

我正在研究一个优化问题,我的目标是当出售两个产品对时最大化利润,但约束是,该对产品中的产品不应重复。

http://www.voidspace.org.uk/python/modules.shtml#pycrypto

我正在使用Pulp优化解决方案,但是代码效率低下,并且会无限循环。

file = pd.read_csv('input_file.csv')

main_product_1 = list(file['Product ID'].unique())
main_product_2 = list(file['Product ID 2'].unique())

file.set_index(['Product ID','Product ID 2'],inplace=True)
file = file['Profit']

# Target Variable
combine = pulp.LpVariable.dicts("combine",((product_1,product_2) for product_1 in main_product_1 for
                                 product_2 in main_product_2 if product_1 != product_2),cat='Binary')

# Initializing the model

model = pulp.LpProblem("prof_max",pulp.LpMaximize)

# Objective Function optimization
model += pulp.lpSum(
        [combine[product_1,product_2] * file.loc[(product_1,product_2)] for product_1 in
         main_product_1 for product_2 in main_product_2 if product_1 != product_2])

# Constraints for optimization
for area in set_plant:
  model += pulp.lpSum([combine[area,other] for other in main_product_1 if area != other]
                      + [combine[other,area] for other in main_product_2 if area != other]) == 1

model.solve()
print(pulp.LpStatus[model.status])

# Check
set_index = set(file.index)
set_expected = set(
        [(product_1,product_2) for product_1 in main_product_1 for product_2 in main_product_2 if
         product_1 != product_2])
len(set_expected - set_index)

问题是代码进入无限循环,但我没有得到任何结果,是否有更优化的方式来运行此方法?

解决方法

问题是您要添加非常大量的整数变量,而整数线性规划是一个极其困难且效率低下的问题。但是,您可能还需要进行其他一些改进。

请考虑以下构造:

  1. 如果您拥有产品1的M个实例和产品2的N个实例,那么您就有MN个二进制变量x_mn;
  2. 如果P为1,则每个变量都会对目标函数贡献x_mn
  3. 您在约束中说x_mn + x_nm == 1,但实际上应该是x_mn + x_nm <= 1。否则,您说必须在列表中有每个组合。这可能会导致不可行的解决方案;
  4. 如果您考虑的是组合而不是排列(即[1000,1001]和[1001,1000]相同,那么这意味着M = N,并且您只能删除大约一半的变量即可还剩M^2 / 2。(如果您将值空间视为MxM正方形,则您只能接受一个三角形,因为另一个三角形是等效的;
  5. 如果您像上面提到的那样限制变量空间,则实际上不需要任何约束;如果x_nm不存在,那么对于二进制变量,x_mn <= 1很明显。
import pandas as pd
import numpy as np
import pulp

file = pd.read_csv('file.csv')
file = file[file['Product ID'] < file['Product ID 2']]
file.set_index(['Product ID','Product ID 2'],inplace=True)
file = file['Profit']

combinations = file.index
individual_products = set()

for product_1,product_2 in combinations:
individual_products.add(product_1)
individual_products.add(product_2)

# Target Variable
combine = pulp.LpVariable.dicts("combine",combinations,cat='Binary')

# Initializing the model

model = pulp.LpProblem("prof_max",pulp.LpMaximize)

# Objective Function optimization
model += pulp.lpSum([combine[i] for i in file.index] * file)

# All individual products can only be used once
for product in individual_products:
matching_combinations = combinations[(combinations.to_frame() == product).any(axis=1)]
model += pulp.lpSum([combine[i] for i in matching_combinations]) <= 1

model.solve()
print(pulp.LpStatus[model.status])
print([v for v in model.variables() if v.varValue > 0])

通过这些更改,在不改变问题或固有实现的前提下,您基本上消除了75%的约束。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...