如何增加 Cplex 解决方案的数量?
How to increase number of Cplex solutions?
我有 cplex 模型,它有 1 个二进制变量 (x_i)。现在我有 2 个关于它的复杂解决方案的问题(我把它们放在一个 post 因为它们是相关的)。
首先: 对于我的模型,我得到了 26 个解决方案,但我知道实际上在 cplex 中生成了更多 solutions.How 解决方案?有什么办法可以增加解数吗?
其次:我想通过解决方案池访问所有解决方案,但是当我尝试打印所有解决方案时,它会打印所有现有变量(显然我只是需要等于 1) 及其值的变量。
这是我的解决方案池代码:
def generate_soln_pool(mdl):
cpx = mdl.get_cplex()
cpx.solnpoolintensity=4
cpx.solnpoolagap=0
cpx.populatelim=100000
try:
cpx.populate_solution_pool()
except CplexSolverError:
print("Exception raised during populate")
return []
numsol = cpx.solution.pool.get_num()
print(numsol)
nb_vars = mdl.number_of_variables
sol_pool = []
for i in range(numsol):
x_i = cpx.solution.pool.get_values(i)
assert len(x_i) == nb_vars
sol = mdl.new_solution()
for k in range(nb_vars):
vk = mdl.get_var_by_index(k)
sol.add_var_value(vk, x_i[k])
sol_pool.append(sol)
return sol_pool
bm=CModel()
pool = generate_soln_pool(bm)
for s, sol in enumerate(pool,start=1):
print(" this is solution #{0} of the pool".format(s))
sol.display()
这是我输出的一部分:
x_0 = 0
x_1 = 0
x_2 = 0
x_3 = 0
x_4 = 0
x_5 = 0
x_6 = 0
x_7 = 0
x_8 = 0
x_9 = 0
x_10= 0
x_11 = 1
x_12 = 0
x_13 = 0
.
.
.
我猜你是从the example in the documentation那里拿来的参数设置?这些参数将使 CPLEX 枚举所有 optimal 解。如果您想要 所有 个解决方案,您必须将解决方案池差距设置为非常大的值。
CPLEX 有很多生成解的方法,但它大致遵循通过启发式方法增强的标准分支定界方案。
当然,解决方案对每个变量都有一个值。如果您只需要某些变量,那么您可以使用 Python 提供的各种过滤和理解类型。例如,要获取解决方案中为 1 的二进制变量的索引,您可以这样做:
indices = [j for j, a in enumerate(cpx.solution.pool.get_values(i)) if a > 0.5]
编辑: 看到 运行 代码后,我们发现了问题所在:
代码只设置了绝对间隙参数,应该同时设置相对间隙参数。
代码设置参数如cpx.solnpoolintensity = 4
。这不是设置参数的正确方法。该语句只会在对象中创建一个新的 属性,其余代码将忽略它。
为枚举(最多)4000 个解决方案设置参数的正确方法是
cpx.parameters.mip.pool.intensity.set(4)
cpx.parameters.mip.pool.absgap.set(1e75)
cpx.parameters.mip.pool.relgap.set(1e75)
cpx.parameters.mip.limits.populate.set(4000)
我有
首先: 对于我的模型,我得到了 26 个解决方案,但我知道实际上在 cplex 中生成了更多 solutions.How 解决方案?有什么办法可以增加解数吗?
其次:我想通过解决方案池访问所有解决方案,但是当我尝试打印所有解决方案时,它会打印所有现有变量(显然我只是需要等于 1) 及其值的变量。
这是我的解决方案池代码:
def generate_soln_pool(mdl):
cpx = mdl.get_cplex()
cpx.solnpoolintensity=4
cpx.solnpoolagap=0
cpx.populatelim=100000
try:
cpx.populate_solution_pool()
except CplexSolverError:
print("Exception raised during populate")
return []
numsol = cpx.solution.pool.get_num()
print(numsol)
nb_vars = mdl.number_of_variables
sol_pool = []
for i in range(numsol):
x_i = cpx.solution.pool.get_values(i)
assert len(x_i) == nb_vars
sol = mdl.new_solution()
for k in range(nb_vars):
vk = mdl.get_var_by_index(k)
sol.add_var_value(vk, x_i[k])
sol_pool.append(sol)
return sol_pool
bm=CModel()
pool = generate_soln_pool(bm)
for s, sol in enumerate(pool,start=1):
print(" this is solution #{0} of the pool".format(s))
sol.display()
这是我输出的一部分:
x_0 = 0
x_1 = 0
x_2 = 0
x_3 = 0
x_4 = 0
x_5 = 0
x_6 = 0
x_7 = 0
x_8 = 0
x_9 = 0
x_10= 0
x_11 = 1
x_12 = 0
x_13 = 0
.
.
.
我猜你是从the example in the documentation那里拿来的参数设置?这些参数将使 CPLEX 枚举所有 optimal 解。如果您想要 所有 个解决方案,您必须将解决方案池差距设置为非常大的值。
CPLEX 有很多生成解的方法,但它大致遵循通过启发式方法增强的标准分支定界方案。
当然,解决方案对每个变量都有一个值。如果您只需要某些变量,那么您可以使用 Python 提供的各种过滤和理解类型。例如,要获取解决方案中为 1 的二进制变量的索引,您可以这样做:
indices = [j for j, a in enumerate(cpx.solution.pool.get_values(i)) if a > 0.5]
编辑: 看到 运行 代码后,我们发现了问题所在:
代码只设置了绝对间隙参数,应该同时设置相对间隙参数。
代码设置参数如
cpx.solnpoolintensity = 4
。这不是设置参数的正确方法。该语句只会在对象中创建一个新的 属性,其余代码将忽略它。
为枚举(最多)4000 个解决方案设置参数的正确方法是
cpx.parameters.mip.pool.intensity.set(4)
cpx.parameters.mip.pool.absgap.set(1e75)
cpx.parameters.mip.pool.relgap.set(1e75)
cpx.parameters.mip.limits.populate.set(4000)