or-tools: преобразовать выражение BoundIntegerExx в выражение IntegerExpression - PullRequest
0 голосов
/ 12 апреля 2019

Я использую Google.OrTools версия 7.0.


Я создал небольшой интерфейс, чтобы добавить ограничения к CpModel:

public interface ISatConstraintWrapper
{
    IEnumerable<BoundIntegerExpression> GenerateConstraints();
    void BindToModel(CpModel model);
} 

Шаблон проектирования довольно прост, вот фиктивный пример, который устанавливает равенство для всех IntVar s в списке:

class MakeAllVarsEqual : ISatConstraintWrapper
{
    public MakeAllVarsEqual(List<IntVar> vars)
    {
        _vars = vars;
    }

    public IEnumerable<BoundIntegerExpression> GenerateConstraints()
    {
        for (var i = 0; i < _vars.Count - 1; i++)
        {                
            yield return _vars[i] == _vars[i+1];
        }
    }

    public void BindToModel(CpModel model)
    {
        foreach (var constraint in GenerateConstraints())
        {
            model.Add(constraint);
        }
    }

    private readonly List<IntVar> _vars;
}

Далее, я хотел бы использовать мой ISatConstraintWrapper, но для минимизации / максимизации ограничений.

Вот пример того, что я собираюсь сделать:

class MinimizeIntExpression : ISatConstraintWrapper
{
    public MinimizeIntExpression(List<IntVar> vars, List<int> coeffs)
    {
        _vars = vars;
        _coeffs = coeffs;
    }

    public IEnumerable<BoundIntegerExpression> GenerateConstraints()
    {
        for (var i = 0; i < _vars.Count; i++)
        {                
            yield return _vars[i]*_coeffs[i];
        }
    }

    public void BindToModel(CpModel model)
    {
        model.Minimize(new SumArray(GenerateConstraints()));
    }

    private readonly List<IntVar> _vars;
    private readonly List<int> _coeffs;
}

Но я не могу, поскольку _vars[i]*_coeffs[i] возвращает IntegerExpression, но не BoundIntegerExpression.

Однако, даже если последний представляет IntegerExpression в домене, эти два класса кажутся несвязанными, и я не нашел способа снизить BoundIntegerExpression до IntegerExpression.

Конечно, я мог бы создать два разных интерфейса, но это не очень удобно, например, если я хочу сохранить свои обертки ограничений в списке.


Можно ли преобразовать BoundIntegerExpression в IntegerExpression? Если нет, как я могу изменить свою оболочку для обработки обоих типов ограничений?

1 Ответ

0 голосов
/ 12 апреля 2019

Вы не можете.

Предлагаю вам прочитать:

https://github.com/google/or-tools/blob/stable/ortools/sat/doc/channeling.md

...