如何基于决策变量(一个用于行,一个用于列)从矩阵(python 中的列表列表)中选择一个元素 | 或工具,Python

Bha*_*thi 1 constraint-programming or-tools

我是约束编程和 OR-Tools 的新手。关于问题的简要说明。有 8 个位置,对于每个位置,我需要决定应选择哪种类型 A (move_A) 的移动和类型 B (move_B) 的移动,以便从 2 个移动的组合(在每个位置)获得的值是最大化。(虽然这只是更大问题的一部分)。我想用AddElement方法来做子设置。

请看下面的尝试

from ortools.sat.python import cp_model
model = cp_model.CpModel()

# value achieved from combination of different moves of type A
# (moves_A (rows)) and different moves of type B (moves_B (columns))
# for e.g. 2nd move of type A and 3rd move of type B will give value = 2
value = [
            [ -1,  5,  3,  2,  2],
            [  2,  4,  2, -1,  1], 
            [  4,  4,  0, -1,  2],
            [  5,  1, -1,  2,  2],
            [  0,  0,  0,  0, 0],
            [  2,  1,  1,  2, 0]
       ]

# 6 moves of type A
num_moves_A = len(value)

# 5 moves of type B
num_moves_B = len(value[0])

num_positions = 8

type_move_A_position = [model.NewIntVar(0, num_moves_A - 1, f"move_A[{i}]") for i in range(num_positions)]

type_move_B_position = [model.NewIntVar(0, num_moves_B - 1, f"move_B[{i}]") for i in range(num_positions)]

value_position = [model.NewIntVar(0, 10, f"value_position[{i}]") for i in range(num_positions)]

# I am getting an error when I run the below
objective_terms = []
for i in range(num_positions):
    model.AddElement(type_move_B_position[i], value[type_move_A_position[i]], value_position[i])
    objective_terms.append(value_position[i])

Run Code Online (Sandbox Code Playgroud)

错误如下:

Traceback (most recent call last):

  File "<ipython-input-65-3696379ce410>", line 3, in <module>
    model.AddElement(type_move_B_position[i], value[type_move_A_position[i]], value_position[i])

TypeError: list indices must be integers or slices, not IntVar
Run Code Online (Sandbox Code Playgroud)

在 MiniZinc 中,下面的代码会起作用

var int: obj = sum(i in 1..num_positions ) (value [type_move_A_position[i], type_move_B_position[i]])
Run Code Online (Sandbox Code Playgroud)

我知道在 OR-Tools 中,我们必须先创建一些中间变量来存储结果,因此上面的 minizinc 方法将不起作用。但我正在努力这样做。

我总是可以创建一个二进制二进制变量的 2 矩阵,一个用于 num_moves_A * num_positions,另一个用于 num_moves_B * num_positions,添加相关约束并达到目的

但我想学习如何通过AddElement约束来做同样的事情

AddElement非常感谢有关如何重写代码段的任何帮助。谢谢。

Lau*_*ron 5

AddElement 仅为一维。它从 minizinc 转换为 CP-SAT 的方式是创建一个中间变量p == index1 * max(index2) + index2并将其用于具有扁平矩阵的元素约束中。