ソルバー内のIntVarに基づいて配列から値を取得する方法は、MakeElement()
関数を使用することです。この場合は2d versionです。
このようにして、行列から特定の値を得ることはできますが、2つのIntVars(たとえば、x - dxの長方形)に基づく範囲は得られません。範囲部分を達成するには、ループとConditionalExpression()
を使用して、指定された値が範囲内にあるかどうかを調べることができます。 1D配列の例
は、
data
から要素を取得するために、そしてあなただけの反復(質問のように)2次元配列の場合に
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);
を次のようにx
x + dx
には次のようになり位置します両方の次元を通して。唯一の違いはMakeElement()
の2dバージョンがアイテム(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.これを達成するための最良の方法であるかどうかは分かりませんが、私が考えることのできる最高のものでした。