检查 Docplex CP 解决方案中的可行性和未满足的约束

Checking for feasibility and unsatisfied constraints in Docplex CP solutions

当我在 docplex 中创建 mp 模型时,我可以检查解决方案是否可行,并可以显示不可行解决方案的未满足约束:

from docplex.cp.model import CpoModel 
from docplex.mp.model import Model

mp_model = Model('MP')
mp_x = mp_model.integer_var(0, 10, "x")

mp_model.add_constraint(mp_x <= 5)
mp_model.add_constraint(mp_x <= 2)

possible_mp_solution = mp_model.new_solution()
possible_mp_solution.add_var_value(mp_x,3) 

print(possible_mp_solution.find_unsatisfied_constraints(mp_model))

CP 是否可能相同(或类似)?我知道您可以创建解决方案以使用 为起点,但我正在寻找一种方法来获取有关可能解决方案的信息。

cp_model = CpoModel(name='CP')
cp_x = cp_model.integer_var(0, 10, "x")

cp_model.add_constraint(cp_x <= 5)
cp_model.add_constraint(cp_x <= 2)


possible_cp_solution = cp_model.create_empty_solution()
possible_cp_solution.set_value(cp_x,3)

# does not exist
# print(possible_cp_solution.find_unsatisfied_constraints(cp_model))

在 CP Optimizer 中不能直接根据模型检查解决方案,但您可以将解决方案作为附加约束添加到模型和 运行 冲突优化器中。这将找到解释解决方案不可行的原因的“一个”约束,以及变量分配的子集。

这是您的示例的插图:

from docplex.cp.model import *

# Assumes solution only contains fixed integer or interval variables
def solution_as_constraints(sol) :
    cts = []
    vars = sol.get_all_var_solutions()
    for v in vars:
        if isinstance(v, CpoIntVarSolution):
            cts.append(v.get_expr() == v.get_value())
        elif isinstance(v, CpoIntervalVarSolution):
            if v.is_present():
                cts.append(presence_of(v.get_expr()))
                cts.append(start_of(v.get_expr()) == v.get_start())
                cts.append(end_of  (v.get_expr()) == v.get_end())
                cts.append(size_of (v.get_expr()) == v.get_size())
            else:
                cts.append(presence_of(v.get_expr())==0)
    return cts

cp_model = CpoModel(name='CP')
cp_x = cp_model.integer_var(0, 10, "x")

cp_model.add_constraint(cp_x <= 5)
cp_model.add_constraint(cp_x <= 2)

possible_cp_solution = cp_model.create_empty_solution()
possible_cp_solution.set_value(cp_x,3)

cp_model.add(solution_as_constraints(possible_cp_solution))
if not cp_model.solve():
    cp_model.refine_conflict().write()

你会得到类似的东西:

Conflict refiner result (TerminatedNormally):
Member constraints:
   x == 3
   x <= 2