微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Google ORTools CP-SAT |从 ortools 变量列表中获取 1 的索引列表

如何解决Google ORTools CP-SAT |从 ortools 变量列表中获取 1 的索引列表

我想使用 ortools 将 [0,1,0] 转换为 [2,4,6]。

其中第二个列表中的“2”、“4”、“6”是第一个列表中“1”的索引。

使用下面的代码我可以得到一个列表 [0,2,6,0]。我怎样才能得到 [2,6]?

from ortools.sat.python import cp_model


model = cp_model.CpModel()
solver = cp_model.cpsolver()

work = {}
days = 8
horizon = 7
for i in range(days):
    work[i] = model.NewBoolVar("work(%i)" % (i))

model.Add(work[0] == 0)
model.Add(work[1] == 0)
model.Add(work[2] == 1)
model.Add(work[3] == 0)
model.Add(work[4] == 1)
model.Add(work[5] == 0)
model.Add(work[6] == 1)
model.Add(work[7] == 0)


v1 = [model.NewIntvar(0,horizon,"") for _ in range(days)]
for d in range(days):
    model.Add(v1[d] == d * work[d])


status = solver.solve(model)
print("status:",status)

vec = []
for i in range(days):
    vec.append(solver.Value(work[i]))
print("work",vec)
vec = []
for v in v1:
    vec.append(solver.Value(v))
print("vec1",vec)

您应该在控制台上看到此输出

status: 4
work [0,0]
vec1 [0,0]

谢谢。


编辑: 我也希望得到 [4,2] 的结果。

解决方法

对于只有 3 个变量,这很容易。在伪代码中:

  • 最大索引为 max(work[i] * i)
  • 最小索引为 min(horizon - (horizon - i) * work[i])
  • 媒介是sum(i * work[i]) - max_index - min_index

但那是作弊。

如果您想要超过 3 个变量,您将需要布尔变量的并行数组,以指示每个变量的等级。

让我勾勒出完整的解决方案。

您需要构建一个图表。 X 轴是变量。为什么轴是等级。你有向右的水平弧线,向右和向上的对角线弧线。如果选择变量,则需要使用对角弧,否则使用水平弧。

如果使用对角弧,则将当前变量分配给弧尾的秩。

然后需要添加约束使其成为连续路径:

  • 每个节点的质量守恒
  • 选择了变量 -> 必须选择对角弧之一
  • 未选择变量 -> 必须选择水平弧之一
  • 左下节点有一个输出弧
  • 右上角的节点有一个传入弧

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。