PuLP CBC 热启动立即接受初始解决方案

问题描述

我目前正在使用带有认 CBC 求解器的纸浆解决调度问题。 问题很大,所以我想使用热启动并为随机可行的初始解决方案设置变量。但是求解器在 0 次迭代后停止,初始解为最优解。我希望求解器从这里开始并寻找更好的解决方

所以我运行了 Pulp Warm Start 文档中的代码示例,同样的事情发生了。我没有触及代码示例。我的 PuLp 安装有问题还是我的热启动想法有问题?

我在 PyCharm python3.8 venv 上运行此代码

https://coin-or.github.io/pulp/guides/how_to_mip_start.html

"""
A set partitioning model of a wedding seating problem
Adaptation where an initial solution is given to solvers: CPLEX_CMD,GUROBI_CMD,PULP_CBC_CMD

Authors: Stuart Mitchell 2009,Franco Peschiera 2019
"""

import pulp

max_tables = 5
max_table_size = 4
guests = 'A B C D E F G I J K L M N O P Q R'.split()


def happiness(table):
    """
    Find the happiness of the table
    - by calculating the maximum distance between the letters
    """
    return abs(ord(table[0]) - ord(table[-1]))


# create list of all possible tables
possible_tables = [tuple(c) for c in pulp.allcombinations(guests,max_table_size)]

# create a binary variable to state that a table setting is used
x = pulp.LpVariable.dicts('table',possible_tables,lowBound=0,upBound=1,cat=pulp.LpInteger)

seating_model = pulp.LpProblem("Wedding Seating Model",pulp.LpMinimize)

seating_model += pulp.lpSum([happiness(table) * x[table] for table in possible_tables])

# specify the maximum number of tables
seating_model += pulp.lpSum([x[table] for table in possible_tables]) <= max_tables,\
                 "Maximum_number_of_tables"

# A guest must seated at one and only one table
for guest in guests:
    seating_model += pulp.lpSum([x[table] for table in possible_tables
                          if guest in table]) == 1,"Must_seat_%s" % guest

# I've taken the optimal solution from a prevIoUs solving. x is the variable dictionary.
solution = {
    ('M','N'): 1.0,('E','F','G'): 1.0,('A','B','C','D'): 1.0,('I','J','K','L'): 1.0,('O','P','Q','R'): 1.0
}
for k,v in solution.items():
    x[k].setinitialValue(v)

solver = pulp.PULP_CBC_CMD(msg=True,warmStart=True)
#solver = pulp.CPLEX_CMD(msg=True,warmStart=True)
#solver = pulp.GUROBI_CMD(msg=True,warmStart=True)
# solver = pulp.CPLEX_PY(msg=True,warmStart=True)
# solver = pulp.GUROBI(msg=True,warmStart=True)
seating_model.solve(solver)


print("The choosen tables are out of a total of %s:" % len(possible_tables))
for table in possible_tables:
    if x[table].value() == 1.0:
        print(table)

结果输出

Welcome to the CBC MILP Solver 
Version: 2.9.0 
Build Date: Feb 12 2015 

command line - /Users/nicoelbert/Documents/GitHub/WueExam/venv/lib/python3.8/site-packages/pulp/apis/../solverdir/cbc/osx/64/cbc /var/folders/mv/pmsgdhgx6tqdpnq2sy_5k75h0000gn/T/d157dc1b36df4498a14efa89fb14865a-pulp.mps mips /var/folders/mv/pmsgdhgx6tqdpnq2sy_5k75h0000gn/T/d157dc1b36df4498a14efa89fb14865a-pulp.mst branch printingOptions all solution /var/folders/mv/pmsgdhgx6tqdpnq2sy_5k75h0000gn/T/d157dc1b36df4498a14efa89fb14865a-pulp.sol (default strategy 1)
At line 2 NAME          MODEL
At line 3 ROWS
At line 23 COLUMNS
At line 24708 RHS
At line 24727 BOUNDS
At line 27941 ENDATA
Problem MODEL has 18 rows,3213 columns and 15062 elements
Coin0008I MODEL read with 0 errors
will open mipstart file /var/folders/mv/pmsgdhgx6tqdpnq2sy_5k75h0000gn/T/d157dc1b36df4498a14efa89fb14865a-pulp.mst.
mipstart values read for 3213 variables.
Continuous objective value is 12 - 0.01 seconds
Cgl0004I processed model has 18 rows,3213 columns (3213 integer (3213 of which binary)) and 15062 elements
Cutoff increment increased from 1e-05 to 0.9999
Cbc0045I mipstart provided solution with cost 12
Cbc0006I The LP relaxation is infeasible or too expensive
Cuts at root node changed objective from 1.79769e+308 to -1.79769e+308
Probing was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Gomory was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Knapsack was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Clique was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
MixedIntegerRounding2 was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
FlowCover was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
TwoMirCuts was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Cgl0013I Postprocessed model is infeasible - possible tolerance issue - try without preprocessing
17 relaxed row infeasibilities - summing to 17
17 relaxed row infeasibilities - summing to 17
17 relaxed row infeasibilities - summing to 17

Result - Optimal solution found

Objective value:                12.00000000
Enumerated nodes:               0
Total iterations:               0
Time (cpu seconds):             0.06
Time (Wallclock seconds):       0.07

Option for printingOptions changed from normal to all
Total time (cpu seconds):       0.07   (Wallclock seconds):       0.09

The choosen tables are out of a total of 3213:

Process finished with exit code 0

解决方法

@kabdulla,问题出在这个例子中——即使你将初始解决方案更改为非最佳解决方案:

Cbc0038I 0.05 秒后 - 可行性泵退出,目标为 12 - 耗时 0.01 秒 Cbc0012I 可行性泵在 0 次迭代和 0 个节点(0.05 秒)后找到的 12 的整数解 Cbc0001I 搜索已完成 - 最佳目标 12,进行了 0 次迭代和 0 个节点(0.05 秒)

所以它正在做这些“预先解决”的事情,并在它甚至考虑初始解决方案之前达到最佳状态。我们需要一个新的热启动例子,因为很多人在 CBC 工作时无法热启动,他们来这里是为了一个例子