目标函数限制和自由上下界的区别

(可分区分器为以下实例,不可能差分和零相关也类似)

  • 限制的情况:
        ALL_BITS = 64
        for i in range(1, ALL_BITS)[::-1]:
            m.addConstr(x[0, i] == 1, name='')
        m.addConstr(x[0, 0] == 0, name='')

这种情况下,已经限制了某些变量的值,其不会因为求解器偏向最优解而造成某些判定解为某个 target 时的无解情况。比如,假设设置目标为

model.setObjective(sum(x[r, i]) for i in range(64), GRB.MIMIMIZE)

此时选定 x[0,i],i in range(64) 为固定值,在更新模型时仍保持这些值不变,且以上为最大 63 个 1,也即最可能有解情况,更新模型,每次更新更接近有解(因为自由度已经放到最大,如果始终无解则区分器不存在)

  • 自由放缩
m.addConstr(1 <= sum(x[0, i] for i in range(64)), name='')
m.addConstr(sum(x[0, i] for i in range(64)) <= 63, name='')

这种约束一般不会设置自由度最大的情况,假设只有当 x[0,i]==1 for i in range(1,64) 时才有解,而其余情况均无解。求解器为了尽快满足目标函数会取某些(>1) 个位置为 0,而其余位置均为1,这会因为自由度不够无法找到该轮的区分器,因为在更新模型时,自由度始终 < 63.