早上好,
我正在尝试找到一种方法来使用或工具将 IntervalVars 转换为 BooleanVars 列表,以便将二进制列表用作一种字段,其中布尔值指示时间间隔在时间 0 和地平线之间的窗口中的位置。我只使用一个间隔,即当我打印所有解决方案时,它会显示所有可能位置的间隔:
所有组合/解决方案:
[
[0, 0, 1, 1, 0],
[0, 1, 1, 0, 0],
[0, 0, 0, 1, 1],
[1, 1, 0, 0, 0]
]
工作模式:
duration = 2
horizon = 5
model = cp_model.CpModel()
bool_vars = []
start_var = model.NewIntVar(0, horizon, "start")
interval_var = model.NewFixedSizeIntervalVar(start_var, duration, "interval")
for i in range(horizon):
bool_var = model.NewBoolVar(f"bool_{i}")
model.Add(interval_var.StartExpr() <= i).OnlyEnforceIf(bool_var)
model.Add(interval_var.EndExpr() > i).OnlyEnforceIf(bool_var)
bool_vars.append(bool_var)
model.Add(sum(bool_vars) == duration)
现在,如果我尝试将此方法扩展到两个间隔,它将不起作用。
durations = [1,2]
horizon = 5
model = cp_model.CpModel()
bool_vars = [model.NewBoolVar(f"bool_{i}") for i in range(horizon)]
for duration in durations:
start_var = model.NewIntVar(0, horizon, f"start_{duration}")
interval_var = model.NewFixedSizeIntervalVar(start_var, duration, f"interval_{duration}")
for i in range(horizon):
model.Add(interval_var.StartExpr() <= i).OnlyEnforceIf(bool_vars[i])
model.Add(interval_var.EndExpr() > i).OnlyEnforceIf(bool_vars[i])
model.Add(sum(bool_vars) == sum(durations))
我怀疑它的线条
model.Add(interval_var.StartExpr() <= i).OnlyEnforceIf(bool_var)
model.Add(interval_var.EndExpr() > i).OnlyEnforceIf(bool_var)
我知道我缺少一些基本的东西,但目前我想不出另一种解决方案
任何意见和批评表示赞赏!<3
我在当前步骤中试图解决的具体问题是:
修改当前方法(使用 Google OR 工具),以便:给定持续时间列表和范围,找到所有可能的组合。具有序列由间隙/暂停与 . 分隔的约束duration_of_gap >= 1
。
示例 1:
inputs:
durations = [1,2]
horizon = 5
solution:
combinations = [
[1, 0, 1, 1, 0],
[1, 0, 0, 1, 1],
[0, 1, 0, 1, 1],
]
示例 2:
inputs:
durations = [3,1,2]
horizon = 10
solution:
combinations = [
[1, 1, 1, 0, 1, 0, 1, 1, 0, 0],
[1, 1, 1, 0, 1, 0, 0, 1, 1, 0],
[1, 1, 1, 0, 1, 0, 0, 0, 1, 1],
[1, 1, 1, 0, 0, 1, 0, 1, 1, 0],
[1, 1, 1, 0, 0, 1, 0, 0, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 0, 1, 1],
[0, 1, 1, 1, 0, 1, 0, 1, 1, 0],
[0, 1, 1, 1, 0, 1, 0, 0, 1, 1],
[0, 1, 1, 1, 0, 0, 1, 0, 1, 1],
[0, 0, 1, 1, 1, 0, 1, 0, 1, 1]
]