OR-Tools Error: Cannot convert lambda expression to type '...' because it is not a delegate type

OR-Tools Error: Cannot convert lambda expression to type '...' because it is not a delegate type

尝试 运行 示例时:VrpTimeWindows of 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]; }
    );

Error CS1660: Cannot convert lambda expression to type 'SWIGTYPE_p_std__functionT_long_long_flong_long_long_longF_t' because it is not a delegate type

我使用的是可用的最新版本:7.0-beta.1

最新可用版本(7.0-beta.1) does not yet support using the lambda expression as an argument to the transit call back function. However, it is committed to the code repository并将在下一版本中提供。

目前,在新版本可用之前,有两种可能的解决方案:

  • 第一种解决方法是可以下载最新版的 OR-Tools 并按照 those 在你的机器上编译它 从源安装的说明

  • 第二个解决方案是用实例替换参数 从 Google.OrTools.ConstraintSolver.LongLongToLong 派生的 class 如下:

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

其中 TimeCallback class 可以有以下实现:

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,您必须在 SolveWithParameters 方法之后对 TimeCallback 对象调用 GC.KeepAlive


下面是使用上面的示例:https://github.com/Muhammad-Altabba/workforce-distribution-sample/