Основа решателя, странное поведение

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SolverFoundation.Services;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var context= SolverContext.GetContext();
            var model = context.CreateModel();

            var index = new Set(Domain.IntegerRange(0, 6), "index");

            var x = new Decision(Domain.IntegerRange(0, 5), "x", index);
            model.AddDecision(x);

            // When I uncomment the following line, values ends
            // up with only 3 elements instead of 7 as expected

            // model.AddConstraint("constraint", x[0] + x[1] + x[2] == 2);

            model.AddGoal("objective", GoalKind.Minimize, Model.Sum(Model.ForEach(index, i => Model.Power(x[i] - 2, 2))));

            context.Solve();
            var values = x.GetValues().ToArray();
        }
    }
}

Если я запускаю этот код как есть, Solver Foundation правильно вычисляет семь значений, каждое из которых равно 2.

Когда я раскомментирую model.AddConstraint("constraint", x[0] + x[1] + x[2] == 2), в конце values ​​содержится только три значения: 0, 1 и 1. Почему он не содержит остальные значения?

В чем дело?


person ehremo    schedule 12.02.2014    source источник
comment
Вы пытались решить ту же модель с помощью OML и утилиты командной строки?   -  person denfromufa    schedule 13.02.2014
comment
Нет, я этого не сделал. TBH Я не знаю, как использовать эти инструменты, и я не хочу тратить время на их изучение, когда приведенный выше код должен работать. В любом случае спасибо за подсказку.   -  person ehremo    schedule 13.02.2014


Ответы (1)


Когда я запускаю ваш пример с активным ограничением, он предлагает 0+1+1 в качестве решения и опускает x[3] .. x[6]. Это похоже на ошибку. Все они должны иметь значение 2.

Добавьте следующие строки для отображения результатов:

foreach (object[] value in values)
   {
       Console.WriteLine("x[{0}] = {1}", value[1], value[0]);
   }

Возможно, блог Натана Бриксиуса может дать некоторую информацию.

После добавления следующего фиктивного ограничения я снова получил полный набор переменных:

    model.AddConstraint("constraint2", (x[3] + x[4] + x[5] + x[6]) < 999);

В качестве альтернативы вы можете обратиться к MiniZinc и использовать такую ​​простую модель:

set of int: ix = 0..6;
array[ix] of var 0..5: x;

constraint
    x[0] + x[1] + x[2] == 2;

solve minimize sum(i in ix)((x[i] - 2)*(x[i] - 2));

output 
["\nx[" ++ show(i) ++ "] = " ++ show(x[i]) | i in ix] ;
person Axel Kemper    schedule 23.02.2014