【问题标题】:How to increase number of Cplex solutions?如何增加 Cplex 解决方案的数量?
【发布时间】:2020-03-24 18:54:48
【问题描述】:

我有 this cplex 模型,它有 1 个二进制变量 (x_i)。现在我有 2 个关于其 cplex 解决方案的问题(我将它们放在一篇文章中,因为它们是相关的)。

首先:对于我的模型,我得到了 26 个解决方案,但我知道实际上还有更多解决方案。如何在 cplex 中生成解决方案?有什么办法可以增加解的数量吗?

第二:我想使用解决方案池访问所有解决方案,但是当我尝试打印所有解决方案时,它会打印所有现有变量(显然我只需要等于 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
.
.
.

【问题讨论】:

    标签: python-3.x cplex docplex


    【解决方案1】:

    我猜你是从the example in the documentation那里拿来参数设置的吧?这些参数将使 CPLEX 枚举所有最优解。如果您想要所有解决方案,则必须将解决方案池差距设置为非常大的值。

    CPLEX 有多种生成解决方案的方法,但大致遵循启发式增强的标准分支定界方案。

    当然,解决方案对每个变量都有一个值。如果您只想要某些变量,那么您可以使用 Python 提供的各种过滤和理解类型。例如,要获取解决方案中为 1 的二进制变量的索引,您可以这样做:

    indices = [j for j, a in enumerate(cpx.solution.pool.get_values(i)) if a > 0.5]
    

    编辑:查看并运行代码后,我们发现问题所在:

    1. 代码只设置了绝对间隙参数,还需要设置相对间隙参数。

    2. 代码设置参数如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)
    

    【讨论】:

    • 是的,我正在使用它。间隙必须有多大?我输入了 90000000000000000000000000000000000000000000000000 但我得到了相同的结果。
    • 通常默认值 1e75 应该没问题。也许没有更多的解决方案?如果您使用完整模型(例如导出到 LP 或 SAV)或完整代码和数据更新您的问题,那么我们可以检查是否有更多解决方案或您的代码有什么问题。
    • 嗯,我有大约 400 件 ilst 物品。当我为所有解决方案运行时,该程序会找到 26 个解决方案。但是当我为其中的 50 个项目运行程序时,它显示了 40 个解决方案!
    • 我不明白为什么更多的项目通常会提供更多的解决方案。同样,如果您希望我们更深入/更深入地研究这一点,您将必须提供一个最小的工作示例代码来说明该问题。此外,如果您可以指定可行且 CPLEX 找不到的解决方案,那将是很好的选择。换句话说,证明 CPLEX 是错误的。
    • 有什么私密的方式可以和你分享我的代码吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多