我正在尝试将客户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值,模型花费的时间太长而无法优化。是否可以对我实现目标函数/约束的方式进行任何更改以使解决方案更快?
答案 0 :(得分:1)
尝试使用诸如Gurobi的商业求解器处理纸浆。您应该大大减少求解时间。
还要检查计算机的内存,如果有任何求解器内存不足并开始分页到磁盘,则求解时间将非常长。