Ошибка OR-Tools: невозможно преобразовать лямбда-выражение в тип '...', поскольку оно не является делегатом - PullRequest
0 голосов
/ 31 января 2019

При попытке запустить пример: VrpTimeWindows из Google OR-Tools , следующий блок кода генерирует ошибку:

int transitCallbackIndex = routing.RegisterTransitCallback(
      (long fromIndex, long toIndex) => {
        // Convert from routing variable Index to time matrix NodeIndex.
        var fromNode = manager.IndexToNode(fromIndex);
        var toNode = manager.IndexToNode(toIndex);
        return data.GetTimeMatrix()[fromNode, toNode]; }
    );

ОшибкаCS1660: Невозможно преобразовать лямбда-выражение в тип 'SWIGTYPE_p_std__functionT_long_long_flong_long_long_longF_t', поскольку это не тип делегата

Я использую последнюю доступную версию: 7.0-beta.1

1 Ответ

0 голосов
/ 31 января 2019

Последняя доступная версия ( 7.0-beta.1 ) пока не поддерживает использование лямбда-выражения в качестве аргумента функции транзитного обратного вызова.Тем не менее, он зафиксирован в хранилище кода и будет доступен в следующей версии.

На данный момент, до выпуска нового выпуска, существует два возможных решения:

  • Первое решение заключается в том, что вы можете загрузить последнюю версию OR-Tools и скомпилировать ее на своем компьютере, следуя этим инструкциям для установки из Source.

  • Второе решение заключается в замене аргумента экземпляром производного класса из Google.OrTools.ConstraintSolver.LongLongToLong следующим образом:

        LongLongToLong timeCallback = new TimeCallback(data, manager);
    
        int transitCallbackIndex = routing.RegisterTransitCallback(timeCallback);
    

Где TimeCallback класс может иметьследующая реализация:

class TimeCallback : LongLongToLong
{
    private long[,] timeMatrix;
    private RoutingIndexManager indexManager;
    public TimeCallback(DataModel data, RoutingIndexManager manager)
    {
        timeMatrix = data.GetTimeMatrix();
        indexManager = manager;
    }

    override public long Run(long fromIndex, long toIndex)
    {
        // Convert from routing variable Index to time matrix NodeIndex.
        int fromNode = indexManager.IndexToNode(fromIndex);
        int toNode = indexManager.IndexToNode(toIndex);
        return timeMatrix[fromNode, toNode];
    }
}

Примечание: Для LongLongToLong timeCallback = new TimeCallback(Data, manager); Сборщик мусора может уничтожить этот объект, так как регистр не поддерживает его работу в C # (примечание: это будет изменено в финальной версии 7.0 с использованием делегата иправильно управляющий владением).Чтобы избежать GC, вы должны сделать вызов GC.KeepAlive для объекта TimeCallback после метода SolveWithParameters.


Вот пример использования выше: https://github.com/Muhammad-Altabba/workforce-distribution-sample/

...