我有要通过cplex python API解决的MILP模型:
def CModel():
mdl=Model('Generate')
#variable declaration
y=mdl.binary_var_dict(ijk,name='y')
Sum=mdl.integer_var_dict(ij,name='S')
#objective
mdl.minimize(0)
#constraints
#1
mdl.add_constraints(mdl.sum(y[(i,j,k)]+y[(j,i,k)] for j in T)==1 for i in T for k in K)
#2
mdl.add_constraints(mdl.sum(y[(i,j,k)]+y[(j,i,k)] for k in K1 )==1 for i in T for j in T if i!=j)
#3
mdl.add_constraints(mdl.sum(y[(i,j,k)]+y[(j,i,k)] for k in K2 )==1 for i in T for j in T if i!=j)
#4
mdl.add_constraints(mdl.sum(y[(i,j,k)] for k in K )==1 for i in T for j in T if i!=j)
#5
for i,j in ij:
for k in K4:
Sum=mdl.sum(y[(j,i,k1)] for k1 in range(k+1,k+8 ))
mdl.add(mdl.if_then(y[(i,j,k)]==1, Sum==0))
return mdl
Sum是一个变量,我用它来构成第5个约束(我只是用它来将y在某些范围内限制为0)。在解决方案池中,我只需要y的索引,其中y == 1。我有用于解决模型的解决方案池:
def soln_pool(mdl):
cpx = mdl.get_cplex()
cpx.parameters.parallel.set(1)
cpx.parameters.mip.pool.intensity.set(4)
cpx.populatelim=50
st2=time.time()
try:
cpx.populate_solution_pool()
except CplexSolverError:
print("Exception raised during populate")
return []
numsol = cpx.solution.pool.get_num() #max timing by 29 second
sol_pool = []
pool=[]
pool2=[]
if numsol!=0:
for i in range(numsol):
indices = [j for j, a in enumerate(cpx.solution.pool.get_values(i)) if a > 0.5]
for element in sol_pool:
for j in element:
v = mdl.get_var_by_index(j)
i1 = int(v.name.split('_')[1])
i2 = int(v.name.split('_')[2])
i3 = int(v.name.split('_')[3])
pool.append([i1,i2,i3])
pool2.append(pool)
在添加约束5之前,解决方案池功能没有问题,但是在添加5之后,出现此错误:
i1 = int(v.name.split('_')[1])
ValueError: invalid literal for int() with base 10: '{y'
我可以只访问溶液池中的变量y值,然后将其转换为整数吗?
答案 0 :(得分:0)
您可以仅选中v.name.startswith('y')
来过滤掉不是纯y变量的任何内容。我的猜测是,令人讨厌的变量是在后台创建的一些辅助变量。您可以打印完整的v.name
来查看违规变量的名称。如果它是一个自动创建的变量,那么它的名称将告诉您创建了哪个约束。
还请注意,您拥有
Sum=mdl.integer_var_dict(ij,name='S')
及以后
Sum=mdl.sum(y[(j,i,k1)] for k1 in range(k+1,k+8 ))
后者覆盖了前者。那可能不是您打算做的。
答案 1 :(得分:0)
丹尼尔(Daniel)是对的。 Model.if_then
生成一个布尔变量。您可以使用以下小代码进行检查:
def is_gen(dv):
return 'yes' if dv.is_generated() else 'no'
for dv in cm.iter_variables():
print(f'-- variable: {dv.name}, index={dv.index}, generated={is_gen(dv)}')
生成如下输出:
-- variable: _bool{y_10_2_3 == 1}, index=5887, generated=yes
代表约束y_20_2_3 == 1的真变量。
如您所见,在Docplex生成变量后,对变量调用is_generated()
会返回True,因此您可以在拆分代码中过滤掉那些变量。