从求解器内部基于IntVar的数组中获取值的方法是使用MakeElement()
函数,在此例中为2d version。
通过这种方式,您可以从矩阵中获取特定值,但不是基于两个IntVars(例如矩形的x-dx)的范围。要完成范围部分,您可以使用循环和ConditionalExpression()
来确定指定值是否在范围内。
例如,在一维数组中,为了从data
得到的元素,位置x
到x + dx
将如下
int[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IntVar x = solver.MakeIntVar(0, data.Length - 1);
IntVar dx = solver.MakeIntVar(1, data.Length);
solver.Add(x + dx <= data.Length);
IntVarVector range = new IntVarVector();
for (int i = 0; i < dx.Max(); i++)
{
range.Add(solver.MakeConditionalExpression((x + i < x + dx).Var() , solver.MakeElement(data, (x + i).Var()), 0).Var());
}
solver.Add(range.ToArray().Sum() <= 10);
在2D阵列的情况下(如在问题),那么你只是迭代通过两个维度。唯一不同的是,MakeElement()
的二维版本接受IndexEvaluator2
项(C#中的LongLongToLong
),因此您必须创建自己的类继承LongLongToLong
并覆盖Run()
函数。
class DataValues: LongLongToLong
{
private int[,] _data;
private int _rows;
private int _cols;
public DataValues(int[,] data, int rows, int cols)
{
_rows = rows;
_cols = cols;
_data = data;
}
public override long Run(long arg0, long arg1)
{
if (arg0 >= _rows || arg1 >= _cols)
return 0;
return _data[arg0, arg1];
}
}
这一类唯一的问题是,它可以要求关闭阵列的值,所以我们必须if (arg0 >= _rows || arg1 >= _cols)
处理它自己。
P.S.我不知道这是否是实现它的最好方法,但这是我能想到的最好的方法,因为我在网上找不到任何类似的东西。