Матрица решений в 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 как целые числа! Что я делаю неправильно? Я не понимаю

Другие вопросы по тегам