【问题标题】:How to make linear programming optimization faster如何使线性规划优化更快
【发布时间】:2019-06-04 08:22:07
【问题描述】:

我正在尝试将客户 Ci 分配给财务顾问 Pj。每个客户都有一个保单价值 xi。我假设分配给每个顾问的客户数量 (n) 是相同的,并且不能将同一客户分配给多个顾问。因此,每个合作伙伴都会有这样的策略值分配:

P1=[x1,x2,x3] , P2=[x4,x5,x6], P3=[x7,x8,x9]

我正在尝试找到最佳分配,以尽量减少顾问之间的基金价值差异。我将离散度定义为基金价值最高 (z_max) 和基金价值最低 (z_min) 的顾问之间的差异。

因此,这个问题的公式是:

如果我们将客户 Ci 分配给顾问 Pj,则 yij=1,否则为 0

第一个约束表示 zmax 必须大于或等于每个策略值;由于目标函数鼓励较小的 zmax 值,这意味着 zmax 将等于最大的策略值。类似地,第二个约束设置 zmin 等于最小策略值。第三个约束条件是每个客户必须被分配给一个顾问。第四个表示每个顾问必须有 n 个客户分配给他/她。

我有一个使用优化包的有效解决方案:PuLP,它可以找到最佳分配。

import random 
import pulp 
import time


# DATA

n = 5 # number of customers for each financial adviser
c = 25 # number of customers 
p = 5 # number of financial adviser
policy_values = random.sample(range(1, 1000000), c) # random generated policy values 

# INDEXES

set_I = range(c)
set_J = range(p)
set_N = range(n)
x = {i: policy_values[i] for i in set_I} #customer policy values
y = {(i,j): random.randint(0, 1) for i in set_I for j in set_J} # allocation dummies 

# DECISION VARIABLES

model = pulp.LpProblem("Allocation Model", pulp.LpMinimize)

y_sum = {}
y_vars = pulp.LpVariable.dicts('y_vars',((i,j) for i in set_I for j in set_J), lowBound=0, upBound = 1, cat=pulp.LpInteger)
z_max = pulp.LpVariable("Max Policy Value")
z_min = pulp.LpVariable("Min Policy Value")
for j in set_J:
    y_sum[j] = pulp.lpSum([y_vars[i,j] * x[i] for i in set_I])

# OBJECTIVE FUNCTION

model += z_max - z_min

# CONSTRAINTS

for j in set_J:
    model += pulp.lpSum([y_vars[i,j] for i in set_I]) == n 
    model += y_sum[j] <= z_max
    model += y_sum[j] >= z_min 


for i in set_I:
    model += pulp.lpSum([y_vars[i,j] for j in set_J]) == 1 

# SOLVE MODEL

start = time.clock() 
model.solve()
print('Optimised model status: '+str(pulp.LpStatus[model.status]))
print('Time elapsed: '+str(time.clock() - start))

请注意,我通过包含一个附加变量 y_sum 来实现约束 1 和 2 的方式略有不同,以防止重复包含大量非零元素的表达式

问题

问题在于,对于较大的 n、p 和 c 值,模型需要很长时间才能优化。是否可以对我实现目标函数/约束的方式进行任何更改以使解决方案更快?

【问题讨论】:

  • 你试过我的建议here 用常量替换 $z^\max$ 和 $z^\min$ 吗?
  • 是的,很遗憾,我无法让 PuLP 最小化为 0 - 我接受这可能是软件包的限制,而不是您的解决方案
  • 那么只需引入一个新变量w;最小化w 并使用w &gt;= 0

标签: python optimization linear-programming gurobi pulp


【解决方案1】:

尝试使用 Gurobi 等商业求解器与纸浆。您应该会大大减少求解时间。

还要检查您的计算机内存,如果任何求解器内存不足并开始分页到磁盘,求解时间将非常长。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 2018-05-24
    • 1970-01-01
    相关资源
    最近更新 更多