Closed GuyBenhaim closed 4 years ago
This was working fine with 6.X, can we duplicate what was done in that makefile? Any 7.X (0<X<5) that is expected to work?
Which Target Framework Moniker are you using ? We moved to .Net Core around 6.X to 7.X IIRC
@Mizux , For 6.X I was using .Net Framework 4.5.2 for 7.5 I'm using .Net Framework 4.7.2 I understood that from 7.4 both Core and .NetFramework are supported.
Is a hotfix planned for this issue? I just have waited for 7.5 to fix the signing issue. Now its fixed but or-tools still seems unusable for .net web projects
Currently investigating what's going wrong when the packages were built...
Thx! Let me know if there is something I could/should do from my side. Guy
seems to be an issue with net452 VrpStartsEnds.cs
// [START program]
// [START import]
using System;
using System.Collections.Generic;
using Google.OrTools.ConstraintSolver;
// [END import]
/// <summary>
/// Minimal TSP using distance matrix.
/// </summary>
public class VrpStartsEnds {
// [START data_model]
class DataModel {
public long[,] DistanceMatrix = {
{0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662},
{548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210},
{776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754},
{696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358},
{582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244},
{274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708},
{502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480},
{194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856},
{308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514},
{194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468},
{536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354},
{502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844},
{388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730},
{354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536},
{468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194},
{776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798},
{662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0}
};
public int VehicleNumber = 4;
// [START starts_ends]
public int[] Starts = {1, 2, 15, 16};
public int[] Ends = {0, 0, 0, 0};
// [END starts_ends]
};
// [END data_model]
// [START solution_printer]
/// <summary>
/// Print the solution.
/// </summary>
static void PrintSolution(
in DataModel data,
in RoutingModel routing,
in RoutingIndexManager manager,
in Assignment solution) {
// Inspect solution.
long maxRouteDistance = 0;
for (int i = 0; i < data.VehicleNumber; ++i) {
Console.WriteLine("Route for Vehicle {0}:", i);
long routeDistance = 0;
var index = routing.Start(i);
while (routing.IsEnd(index) == false) {
Console.Write("{0} -> ", manager.IndexToNode((int)index));
var previousIndex = index;
index = solution.Value(routing.NextVar(index));
routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0);
}
Console.WriteLine("{0}", manager.IndexToNode((int)index));
Console.WriteLine("Distance of the route: {0}m", routeDistance);
maxRouteDistance = Math.Max(routeDistance, maxRouteDistance);
}
Console.WriteLine("Maximum distance of the routes: {0}m", maxRouteDistance);
}
// [END solution_printer]
public static void Main(String[] args) {
// Instantiate the data problem.
// [START data]
DataModel data = new DataModel();
// [END data]
// Create Routing Index Manager
// [START index_manager]
RoutingIndexManager manager = new RoutingIndexManager(
data.DistanceMatrix.GetLength(0),
data.VehicleNumber,
data.Starts,
data.Ends);
// [END index_manager]
// Create Routing Model.
// [START routing_model]
RoutingModel routing = new RoutingModel(manager);
// [END routing_model]
// Create and register a transit callback.
// [START transit_callback]
int transitCallbackIndex = routing.RegisterTransitCallback(
(long fromIndex, long toIndex) => {
// Convert from routing variable Index to distance matrix NodeIndex.
var fromNode = manager.IndexToNode(fromIndex);
var toNode = manager.IndexToNode(toIndex);
return data.DistanceMatrix[fromNode, toNode]; }
);
// [END transit_callback]
// Define cost of each arc.
// [START arc_cost]
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
// [END arc_cost]
// Add Distance constraint.
// [START distance_constraint]
routing.AddDimension(transitCallbackIndex, 0, 2000,
true, // start cumul to zero
"Distance");
RoutingDimension distanceDimension = routing.GetMutableDimension("Distance");
distanceDimension.SetGlobalSpanCostCoefficient(100);
// [END distance_constraint]
// Setting first solution heuristic.
// [START parameters]
RoutingSearchParameters searchParameters =
operations_research_constraint_solver.DefaultRoutingSearchParameters();
searchParameters.FirstSolutionStrategy =
FirstSolutionStrategy.Types.Value.PathCheapestArc;
// [END parameters]
// Solve the problem.
// [START solve]
Assignment solution = routing.SolveWithParameters(searchParameters);
// [END solve]
// Print solution on console.
// [START print_solution]
PrintSolution(data, routing, manager, solution);
// [END print_solution]
}
}
// [END program]
VrpStartsEnds.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<LangVersion>7.3</LangVersion>
<TargetFramework>netcoreapp2.1</TargetFramework>
<EnableDefaultItems>false</EnableDefaultItems>
<!-- see https://github.com/dotnet/docs/issues/12237 -->
<RollForward>LatestMajor</RollForward>
<RestoreSources>$(RestoreSources);https://api.nuget.org/v3/index.json</RestoreSources>
<AssemblyName>Google.OrTools.VrpStartsEnds</AssemblyName>
<IsPackable>true</IsPackable>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<GenerateTailCalls>true</GenerateTailCalls>
</PropertyGroup>
<ItemGroup>
<Compile Include="VrpStartsEnds.cs" />
<PackageReference Include="Google.OrTools" Version="7.5.*" />
</ItemGroup>
</Project>
it's working....
if I change in VrpStartsEnds.csproj:
- <TargetFramework>netcoreapp2.1</TargetFramework>
+ <TargetFramework>net452</TargetFramework>
dotnet nuget locals all --clear
dotnet build
dotnet run
Unhandled Exception: System.TypeInitializationException: The type initializer for 'Google.OrTools.ConstraintSolver.operations_research_constraint_solverPINVOKE' threw an exception. ---> System.TypeInitializationException: The type initializer for 'SWIGExceptionHelper' threw an exception. ---> System.DllNotFoundException: Unable to l
oad DLL 'google-ortools-native': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
at Google.OrTools.ConstraintSolver.operations_research_constraint_solverPINVOKE.SWIGExceptionHelper.SWIGRegisterExceptionCallbacks_operations_research_constraint_solver(ExceptionDelegate applicationDelegate, ExceptionDelegate arithmeticDelegate, ExceptionDelegate divideByZeroDelegate, ExceptionDelegate indexOutOfRangeDelegate, Ex
ceptionDelegate invalidCastDelegate, ExceptionDelegate invalidOperationDelegate, ExceptionDelegate ioDelegate, ExceptionDelegate nullReferenceDelegate, ExceptionDelegate outOfMemoryDelegate, ExceptionDelegate overflowDelegate, ExceptionDelegate systemExceptionDelegate)
at Google.OrTools.ConstraintSolver.operations_research_constraint_solverPINVOKE.SWIGExceptionHelper..cctor()
--- End of inner exception stack trace ---
at Google.OrTools.ConstraintSolver.operations_research_constraint_solverPINVOKE.SWIGExceptionHelper..ctor()
at Google.OrTools.ConstraintSolver.operations_research_constraint_solverPINVOKE..cctor()
--- End of inner exception stack trace ---
at Google.OrTools.ConstraintSolver.operations_research_constraint_solverPINVOKE.new_RoutingIndexManager__SWIG_1(Int32 jarg1, Int32 jarg2, Int32 length3, Int32[] jarg3, Int32 length4, Int32[] jarg4)
at VrpStartsEnds.Main(String[] args) in C:\Users\corentinl\work\1862\VrpStartsEnds.cs:line 91
what happens if you put
<TargetFramework>net452;netcoreapp2.1</TargetFramework>
I'd suggest it will find a compromise between the 2 sdk versions
if I copy .nuget\packages\google.ortools.runtime.win-x64\7.5.7466\runtimes\win-x64\native\google-ortools-native.dll
in bin\Debug\net452\google-ortools-native.dll
it works
So it seems in net452 we are missing something...
note: on the contrary we have a bin\Debug\netcoreapp2.1\Google.OrTools.VrpStartsEnds.deps.json
with
"Google.OrTools.runtime.win-x64/7.5.7466": {
"runtimeTargets": {
"runtimes/win-x64/native/google-ortools-native.dll": {
"rid": "win-x64",
"assetType": "native",
"fileVersion": "0.0.0.0"
}
}
},
@m0ddixx you'll need to use <TargetFrameworks>
and basically it compile two times...
oh right. if you fix the issue, is there a chance you upload it to the nuget repository or do we need to wait for the 7.6 release? Latter would mean I have to reschedule some work for my project which would be very helpful to be answered. Thanks in advance for your help
In the proj file I've got:
<Reference Include="Google.Protobuf, Version=3.11.2.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>..\packages\Google.Protobuf.3.11.2\lib\**net45**\Google.Protobuf.dll</HintPath>
</Reference>
I tried building as 4.5.2 and ORT 7.5
The project builds, but after running it the program immediately crashes when reaching: RoutingIndexManager manager = new RoutingIndexManager(number_of_locations, number_of_vehicles, vehiclestarts, vehicleends);
With exception message: Access is denied. (- HRESULT: 0x80070005 (E_ACCESSDENIED))
...
Managed to make it work using:
diff --git a/ortools/dotnet/Google.OrTools.runtime.win-x64/Google.OrTools.runtime.win-x64.csproj.in b/ortools/dotnet/Google.OrTools.runtime.win-x64/Google.OrTools.runtime.win-x64.csproj.in
index 2b7692853..fc187fe9e 100644
--- a/ortools/dotnet/Google.OrTools.runtime.win-x64/Google.OrTools.runtime.win-x64.csproj.in
+++ b/ortools/dotnet/Google.OrTools.runtime.win-x64/Google.OrTools.runtime.win-x64.csproj.in
@@ -29,13 +29,14 @@
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
-
- <!-- For netframework we need to copy the native binary manually during build on Nuget consumer side. That's why we need a separate target file doing this for us. -->
- <Content Include="$(MSBuildThisFileDirectory)\Google.OrTools.runtime.win-x64.targets">
- <PackagePath>build/net45/%(Filename)%(Extension)</PackagePath>
+ <!-- Except for net452 TFM see #1862 -->
+ <Content Include="../../../lib/$(AssemblyName).dll">
+ <PackagePath>lib/net452/%(Filename)%(Extension)</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+
+ <!-- For netframework we need to copy the native binary manually during build on Nuget consumer side. That's why we need a separate target file doing this for us. -->
<Content Include="$(MSBuildThisFileDirectory)\Google.OrTools.runtime.win-x64.targets">
<PackagePath>build/netstandard2.0/%(Filename)%(Extension)</PackagePath>
<Pack>true</Pack>
Great news. Can you please explain the steps to take?
ugly hack using a powershell: First you must know the location of your nuget package cache using:
dotnet nuget locals all --list
Then you can hack the google.ortools.runtime.win-x64
package :smiley_cat:
cd .nuget\packages\google.ortools.runtime.win-x64\7.5.7466
mkdir -p lib/net452
cp .\runtimes\win-x64\native\google-ortools-native.dll .\lib\net452\
Where do I do this?
I copied google-ortools-native.dll from here: packages\Google.OrTools.runtime.win-x64.7.5.7466\runtimes\win-x64\native to here: \packages\Google.OrTools.7.5.7466\lib\net452
Same exception ....
you must do it in the nuget cache, did you try packages\Google.OrTools.runtime.win-x64.7.5.7466\lib\net452
There is no \lib there Only directories: build, content, runtimes
I have lib under \packages\Google.OrTools.7.5.7466\lib\net452
I cleared the nuget cache. nothing there. Still, getting the exception
There is no \lib there Only directories: build, content, runtimes
I have lib under \packages\Google.OrTools.7.5.7466\lib\net452
You should create the lib folder and copy the dll from the runtime directory. I couldn't test this yet. I have to verify this tomorrow.
I copied the native dll from: packages\Google.OrTools.runtime.win-x64.7.5.7466\runtimes\win-x64\native to" .nuget\packages\google.ortools.runtime.win-x64\7.5.7466\lib\net452
Same exception
Tomorrow. BB.
Can you add:
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
to your csproj file. Due to any change in the nuget the native dll google-ortools-native.dll
is not copied to output directory anymore. The above setting should fix that.
Peter, What do you mean by "output directory" ? At least for me, manually copying google-ortools-native.dll to the nuget cache did not help in avoiding the exception. Thx
I mean the build output directory, where all files go during build. Did you also try my suggestion?
For me it is not working. At least for the ASP.Net Project.
Can you add:
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
to your csproj file. Due to any change in the nuget the native dll
google-ortools-native.dll
is not copied to output directory anymore. The above setting should fix that.
you mean adding to .csproj?
i tried the solution by @Mizux with and without the added line to the .csproj file with no success
Same here: added to .csproj -> same exception ....
Yes, add this line to csproj tp the first PropertyGroup
. Please also look at my uploaded example Project ConsoleApp1.zip
. This is a NetFramework Console Project with this setting in csproj, which works for me.
For the other users with problems: What is the failure message? Did you try the uploaded ConsoleApp1.zip
and is it working on your side? Did you try to create a new Project with installing newest ortools in order to exclude side-effects in your specific configuration?
I think OP and I are using ortools within a web application. I could test this with a console application, but that wouldn't fix the issue right away
In my case the main project is a ClassLibrary and uses webAPI. The or-tools example-projects build and run for me, no issues. The problem is with the WebProject.
Interestingly running your project crashes immediately when reaching : RoutingIndexManager manager = new RoutingIndexManager( data.DistanceMatrix.GetLength(0), data.VehicleNumber, data.Starts, data.Ends);
Exception Details:
System.TypeInitializationException HResult=0x80131534 Message=The type initializer for 'Google.OrTools.ConstraintSolver.operations_research_constraint_solverPINVOKE' threw an exception. Source=Google.OrTools StackTrace: at Google.OrTools.ConstraintSolver.operations_research_constraint_solverPINVOKE.new_RoutingIndexManager__SWIG_1(Int32 jarg1, Int32 jarg2, Int32 length3, Int32[] jarg3, Int32 length4, Int32[] jarg4) at Google.OrTools.ConstraintSolver.RoutingIndexManager..ctor(Int32 num_nodes, Int32 num_vehicles, Int32[] starts, Int32[] ends) at ConsoleApp1.Program.Main(String[] args) in C:\Users\guy\Documents\Temp\ConsoleApp1\ConsoleApp1\ConsoleApp1\Program.cs:line 91
Inner Exception 1: TypeInitializationException: The type initializer for 'SWIGExceptionHelper' threw an exception.
Inner Exception 2: DllNotFoundException: Unable to load DLL 'google-ortools-native': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Doing VS "Clean Solution" for your project, now allows it to run. Nice.
But doing the same for mine, does not help ...
This is the path in csproj:
Rereading #1500 and https://docs.microsoft.com/en-us/nuget/create-packages/supporting-multiple-target-frameworks#architecture-specific-folders I'm still not convincing if:
google-ortools-native.dll
was a right moveruntimes/win-x64/lib/net452/
instead of runtimes/win-x64/native
. i.e. does native is not for C++ nuget package which is not exactly our case
https://github.com/google/or-tools/blob/858fa626959f7e386153af82756384b79f983b5a/ortools/dotnet/Google.OrTools.runtime.win-x64/Google.OrTools.runtime.win-x64.csproj.in#L27-L28netcorapp2.1
or netcoreapp3.1
as TFM it magically work and do the right thing (i.e. copying the google-ortools-native.dll
in the bin folder)@ptr1120 I'm pretty sure I'm wrong, but your App csproj seems cheating to me.
I mean at the end of "ConsoleApp1.csproj", we can show:
<Import Project="..\packages\Google.OrTools.runtime.win-x64.7.5.7466\build\net45\Google.OrTools.runtime.win-x64.targets" Condition="Exists('..\packages\Google.OrTools.runtime.win-x64.7.5.7466\build\net45\Google.OrTools.runtime.win-x64.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Google.OrTools.runtime.win-x64.7.5.7466\build\net45\Google.OrTools.runtime.win-x64.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Google.OrTools.runtime.win-x64.7.5.7466\build\net45\Google.OrTools.runtime.win-x64.targets'))" />
</Target>
so it seems you "manually" call the .targets
file while we would like for users to be able to consume it by simply adding in its .csproj:
<PackageReference Include="Google.OrTools" Version="7.5.*" />
note: also your sample provide a packages.config
and contains <HintPath>..\packages\Google.OrTools.7.5.7466\lib\net452\Google.OrTools.dll</HintPath>
and the property CopyLocalLockFileAssemblies
Yes, this (Import
, Target
) is automatically added to the csproj by nuget when you install the nuget package. The only change I did manually is the <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
setting.
Also when updating the ortools using the default nuget mechanism the Target
and Import
is updated automatically.
@ptr1120 <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
don't seems to work using dotnet build
.
I did few test using:
bin
and obj
folders before buildingdotnet build
in a powershellConcerning my point 1
above, in runtime linux-x64 and macos-x64 we don't use a target file shenanigan and while targeting netcoreapp2.1
or netcoreapp3.1
native file are still copied e.g. bin/Debug/netcoreapp3.1/runtimes/win-x64/google-ortools-native.dll
(ed it also copy runtimes/linux-x64 and runtime/mac-x64)
-> If I remove the build
directory from nupkg it still copy files -> it seems it won't use the .target
So for netstandard2.0 (aka netcoreapp2.1) and netstandard2.1 (aka netcoreapp3.1) it seems unneeded
Concerning 2
i guess we should keep the runtimes/<platform>-x64/native
BUT when I target net452 it won't work so I would tend to say runtimes/* stuff is something only working for .net core answering my 3
Now back to net452, i was only able to see them in bin/Debug/net452
while I was adding in google-runtime-win-x64 a lib/net452/google-native....dll
(and in this test I also removed the build
directory)
How do we move forward from here?
I will also have a deeper look on that. But first some implications:
Also I would like to summarize that there are no issues consuming ortools from netcore, netstandard and netframework, except for netframework web projects. Or did I understand anything wrong.
So, as a next step it would be interesting whether ortools work in a fresh, minimal netframework web project, created with VisualStudio and ortools installed with visual studio.
@Mizux: you are right the target file is only for netframework, which works only on windows, for dotnetcore on other platforms this is not needed because netcore has a completely different assembly resolving strategy.
Interesting. Using the default mechanisms, OrTools seems to work also with a netframework Web Project. What I did:
x64
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using Google.OrTools.ConstraintSolver;
namespace WebApplication1.Controllers { internal class DataModel { public long[,] DistanceMatrix = { {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662}, {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210}, {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754}, {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358}, {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244}, {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708}, {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480}, {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856}, {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514}, {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468}, {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354}, {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844}, {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730}, {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536}, {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194}, {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798}, {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0} };
public int VehicleNumber = 4;
// [START starts_ends]
public int[] Starts = { 1, 2, 15, 16 };
public int[] Ends = { 0, 0, 0, 0 };
// [END starts_ends]
};
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Title = "Home Page";
ViewBag.Solution = Execute();
return View();
}
private static string Execute()
{
// Instantiate the data problem.
// [START data]
DataModel data = new DataModel();
// [END data]
// Create Routing Index Manager
// [START index_manager]
RoutingIndexManager manager = new RoutingIndexManager(
data.DistanceMatrix.GetLength(0),
data.VehicleNumber,
data.Starts,
data.Ends);
// [END index_manager]
// Create Routing Model.
// [START routing_model]
RoutingModel routing = new RoutingModel(manager);
// [END routing_model]
// Create and register a transit callback.
// [START transit_callback]
int transitCallbackIndex = routing.RegisterTransitCallback(
(long fromIndex, long toIndex) =>
{
// Convert from routing variable Index to distance matrix NodeIndex.
var fromNode = manager.IndexToNode(fromIndex);
var toNode = manager.IndexToNode(toIndex);
return data.DistanceMatrix[fromNode, toNode];
}
);
// [END transit_callback]
// Define cost of each arc.
// [START arc_cost]
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
// [END arc_cost]
// Add Distance constraint.
// [START distance_constraint]
routing.AddDimension(transitCallbackIndex, 0, 2000,
true, // start cumul to zero
"Distance");
RoutingDimension distanceDimension = routing.GetMutableDimension("Distance");
distanceDimension.SetGlobalSpanCostCoefficient(100);
// [END distance_constraint]
// Setting first solution heuristic.
// [START parameters]
RoutingSearchParameters searchParameters =
operations_research_constraint_solver.DefaultRoutingSearchParameters();
searchParameters.FirstSolutionStrategy =
FirstSolutionStrategy.Types.Value.PathCheapestArc;
// [END parameters]
// Solve the problem.
// [START solve]
Assignment solution = routing.SolveWithParameters(searchParameters);
// [END solve]
// Print solution on console.
// [START print_solution]
return PrintSolution(data, routing, manager, solution);
// [END print_solution]
}
private static string PrintSolution(
in DataModel data,
in RoutingModel routing,
in RoutingIndexManager manager,
in Assignment solution)
{
var sb = new StringBuilder();
// Inspect solution.
long maxRouteDistance = 0;
for (int i = 0; i < data.VehicleNumber; ++i)
{
sb.AppendLine($"Route for Vehicle {i}:");
Console.WriteLine();
long routeDistance = 0;
var index = routing.Start(i);
while (routing.IsEnd(index) == false)
{
sb.Append($"{manager.IndexToNode((int)index)} -> ");
var previousIndex = index;
index = solution.Value(routing.NextVar(index));
routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0);
}
sb.AppendLine($"{manager.IndexToNode((int)index)}");
sb.AppendLine($"Distance of the route: {routeDistance}m");
maxRouteDistance = Math.Max(routeDistance, maxRouteDistance);
}
sb.AppendLine($"Maximum distance of the routes: {maxRouteDistance}m");
return sb.ToString();
}
}
}
Result:
![Capture](https://user-images.githubusercontent.com/582627/73589983-56074680-44dd-11ea-80c0-562d454051b2.PNG)
I even did **not** add the `<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>` setting to csproj.
The `google-ortools-native.dll` is added to the output (bin/) directory during build automatically.
I add the project here, please can anybody confirm that this is working on your side.
[WebApplication1.zip](https://github.com/google/or-tools/files/4142380/WebApplication1.zip)
As a next step, after we have confirmed that default netcore/netframework (also Web) projects work with OrTools 7.5, we can check which of your specific project configuration is breaking the things.
2. Since our native google-ortools-native.dll is intended to be used by a net452 TFM should we put it in
runtimes/win-x64/lib/net452/
instead ofruntimes/win-x64/native
. i.e. does native is not for C++ nuget package which is not exactly our case https://github.com/google/or-tools/blob/858fa626959f7e386153af82756384b79f983b5a/ortools/dotnet/Google.OrTools.runtime.win-x64/Google.OrTools.runtime.win-x64.csproj.in#L27-L28
@Mizux:
Under the runtime folder in a NuGet package, runtime dependent libraries are added.
I believe lib
folders are only for managed libraries (dotnet dll's) and all files in that folder will be referenced by the project at runtime. Whereas native
folders contain non-managed (non-dotnet, e.g. c++) dependencies, which must not be referenced by the project, but needed at runtime (so must be copied to output directory).
Hello, Any recommendation regarding ASP.Net Framework 4.5/4.7 web projects? Did you try to build starting with a 'clean' ASP.Net VS project and then adding ortools?
@GuyBenhaim: I tried netframework 4.8. Did you try my attached web project? You can try creating a clean solution with any target framework you want using the described steps and tell what happens.
the attached one works?
Yes, as described, it works.
Looks better that what I saw until this, but does get! Build, and opens the browser, but gets: Could not find a part of the path ...\WebApplication1\WebApplication1\bin\roslyn\csc.exe'.
Details: Version: 7.5 from NuGet, Windows 10, C#, Routing Solver,
I built the project and when calling it (via URL) the code reached the part that initializes the IndexManager, with valid parameters, and gets an immediate exception: