Фонд Microsoft Solver по модулю оператора

Я пытаюсь добавить базовое ограничение в основание своего решателя следующим образом:

model.AddConstraint("c1", x % y == 0);

Я получаю ошибку компиляции, в которой говорится, что "Оператор"% "не может быть применен к операндам типа"Microsoft.SolverFoundation.Services.Decision "и"Microsoft.SolverFoundation.Services.Decision ".

Это имеет смысл, поскольку многие операторы не поддерживаются. Тем не менее, многие операторы, которые не поддерживаются (sin, cos, tan и т. Д.), Доступны в качестве специальных методов для класса Model, например ниже:

model.AddConstraint("c1", Model.Sum(x,y) == 0);

Если я заменю "Sum" на "Mod", метод не будет доступен.

Есть идеи, как выполнить операцию по модулю в Solver Foundation? Согласно документации здесь, это поддерживается.

Я собираюсь начать использовать рефлектор, чтобы копаться в коде, но я решил опубликовать его здесь. Если я найду решение, я обновлю свой вопрос, чтобы включить ответ.

2 ответа

Я не вижу мод на http://msdn.microsoft.com/en-us/library/ff525341(v=vs.93).aspx, но вот обходной путь:

Model.Floor(Model.Quotient(x,y))==Model.Ceiling(Model.Quotient(x,y))

Это верно только в том случае, если x / y является целым числом, и поэтому x%y==0.

Существуют также другие способы объединения разрешенных операторов, чтобы проверить, делится ли это. Мой любимый (хотя я бы не рекомендовал его из-за точности с плавающей запятой)

Model.Sin(Math.PI*Model.Quotient(x,y))==0 

Действительно интересно, я хотел написать точно такой же вопрос на SO:-)

Я обнаружил, что оператор Mod определен для языка OML по адресу http://msdn.microsoft.com/en-us/library/ff818505(v=vs.93).aspx.

Существует перегрузка метода AddConstraint, который принимает строку выражения (я полагаю, выражение OML?) Вместо Term. К сожалению, я не знаю правильного форматирования, но как только у нас получится разбить его, мы сможем использовать и все остальные операторы.

РЕДАКТИРОВАТЬ

Похоже, что не все выражения OML, описанные в API, работают. Например,

SolverContext sc = SolverContext.GetContext();
Model m = sc.CreateModel();

m.AddDecision(new Decision(Domain.IntegerRange(0,10), "a"));
m.AddDecision(new Decision(Domain.IntegerRange(0, 10), "b"));

m.AddConstraint(null, "a > 0");
m.AddConstraint(null, "b == Plus[a,2]");

Плюс [x,y] в этом случае работает, и решатель вычисляет следующее решение

а: 1, б: 3

Но если я заменю последнее ограничение этим

m.AddConstraint(null, "b == Mod[a,2]");

Я получаю OmlParseException ("Не удалось проанализировать модель OML. Выражение: Mod[a,2]."). Я думаю, что мы здесь сами по себе и, пожалуй, лучшее, что мы можем сделать, это придерживаться ответа пользователя 141603.

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