Матрица решений в Microsoft Solver Foundation
Я пытаюсь использовать Microsoft Solver Foundation для оптимизации проблемы с матрицей двоичных переменных решения. Вот формат моей матрицы решений:
X[i,j] =
{
{ x11, x12, ..., x1n },
{ x21, x22, ..., x2n },
...
{ xm1, xm2, ..., xmn },
};
У меня также есть вектор параметров, который зависит от матрицы Xij (каждый элемент вектора является суммой одного столбца Xij:
Y[i] =
{
Sum(x11, x21, ..., xm1), Sum(x12, x22, ..., xm2), ..., Sum(x1n, x2n, ..., xmn)
}
Я знаю, что мне следует работать с индексированными объектами Decision, но у меня возникают проблемы с этим. Может ли кто-нибудь, пожалуйста, помогите мне. Я понимаю, что существует два способа индексации решений:
Decision Xij = new Decision(Domain.Any, "x", Some Set, Some other set);
а также есть:
`Decision[,] = new Decsion [i, j];`
Какая разница?
2 ответа
Да, вы можете использовать C#
массив для определения нескалярной переменной Decision или использования индексированных объектов Decision, как объяснено в блоге Натана Бриксиуса.
Там могут быть лучшие способы сделать это, но я бы определил один Sum
ограничение для каждого элемента в вашем параметре вектора Y[i]
, Вектор параметра или его элементы могут быть определены как переменные решения или вы можете объявить их как объекты Term, что может быть более эффективным.
Имейте в виду, что Microsoft, похоже, больше не работает над Solver Foundation. Так что, возможно, имеет смысл поискать другие решатели. Мой личный фаворит - MiniZinc, но это, безусловно, зависит от типа решаемой проблемы. Некоторые люди предпочитают Google OR-Tools.
Я создал 2D-массивы для Xij следующим образом:
static Decision[,] XijMatrix()
{
Decision[,] d = new Decision[int rows, int cols];
for (int row = 0; row < rows; row++)
for (int col = 0; col < cols; col++)
d[row, col] = new Decision(Domain.Boolean, "X" + row + col);
return d;
}
и еще один массив для Yj:
static Decision[,] YjMatrix()
{
Decision[,] d = new Decision[1, int cols];
for (int col = 0; col < cols; col++)
d[0, col] = new Decision(Domain.Boolean, "Y" + col);
return d;
}
и чтобы связать эти две матрицы вместе, я добавил ограничение для moedl:
for (int i = 0; i < Yj.GetLength(1); i++)
{
model.AddConstraint("C" + i, Yj[0, i] == matColSum(Xij, i));
}
и matColSum используется для добавления элементов столбца (i):
static Term matColSum(Decision[,] Xij, int i)
{
Term r = Xij[0, i];
for (int row = 1; row < Xij.GetLength(0); row++)
{
r += Xij[row, i];
}
return r;
}
Теперь это создает матрицу Xij, которая в каждом столбце имеет только одно истинное значение (1); Это похоже на то, что matColSum рассматривает элементы Xij и Yj как целые числа! Что я делаю неправильно? Я не понимаю