diff --git a/csharp/cstsp.cs b/csharp/cstsp.cs new file mode 100644 index 0000000000..1490006605 --- /dev/null +++ b/csharp/cstsp.cs @@ -0,0 +1,115 @@ +// +// Copyright 2012 Google +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; +using System.Collections.Generic; +using Google.OrTools.ConstraintSolver; + +class Tsp +{ + class RandomManhattan : LongResultCallback2 { + public RandomManhattan(int size, int seed) + { + this.size_ = size; + this.xs_ = new int[size]; + this.ys_ = new int[size]; + Random generator = new Random(seed); + for (int i = 0; i < size; ++i) + { + xs_[i] = generator.Next(1000); + ys_[i] = generator.Next(1000); + } + } + + public override long Run(long firstIndex, long secondIndex) { + return Math.Abs(xs_[firstIndex] - xs_[secondIndex]) + + Math.Abs(ys_[firstIndex] - ys_[secondIndex]); + } + + private int size_; + private int[] xs_; + private int[] ys_; + }; + + class ConstantCallback : LongResultCallback2 { + public override long Run(long firstIndex, long secondIndex) { + return 1; + } + }; + + static void Solve(int size, int forbidden, int seed) + { + RoutingModel routing = new RoutingModel(size, 1); + // Setting first solution heuristic (cheapest addition). + routing.SetFirstSolutionStrategy(RoutingModel.ROUTING_PATH_CHEAPEST_ARC); + + // Setting the cost function. + // Put a permanent callback to the distance accessor here. The callback + // has the following signature: ResultCallback2. + // The two arguments are the from and to node inidices. + RandomManhattan distances = new RandomManhattan(size, seed); + routing.SetCost(distances); + + // Forbid node connections (randomly). + Random randomizer = new Random(); + long forbidden_connections = 0; + while (forbidden_connections < forbidden) { + long from = randomizer.Next(size - 1); + long to = randomizer.Next(size - 1) + 1; + if (routing.NextVar(from).Contains(to)) { + Console.WriteLine("Forbidding connection {0} -> {1}", from, to); + routing.NextVar(from).RemoveValue(to); + ++forbidden_connections; + } + } + + // Add dummy dimension to test API. + routing.AddDimension(new ConstantCallback(), size + 1, size + 1, "dummy"); + + // Solve, returns a solution if any (owned by RoutingModel). + Assignment solution = routing.Solve(); + if (solution != null) { + // Solution cost. + Console.WriteLine("Cost = {0}", solution.ObjectiveValue()); + // Inspect solution. + // Only one route here; otherwise iterate from 0 to routing.vehicles() - 1 + int route_number = 0; + for (long node = routing.Start(route_number); + !routing.IsEnd(node); + node = solution.Value(routing.NextVar(node))) { + Console.Write("{0} -> ", node); + } + Console.WriteLine("0"); + } + } + + public static void Main(String[] args) + { + int size = 10; + if (args.Length > 0) { + size = Convert.ToInt32(args[0]); + } + int forbidden = 0; + if (args.Length > 0) { + forbidden = Convert.ToInt32(args[1]); + } + int seed = 0; + if (args.Length > 2) { + seed = Convert.ToInt32(args[2]); + } + + Solve(size, forbidden, seed); + } +} diff --git a/makefiles/Makefile.csharp.mk b/makefiles/Makefile.csharp.mk index f878a931d4..89be5a3b18 100644 --- a/makefiles/Makefile.csharp.mk +++ b/makefiles/Makefile.csharp.mk @@ -103,6 +103,9 @@ furniture_moving_intervals.exe: $(LIBPREFIX)Google.OrTools.ConstraintSolver.$(SH organize_day_intervals.exe: $(LIBPREFIX)Google.OrTools.ConstraintSolver.$(SHAREDLIBEXT) csharp/organize_day_intervals.cs $(CSC) /target:exe /out:organize_day_intervals.exe /platform:$(NETPLATFORM) /r:Google.OrTools.ConstraintSolver.dll csharp$Sorganize_day_intervals.cs +cstsp.exe: $(LIBPREFIX)Google.OrTools.ConstraintSolver.$(SHAREDLIBEXT) csharp/cstsp.cs + $(CSC) /target:exe /out:cstsp.exe /platform:$(NETPLATFORM) /r:Google.OrTools.ConstraintSolver.dll csharp$Scstsp.cs + # csharpalgorithms csharpalgorithms: $(LIBPREFIX)Google.OrTools.Algorithms.$(SHAREDLIBEXT) diff --git a/makefiles/Makefile.test.unix b/makefiles/Makefile.test.unix index 60b59d2005..4399931e75 100644 --- a/makefiles/Makefile.test.unix +++ b/makefiles/Makefile.test.unix @@ -27,4 +27,5 @@ test_csharp: $(CSHARPEXE) testlp.exe $(MONO) csknapsack.exe $(MONO) furniture_moving_intervals.exe $(MONO) organize_day_intervals.exe + $(MONO) cstsp.exe $(MONO) testlp.exe diff --git a/makefiles/Makefile.test.win b/makefiles/Makefile.test.win index ebf56d3eb3..f6a544dd66 100644 --- a/makefiles/Makefile.test.win +++ b/makefiles/Makefile.test.win @@ -26,6 +26,7 @@ test_csharp: $(CSHARPEXE) testlp.exe csknapsack.exe furniture_moving_intervals.exe organize_day_intervals.exe + cstsp.exe testlp.exe diff --git a/util/data.swig b/util/data.swig index 9b319eeaed..dc7c660001 100644 --- a/util/data.swig +++ b/util/data.swig @@ -724,25 +724,25 @@ using std::string; class LongResultCallback1 { public: - virtual int64 run(int64) = 0; + virtual int64 Run(int64) = 0; ResultCallback1* GetPermanentCallback() { - return NewPermanentCallback(this, &LongResultCallback1::run); + return NewPermanentCallback(this, &LongResultCallback1::Run); } virtual ~LongResultCallback1() {} }; class LongResultCallback2 { public: - virtual int64 run(int64, int64) = 0; + virtual int64 Run(int64, int64) = 0; ResultCallback2* GetPermanentCallback() { - return NewPermanentCallback(this, &LongResultCallback2::run); + return NewPermanentCallback(this, &LongResultCallback2::Run); } virtual ~LongResultCallback2() {} }; class LongResultCallback3 { public: - virtual int64 run(int64, int64, int64) = 0; + virtual int64 Run(int64, int64, int64) = 0; ResultCallback3* GetPermanentCallback() { - return NewPermanentCallback(this, &LongResultCallback3::run); + return NewPermanentCallback(this, &LongResultCallback3::Run); } virtual ~LongResultCallback3() {} }; @@ -751,19 +751,19 @@ class LongResultCallback3 { class LongResultCallback1 { public: - virtual int64 run(int64) = 0; + virtual int64 Run(int64) = 0; ResultCallback1* GetPermanentCallback(); virtual ~LongResultCallback1(); }; class LongResultCallback2 { public: - virtual int64 run(int64, int64) = 0; + virtual int64 Run(int64, int64) = 0; ResultCallback2* GetPermanentCallback(); virtual ~LongResultCallback2(); }; class LongResultCallback3 { public: - virtual int64 run(int64, int64, int64) = 0; + virtual int64 Run(int64, int64, int64) = 0; ResultCallback3* GetPermanentCallback(); virtual ~LongResultCallback3(); };