From 4bb702ec1b810ed41af913d931957522fbd1bddb Mon Sep 17 00:00:00 2001 From: "lperron@google.com" Date: Thu, 12 Jun 2014 15:07:04 +0000 Subject: [PATCH] port csharp to new styleguide --- makefiles/Makefile.csharp.mk | 43 +- src/algorithms/csharp/knapsack_solver.swig | 13 + .../google/ortools/util/NestedArrayHelper.cs | 33 +- .../csharp/constraint_solver.swig | 1031 +++++++++++++++++ src/constraint_solver/csharp/routing.swig | 98 ++ src/graph/csharp/graph.swig | 54 + src/linear_solver/csharp/linear_solver.swig | 488 ++++++++ src/util/csharp/data.swig | 280 +++++ src/util/csharp/tuple_set.swig | 17 + 9 files changed, 2019 insertions(+), 38 deletions(-) create mode 100644 src/algorithms/csharp/knapsack_solver.swig create mode 100644 src/constraint_solver/csharp/constraint_solver.swig create mode 100644 src/constraint_solver/csharp/routing.swig create mode 100644 src/graph/csharp/graph.swig create mode 100644 src/linear_solver/csharp/linear_solver.swig create mode 100644 src/util/csharp/data.swig create mode 100644 src/util/csharp/tuple_set.swig diff --git a/makefiles/Makefile.csharp.mk b/makefiles/Makefile.csharp.mk index 14edad5f2d..01882be685 100644 --- a/makefiles/Makefile.csharp.mk +++ b/makefiles/Makefile.csharp.mk @@ -48,14 +48,15 @@ clean_csharp: -$(DEL) $(LIB_DIR)$S$(LIBPREFIX)Google.OrTools*.pdb -$(DEL) $(LIB_DIR)$S$(LIBPREFIX)Google.OrTools*.exp -$(DEL) $(LIB_DIR)$S$(LIBPREFIX)Google.OrTools*.netmodule - -$(DEL) $(GEN_DIR)$Slinear_solver$S*csharp_wrap* - -$(DEL) $(GEN_DIR)$Sconstraint_solver$S*csharp_wrap* - -$(DEL) $(GEN_DIR)$Salgorithms$S*csharp_wrap* - -$(DEL) $(GEN_DIR)$Sgraph$S*csharp_wrap* + -$(DEL) $(GEN_DIR)$Slinear_solver$Scsharp$S*csharp_wrap* + -$(DEL) $(GEN_DIR)$Sconstraint_solver$Scsharp$S*csharp_wrap* + -$(DEL) $(GEN_DIR)$Salgorithms$Scsharp$S*csharp_wrap* + -$(DEL) $(GEN_DIR)$Sgraph$Scsharp$S*csharp_wrap* -$(DEL) $(GEN_DIR)$Scom$Sgoogle$Sortools$Slinearsolver$S*.cs -$(DEL) $(GEN_DIR)$Scom$Sgoogle$Sortools$Sconstraintsolver$S*.cs -$(DEL) $(GEN_DIR)$Scom$Sgoogle$Sortools$Sknapsacksolver$S*.cs -$(DEL) $(GEN_DIR)$Scom$Sgoogle$Sortools$Sgraph$S*.cs + -$(DEL) $(GEN_DIR)$Scom$Sgoogle$Sortools$Sutil$S*.cs -$(DEL) $(OBJ_DIR)$Sswig$S*csharp_wrap.$O -$(DEL) $(BIN_DIR)$S*.exe @@ -64,23 +65,22 @@ clean_csharp: csharportools: $(BIN_DIR)/Google.OrTools.dll $(GEN_DIR)/linear_solver/linear_solver_csharp_wrap.cc: \ - $(SRC_DIR)/linear_solver/linear_solver.swig \ - $(SRC_DIR)/base/base.swig $(SRC_DIR)/util/data.swig \ + $(SRC_DIR)/linear_solver/csharp/linear_solver.swig \ + $(SRC_DIR)/base/base.swig $(SRC_DIR)/util/csharp/data.swig \ $(SRC_DIR)/linear_solver/linear_solver.h \ $(GEN_DIR)/linear_solver/linear_solver2.pb.h - $(SWIG_BINARY) $(SWIG_INC) -I$(INC_DIR) -c++ -csharp -o $(GEN_DIR)$Slinear_solver$Slinear_solver_csharp_wrap.cc -module operations_research_linear_solver -namespace Google.OrTools.LinearSolver -dllimport "Google.OrTools.$(DYNAMIC_SWIG_LIB_SUFFIX)" -outdir $(GEN_DIR)$Scom$Sgoogle$Sortools$Slinearsolver $(SRC_DIR)/linear_solver$Slinear_solver.swig + $(SWIG_BINARY) $(SWIG_INC) -I$(INC_DIR) -c++ -csharp -o $(GEN_DIR)$Slinear_solver$Slinear_solver_csharp_wrap.cc -module operations_research_linear_solver -namespace Google.OrTools.LinearSolver -dllimport "Google.OrTools.$(DYNAMIC_SWIG_LIB_SUFFIX)" -outdir $(GEN_DIR)$Scom$Sgoogle$Sortools$Slinearsolver $(SRC_DIR)/linear_solver$Scsharp$Slinear_solver.swig $(OBJ_DIR)/swig/linear_solver_csharp_wrap.$O: $(GEN_DIR)/linear_solver/linear_solver_csharp_wrap.cc $(CCC) $(CFLAGS) -c $(GEN_DIR)/linear_solver/linear_solver_csharp_wrap.cc $(OBJ_OUT)$(OBJ_DIR)$Sswig$Slinear_solver_csharp_wrap.$O $(GEN_DIR)/constraint_solver/constraint_solver_csharp_wrap.cc: \ - $(SRC_DIR)/constraint_solver/routing.swig \ - $(SRC_DIR)/constraint_solver/constraint_solver.swig \ + $(SRC_DIR)/constraint_solver/csharp/routing.swig \ + $(SRC_DIR)/constraint_solver/csharp/constraint_solver.swig \ $(SRC_DIR)/base/base.swig \ - $(SRC_DIR)/util/callback.swig \ - $(SRC_DIR)/util/data.swig \ + $(SRC_DIR)/util/csharp/data.swig \ $(SRC_DIR)/constraint_solver/constraint_solver.h - $(SWIG_BINARY) $(SWIG_INC) -I$(INC_DIR) -c++ -csharp -o $(GEN_DIR)$Sconstraint_solver$Sconstraint_solver_csharp_wrap.cc -module operations_research_constraint_solver -namespace Google.OrTools.ConstraintSolver -dllimport "Google.OrTools.$(DYNAMIC_SWIG_LIB_SUFFIX)" -outdir $(GEN_DIR)$Scom$Sgoogle$Sortools$Sconstraintsolver $(SRC_DIR)$Sconstraint_solver$Srouting.swig + $(SWIG_BINARY) $(SWIG_INC) -I$(INC_DIR) -c++ -csharp -o $(GEN_DIR)$Sconstraint_solver$Sconstraint_solver_csharp_wrap.cc -module operations_research_constraint_solver -namespace Google.OrTools.ConstraintSolver -dllimport "Google.OrTools.$(DYNAMIC_SWIG_LIB_SUFFIX)" -outdir $(GEN_DIR)$Scom$Sgoogle$Sortools$Sconstraintsolver $(SRC_DIR)$Sconstraint_solver$Scsharp$Srouting.swig $(SED) -i -e 's/CSharp_new_Solver/CSharp_new_CpSolver/g' $(GEN_DIR)/com/google/ortools/constraintsolver/*cs $(GEN_DIR)/constraint_solver/constraint_solver_csharp_wrap.* $(SED) -i -e 's/CSharp_delete_Solver/CSharp_delete_CpSolver/g' $(GEN_DIR)/com/google/ortools/constraintsolver/*cs $(GEN_DIR)/constraint_solver/constraint_solver_csharp_wrap.* $(SED) -i -e 's/CSharp_Solver_Solve/CSharp_CpSolver_Solve/g' $(GEN_DIR)/com/google/ortools/constraintsolver/*cs $(GEN_DIR)/constraint_solver/constraint_solver_csharp_wrap.* @@ -95,31 +95,28 @@ $(OBJ_DIR)/swig/constraint_solver_csharp_wrap.$O: \ $(CCC) $(CFLAGS) -c $(GEN_DIR)$Sconstraint_solver$Sconstraint_solver_csharp_wrap.cc $(OBJ_OUT)$(OBJ_DIR)$Sswig$Sconstraint_solver_csharp_wrap.$O $(GEN_DIR)/algorithms/knapsack_solver_csharp_wrap.cc: \ - $(SRC_DIR)/algorithms/knapsack_solver.swig \ - $(SRC_DIR)/algorithms/knapsack_solver.swig \ + $(SRC_DIR)/algorithms/csharp/knapsack_solver.swig \ $(SRC_DIR)/base/base.swig \ - $(SRC_DIR)/util/data.swig \ + $(SRC_DIR)/util/csharp/data.swig \ $(SRC_DIR)/algorithms/knapsack_solver.h - $(SWIG_BINARY) $(SWIG_INC) -I$(INC_DIR) -c++ -csharp -o $(GEN_DIR)$Salgorithms$Sknapsack_solver_csharp_wrap.cc -module operations_research_algorithms -namespace Google.OrTools.Algorithms -dllimport "Google.OrTools.$(DYNAMIC_SWIG_LIB_SUFFIX)" -outdir $(GEN_DIR)$Scom$Sgoogle$Sortools$Sknapsacksolver $(SRC_DIR)$Salgorithms$Sknapsack_solver.swig + $(SWIG_BINARY) $(SWIG_INC) -I$(INC_DIR) -c++ -csharp -o $(GEN_DIR)$Salgorithms$Sknapsack_solver_csharp_wrap.cc -module operations_research_algorithms -namespace Google.OrTools.Algorithms -dllimport "Google.OrTools.$(DYNAMIC_SWIG_LIB_SUFFIX)" -outdir $(GEN_DIR)$Scom$Sgoogle$Sortools$Sknapsacksolver $(SRC_DIR)$Salgorithms$Scsharp$Sknapsack_solver.swig $(OBJ_DIR)/swig/knapsack_solver_csharp_wrap.$O: $(GEN_DIR)/algorithms/knapsack_solver_csharp_wrap.cc $(CCC) $(CFLAGS) -c $(GEN_DIR)/algorithms/knapsack_solver_csharp_wrap.cc $(OBJ_OUT)$(OBJ_DIR)$Sswig$Sknapsack_solver_csharp_wrap.$O $(GEN_DIR)/graph/graph_csharp_wrap.cc: \ - $(SRC_DIR)/graph/graph.swig \ + $(SRC_DIR)/graph/csharp/graph.swig \ $(SRC_DIR)/base/base.swig \ - $(SRC_DIR)/util/data.swig \ + $(SRC_DIR)/util/csharp/data.swig \ $(SRC_DIR)/graph/max_flow.h \ $(SRC_DIR)/graph/min_cost_flow.h - $(SWIG_BINARY) $(SWIG_INC) -I$(INC_DIR) -c++ -csharp -o $(GEN_DIR)$Sgraph$Sgraph_csharp_wrap.cc -module operations_research_graph -namespace Google.OrTools.Graph -dllimport "Google.OrTools.$(DYNAMIC_SWIG_LIB_SUFFIX)" -outdir $(GEN_DIR)$Scom$Sgoogle$Sortools$Sgraph $(SRC_DIR)$Sgraph$Sgraph.swig + $(SWIG_BINARY) $(SWIG_INC) -I$(INC_DIR) -c++ -csharp -o $(GEN_DIR)$Sgraph$Sgraph_csharp_wrap.cc -module operations_research_graph -namespace Google.OrTools.Graph -dllimport "Google.OrTools.$(DYNAMIC_SWIG_LIB_SUFFIX)" -outdir $(GEN_DIR)$Scom$Sgoogle$Sortools$Sgraph $(SRC_DIR)$Sgraph$Scsharp$Sgraph.swig $(OBJ_DIR)/swig/graph_csharp_wrap.$O: $(GEN_DIR)/graph/graph_csharp_wrap.cc $(CCC) $(CFLAGS) -c $(GEN_DIR)$Sgraph$Sgraph_csharp_wrap.cc $(OBJ_OUT)$(OBJ_DIR)$Sswig$Sgraph_csharp_wrap.$O $(BIN_DIR)/Google.OrTools.dll: \ $(OBJ_DIR)/swig/linear_solver_csharp_wrap.$O \ - $(SRC_DIR)/com/google/ortools/linearsolver/LinearExpr.cs \ - $(SRC_DIR)/com/google/ortools/linearsolver/LinearConstraint.cs \ $(OBJ_DIR)/swig/constraint_solver_csharp_wrap.$O \ $(OBJ_DIR)/swig/knapsack_solver_csharp_wrap.$O \ $(OBJ_DIR)/swig/graph_csharp_wrap.$O \ @@ -128,13 +125,15 @@ $(BIN_DIR)/Google.OrTools.dll: \ $(SRC_DIR)/com/google/ortools/constraintsolver/IntArrayHelper.cs \ $(SRC_DIR)/com/google/ortools/constraintsolver/ValCstPair.cs \ $(SRC_DIR)/com/google/ortools/constraintsolver/NetDecisionBuilder.cs \ + $(SRC_DIR)/com/google/ortools/linearsolver/LinearExpr.cs \ + $(SRC_DIR)/com/google/ortools/linearsolver/LinearConstraint.cs \ $(SRC_DIR)/com/google/ortools/util/NestedArrayHelper.cs \ $(STATIC_ALL_DEPS) ifeq ($(SYSTEM),win) $(CSC) /target:module /out:$(LIB_DIR)$S$(LIBPREFIX)Google.OrTools.netmodule /warn:0 /nologo /debug $(GEN_DIR)\\com\\google\\ortools\\linearsolver\\*.cs $(SRC_DIR)\\com\\google\\ortools\\linearsolver\\*.cs $(GEN_DIR)\\com\\google\\ortools\\constraintsolver\\*.cs $(SRC_DIR)\\com\\google\\ortools\\constraintsolver\\*.cs $(GEN_DIR)\\com\\google\\ortools\\knapsacksolver\\*.cs $(GEN_DIR)\\com\\google\\ortools\\graph\\*.cs $(SRC_DIR)\\com\\google\\ortools\\util\\*.cs $(DYNAMIC_LD) $(SIGNING_FLAGS) $(LDOUT)$(BIN_DIR)$SGoogle.OrTools.dll $(LIB_DIR)$S$(LIBPREFIX)Google.OrTools.netmodule $(OBJ_DIR)$Sswig$Slinear_solver_csharp_wrap.$O $(OBJ_DIR)$Sswig$Sconstraint_solver_csharp_wrap.$O $(OBJ_DIR)$Sswig$Sknapsack_solver_csharp_wrap.$O $(OBJ_DIR)$Sswig$Sgraph_csharp_wrap.$O $(STATIC_ALL_LNK) $(STATIC_LD_FLAGS) else - $(CSC) /target:library /out:$(BIN_DIR)/Google.OrTools.dll /warn:0 /nologo /debug $(GEN_DIR)/com/google/ortools/linearsolver/*.cs $(SRC_DIR)/com/google/ortools/linearsolver/*.cs $(GEN_DIR)/com/google/ortools/constraintsolver/*.cs $(SRC_DIR)/com/google/ortools/constraintsolver/*.cs $(GEN_DIR)/com/google/ortools/knapsacksolver/*.cs $(GEN_DIR)/com/google/ortools/graph/*.cs $(SRC_DIR)/com/google/ortools/util/*.cs + $(CSC) /target:library /out:$(BIN_DIR)/Google.OrTools.dll /warn:0 /nologo /debug $(SRC_DIR)/com/google/ortools/util/*.cs $(GEN_DIR)/com/google/ortools/linearsolver/*.cs $(SRC_DIR)/com/google/ortools/linearsolver/*.cs $(GEN_DIR)/com/google/ortools/constraintsolver/*.cs $(SRC_DIR)/com/google/ortools/constraintsolver/*.cs $(GEN_DIR)/com/google/ortools/knapsacksolver/*.cs $(GEN_DIR)/com/google/ortools/graph/*.cs $(DYNAMIC_LD) $(LDOUT)$(LIB_DIR)$S$(LIBPREFIX)Google.OrTools.$(DYNAMIC_SWIG_LIB_SUFFIX) $(OBJ_DIR)/swig/linear_solver_csharp_wrap.$O $(OBJ_DIR)/swig/constraint_solver_csharp_wrap.$O $(OBJ_DIR)/swig/knapsack_solver_csharp_wrap.$O $(OBJ_DIR)/swig/graph_csharp_wrap.$O $(STATIC_ALL_LNK) $(STATIC_LD_FLAGS) endif diff --git a/src/algorithms/csharp/knapsack_solver.swig b/src/algorithms/csharp/knapsack_solver.swig new file mode 100644 index 0000000000..fd188e38b7 --- /dev/null +++ b/src/algorithms/csharp/knapsack_solver.swig @@ -0,0 +1,13 @@ +// TODO(user): Refactor this file to adhere to the SWIG style guide. + +%include util/csharp/data.swig + +// Include the file we want to wrap a first time. +%{ +#include "algorithms/knapsack_solver.h" +%} + +%rename (UseReduction) operations_research::KnapsackSolver::use_reduction; +%rename (SetUseReduction) operations_research::KnapsackSolver::set_use_reduction; + +%include "algorithms/knapsack_solver.h" diff --git a/src/com/google/ortools/util/NestedArrayHelper.cs b/src/com/google/ortools/util/NestedArrayHelper.cs index 6d5af30962..b6665f035f 100644 --- a/src/com/google/ortools/util/NestedArrayHelper.cs +++ b/src/com/google/ortools/util/NestedArrayHelper.cs @@ -11,23 +11,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Google.OrTools.Util +namespace Google.OrTools { + +using System; +using System.Collections.Generic; + +public static class NestedArrayHelper { - using System; - using System.Collections.Generic; + public static T[] GetFlatArray(T[,] arr) { + int flatLength = arr.GetLength(0) * arr.GetLength(1); + int idx = 0; + T[] flat = new T[flatLength]; - public static class NestedArrayHelper - { - public static T[] GetFlatArray(T[,] arr) { - int flatLength = arr.GetLength(0) * arr.GetLength(1); - int idx = 0; - T[] flat = new T[flatLength]; + for (int i = 0; i < arr.GetLength(0); i++) + for (int j = 0; j < arr.GetLength(1); j++) + flat[idx++] = arr[i,j]; - for (int i = 0; i < arr.GetLength(0); i++) - for (int j = 0; j < arr.GetLength(1); j++) - flat[idx++] = arr[i,j]; - - return flat; - } + return flat; } -} // namespace Google.OrTools.Util +} + +} // namespace Google.OrTools diff --git a/src/constraint_solver/csharp/constraint_solver.swig b/src/constraint_solver/csharp/constraint_solver.swig new file mode 100644 index 0000000000..3a1c4b5ca7 --- /dev/null +++ b/src/constraint_solver/csharp/constraint_solver.swig @@ -0,0 +1,1031 @@ +// Copyright 2010-2013 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. + +%include exception.i +%include util/csharp/data.swig +%include util/csharp/tuple_set.swig + +// ############ BEGIN DUPLICATED CODE BLOCK ############ +// IMPORTANT: keep this code block in sync with the .swig +// files in ../python and ../csharp. + +// Protect from failure. +%define PROTECT_FROM_FAILURE(Method, GetSolver) +%exception Method { + operations_research::Solver* const solver = GetSolver; + FailureProtect protect; + Closure* const intercept = NewCallback<>(&protect, &FailureProtect::JumpBack); + solver->set_fail_intercept(intercept); + if (setjmp(protect.exception_buffer) == 0) { + $action + solver->clear_fail_intercept(); + delete intercept; + } else { + solver->clear_fail_intercept(); + SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, "fail"); + return $null; + } +} +%enddef + +namespace operations_research { +PROTECT_FROM_FAILURE(IntExpr::SetValue(int64 v), arg1->solver()); +PROTECT_FROM_FAILURE(IntExpr::SetMin(int64 v), arg1->solver()); +PROTECT_FROM_FAILURE(IntExpr::SetMax(int64 v), arg1->solver()); +PROTECT_FROM_FAILURE(IntExpr::SetRange(int64 mi, int64 ma), arg1->solver()); +PROTECT_FROM_FAILURE(IntVar::RemoveValue(int64 v), arg1->solver()); +PROTECT_FROM_FAILURE(IntVar::RemoveValues(const std::vector& values), + arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetStartMin(int64 m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetStartMax(int64 m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetStartRange(int64 mi, int64 ma), + arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetDurationMin(int64 m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetDurationMax(int64 m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetDurationRange(int64 mi, int64 ma), + arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetEndMin(int64 m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetEndMax(int64 m), arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetEndRange(int64 mi, int64 ma), + arg1->solver()); +PROTECT_FROM_FAILURE(IntervalVar::SetPerformed(bool val), arg1->solver()); +PROTECT_FROM_FAILURE(Solver::AddConstraint(Constraint* const ct), arg1); +PROTECT_FROM_FAILURE(Solver::Fail(), arg1); +#undef PROTECT_FROM_FAILURE +} // namespace operations_research + +// ############ END DUPLICATED CODE BLOCK ############ + +// Callback wrapping. +%{ +#include +#include "base/callback.h" +#include "base/integral_types.h" +%} + +// TODO(user): split out the callback code; it creates another file since +// it uses a different module. +%module(directors="1") main +%feature("director") LongResultCallback1; +%feature("director") LongResultCallback2; +%feature("director") LongResultCallback3; +%{ +#include +#include "base/callback.h" +#include "base/integral_types.h" + +class LongResultCallback1 { + public: + virtual int64 Run(int64) = 0; + ResultCallback1* GetPermanentCallback() { + return NewPermanentCallback(this, &LongResultCallback1::Run); + } + virtual ~LongResultCallback1() {} +}; +class LongResultCallback2 { + public: + virtual int64 Run(int64, int64) = 0; + ResultCallback2* GetPermanentCallback() { + return NewPermanentCallback(this, &LongResultCallback2::Run); + } + virtual ~LongResultCallback2() {} +}; +class LongResultCallback3 { + public: + virtual int64 Run(int64, int64, int64) = 0; + ResultCallback3* GetPermanentCallback() { + return NewPermanentCallback(this, &LongResultCallback3::Run); + } + virtual ~LongResultCallback3() {} +}; +%} + +class LongResultCallback1 { + public: + virtual int64 Run(int64) = 0; + ResultCallback1* GetPermanentCallback(); + virtual ~LongResultCallback1(); +}; +class LongResultCallback2 { + public: + virtual int64 Run(int64, int64) = 0; + ResultCallback2* GetPermanentCallback(); + virtual ~LongResultCallback2(); +}; +class LongResultCallback3 { + public: + virtual int64 Run(int64, int64, int64) = 0; + ResultCallback3* GetPermanentCallback(); + virtual ~LongResultCallback3(); +}; + +// Typemaps for callbacks in csharp. +%typemap(cstype) ResultCallback1* "LongResultCallback1"; +%typemap(csin) ResultCallback1* + "$descriptor(ResultCallback1*) + .getCPtr($csinput.GetPermanentCallback())"; +%typemap(cstype) ResultCallback2* "LongResultCallback2"; +%typemap(csin) ResultCallback2* + "$descriptor(ResultCallback2*) + .getCPtr($csinput.GetPermanentCallback())"; +%typemap(cstype) ResultCallback3* + "LongResultCallback3"; +%typemap(csin) ResultCallback3* + "$descriptor(ResultCallback3*) + .getCPtr($csinput.GetPermanentCallback())"; + +%module(directors="1", allprotected="1") operations_research; +%feature("director") Action; +%feature("director") BaseLNS; +%feature("director") Decision; +%feature("director") DecisionBuilder; +%feature("director") IntVarLocalSearchFilter; +%feature("director") IntVarLocalSearchOperator; +%feature("director") SequenceVarLocalSearchOperator; +%feature("director") LocalSearchOperator; +%feature("director") OptimizeVar; +%feature("director") SearchLimit; +%feature("director") SearchMonitor; +%feature("director") SymmetryBreaker; + +%include "std_vector.i" + +%template(IntVector) std::vector; + +%{ +#include + +#include "constraint_solver/constraint_solver.h" +#include "constraint_solver/constraint_solveri.h" + +namespace operations_research { +class LocalSearchPhaseParameters { + public: + LocalSearchPhaseParameters() {} + ~LocalSearchPhaseParameters() {} +}; +} // namespace operations_research + +struct FailureProtect { + jmp_buf exception_buffer; + void JumpBack() { + longjmp(exception_buffer, 1); + } +}; +%} + +%ignore operations_research::Solver::MakeIntVarArray; +%ignore operations_research::Solver::MakeBoolVarArray; +%ignore operations_research::Solver::MakeFixedDurationIntervalVarArray; +%ignore operations_research::IntVarLocalSearchFilter::FindIndex; +%ignore operations_research::SequenceVarLocalSearchOperatorTemplate::Value; + +// Generic rename rule. +%rename("%(camelcase)s", %$isfunction) ""; + +// Rename rule on DecisionBuilder; +%rename (NextWrap) operations_research::DecisionBuilder::Next; + +// Rename rule on SearchLimit +%rename (IsCrossed) operations_research::SearchLimit::crossed; + +// Rename rules on Solver. +%rename (Add) operations_research::Solver::AddConstraint; + +// Rename rule on DisjunctiveConstraint. +%rename (SequenceVar) operations_research::DisjunctiveConstraint::MakeSequenceVar; + +// Generic rename rules. +%rename (ToString) *::DebugString; + +// Keep the .solver() API. +%rename (solver) *::solver; + +// Rename NewSearch and EndSearch to add pinning. +%rename (NewSearchAux) operations_research::Solver::NewSearch; +%rename (EndSearchAux) operations_research::Solver::EndSearch; + +%typemap(csinterfaces_derived) operations_research::Constraint "IConstraintWithStatus"; +%typemap(cscode) operations_research::Constraint %{ + public static implicit operator IntVar(Constraint eq) + { + return eq.Var(); + } + + public static implicit operator IntExpr(Constraint eq) + { + return eq.Var(); + } + public static IntExpr operator+(Constraint a, Constraint b) { + return a.solver().MakeSum(a.Var(), b.Var()); + } + public static IntExpr operator+(Constraint a, long v) { + return a.solver().MakeSum(a.Var(), v); + } + public static IntExpr operator+(long v, Constraint a) { + return a.solver().MakeSum(a.Var(), v); + } + public static IntExpr operator-(Constraint a, Constraint b) { + return a.solver().MakeDifference(a.Var(), b.Var()); + } + public static IntExpr operator-(Constraint a, long v) { + return a.solver().MakeSum(a.Var(), -v); + } + public static IntExpr operator-(long v, Constraint a) { + return a.solver().MakeDifference(v, a.Var()); + } + public static IntExpr operator*(Constraint a, Constraint b) { + return a.solver().MakeProd(a.Var(), b.Var()); + } + public static IntExpr operator*(Constraint a, long v) { + return a.solver().MakeProd(a.Var(), v); + } + public static IntExpr operator*(long v, Constraint a) { + return a.solver().MakeProd(a.Var(), v); + } + public static IntExpr operator/(Constraint a, long v) { + return a.solver().MakeDiv(a.Var(), v); + } + public static IntExpr operator-(Constraint a) { + return a.solver().MakeOpposite(a.Var()); + } + public IntExpr Abs() { + return this.solver().MakeAbs(this.Var()); + } + public IntExpr Square() { + return this.solver().MakeSquare(this.Var()); + } + public static WrappedConstraint operator ==(Constraint a, long v) { + return new WrappedConstraint(a.solver().MakeEquality(a.Var(), v)); + } + public static WrappedConstraint operator ==(long v, Constraint a) { + return new WrappedConstraint(a.solver().MakeEquality(a.Var(), v)); + } + public static WrappedConstraint operator !=(Constraint a, long v) { + return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v)); + } + public static WrappedConstraint operator !=(long v, Constraint a) { + return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v)); + } + public static WrappedConstraint operator >=(Constraint a, long v) { + return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator >=(long v, Constraint a) { + return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator >(Constraint a, long v) { + return new WrappedConstraint(a.solver().MakeGreater(a.Var(), v)); + } + public static WrappedConstraint operator >(long v, Constraint a) { + return new WrappedConstraint(a.solver().MakeLess(a.Var(), v)); + } + public static WrappedConstraint operator <=(Constraint a, long v) { + return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator <=(long v, Constraint a) { + return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator <(Constraint a, long v) { + return new WrappedConstraint(a.solver().MakeLess(a.Var(), v)); + } + public static WrappedConstraint operator <(long v, Constraint a) { + return new WrappedConstraint(a.solver().MakeGreater(a.Var(), v)); + } + public static WrappedConstraint operator >=(Constraint a, Constraint b) { + return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), b.Var())); + } + public static WrappedConstraint operator >(Constraint a, Constraint b) { + return new WrappedConstraint(a.solver().MakeGreater(a.Var(), b.Var())); + } + public static WrappedConstraint operator <=(Constraint a, Constraint b) { + return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), b.Var())); + } + public static WrappedConstraint operator <(Constraint a, Constraint b) { + return new WrappedConstraint(a.solver().MakeLess(a.Var(), b.Var())); + } + public static ConstraintEquality operator ==(Constraint a, Constraint b) { + return new ConstraintEquality(a, b, true); + } + public static ConstraintEquality operator !=(Constraint a, Constraint b) { + return new ConstraintEquality(a, b, false); + } +%} + + +// Add arithmetic operators to integer expressions. +%typemap(cscode) operations_research::IntExpr %{ + public static IntExpr operator+(IntExpr a, IntExpr b) { + return a.solver().MakeSum(a, b); + } + public static IntExpr operator+(IntExpr a, long v) { + return a.solver().MakeSum(a, v); + } + public static IntExpr operator+(long v, IntExpr a) { + return a.solver().MakeSum(a, v); + } + public static IntExpr operator-(IntExpr a, IntExpr b) { + return a.solver().MakeDifference(a, b); + } + public static IntExpr operator-(IntExpr a, long v) { + return a.solver().MakeSum(a, -v); + } + public static IntExpr operator-(long v, IntExpr a) { + return a.solver().MakeDifference(v, a); + } + public static IntExpr operator*(IntExpr a, IntExpr b) { + return a.solver().MakeProd(a, b); + } + public static IntExpr operator*(IntExpr a, long v) { + return a.solver().MakeProd(a, v); + } + public static IntExpr operator*(long v, IntExpr a) { + return a.solver().MakeProd(a, v); + } + public static IntExpr operator/(IntExpr a, long v) { + return a.solver().MakeDiv(a, v); + } + public static IntExpr operator-(IntExpr a) { + return a.solver().MakeOpposite(a); + } + public IntExpr Abs() { + return this.solver().MakeAbs(this); + } + public IntExpr Square() { + return this.solver().MakeSquare(this); + } + public static IntExprEquality operator ==(IntExpr a, IntExpr b) { + return new IntExprEquality(a, b, true); + } + public static IntExprEquality operator !=(IntExpr a, IntExpr b) { + return new IntExprEquality(a, b, false); + } + public static WrappedConstraint operator ==(IntExpr a, long v) { + return new WrappedConstraint(a.solver().MakeEquality(a, v)); + } + public static WrappedConstraint operator !=(IntExpr a, long v) { + return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v)); + } + public static WrappedConstraint operator >=(IntExpr a, long v) { + return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a, v)); + } + public static WrappedConstraint operator >(IntExpr a, long v) { + return new WrappedConstraint(a.solver().MakeGreater(a, v)); + } + public static WrappedConstraint operator <=(IntExpr a, long v) { + return new WrappedConstraint(a.solver().MakeLessOrEqual(a, v)); + } + public static WrappedConstraint operator <(IntExpr a, long v) { + return new WrappedConstraint(a.solver().MakeLess(a, v)); + } + public static WrappedConstraint operator >=(IntExpr a, IntExpr b) { + return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), b.Var())); + } + public static WrappedConstraint operator >(IntExpr a, IntExpr b) { + return new WrappedConstraint(a.solver().MakeGreater(a.Var(), b.Var())); + } + public static WrappedConstraint operator <=(IntExpr a, IntExpr b) { + return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), b.Var())); + } + public static WrappedConstraint operator <(IntExpr a, IntExpr b) { + return new WrappedConstraint(a.solver().MakeLess(a.Var(), b.Var())); + } +%} + +CS_TYPEMAP_STDVECTOR_OBJECT(operations_research::IntVar, IntVar) +CS_TYPEMAP_STDVECTOR_OBJECT(operations_research::SearchMonitor, SearchMonitor) +CS_TYPEMAP_STDVECTOR_OBJECT(operations_research::DecisionBuilder, DecisionBuilder) +CS_TYPEMAP_STDVECTOR_OBJECT(operations_research::IntervalVar, IntervalVar) +CS_TYPEMAP_STDVECTOR_OBJECT(operations_research::SequenceVar, SequenceVar) +CS_TYPEMAP_STDVECTOR_OBJECT(operations_research::LocalSearchOperator, LocalSearchOperator) +CS_TYPEMAP_STDVECTOR_OBJECT(operations_research::LocalSearchFilter, LocalSearchFilter) +CS_TYPEMAP_STDVECTOR_OBJECT(operations_research::SymmetryBreaker, SymmetryBreaker) + +namespace operations_research { +%extend IntervalVar { + Constraint* EndsAfterEnd(IntervalVar* other) { + return self->solver()->MakeIntervalVarRelation(self, operations_research::Solver::ENDS_AFTER_END, other); + } + Constraint* EndsAfterStart(IntervalVar* other) { + return self->solver()->MakeIntervalVarRelation(self, operations_research::Solver::ENDS_AFTER_START, other); + } + Constraint* EndsAtEnd(IntervalVar* other) { + return self->solver()->MakeIntervalVarRelation(self, operations_research::Solver::ENDS_AT_END, other); + } + Constraint* EndsAtStart(IntervalVar* other) { + return self->solver()->MakeIntervalVarRelation(self, operations_research::Solver::ENDS_AT_START, other); + } + Constraint* StartsAfterEnd(IntervalVar* other) { + return self->solver()->MakeIntervalVarRelation(self, operations_research::Solver::STARTS_AFTER_END, other); + } + Constraint* StartsAfterStart(IntervalVar* other) { + return self->solver()->MakeIntervalVarRelation(self, + operations_research::Solver::STARTS_AFTER_START, + other); + } + Constraint* StartsAtEnd(IntervalVar* other) { + return self->solver()->MakeIntervalVarRelation(self, operations_research::Solver::STARTS_AT_END, other); + } + Constraint* StartsAtStart(IntervalVar* other) { + return self->solver()->MakeIntervalVarRelation(self, + operations_research::Solver::STARTS_AT_START, + other); + } + Constraint* EndsAfter(int64 date) { + return self->solver()->MakeIntervalVarRelation(self, + operations_research::Solver::ENDS_AFTER, + date); + } + Constraint* EndsAt(int64 date) { + return self->solver()->MakeIntervalVarRelation(self, + operations_research::Solver::ENDS_AT, + date); + } + Constraint* EndsBefore(int64 date) { + return self->solver()->MakeIntervalVarRelation(self, + operations_research::Solver::ENDS_BEFORE, + date); + } + Constraint* StartsAfter(int64 date) { + return self->solver()->MakeIntervalVarRelation(self, + operations_research::Solver::STARTS_AFTER, + date); + } + Constraint* StartsAt(int64 date) { + return self->solver()->MakeIntervalVarRelation(self, + operations_research::Solver::STARTS_AT, + date); + } + Constraint* StartsBefore(int64 date) { + return self->solver()->MakeIntervalVarRelation(self, + operations_research::Solver::STARTS_BEFORE, + date); + } + Constraint* CrossesDate(int64 date) { + return self->solver()->MakeIntervalVarRelation(self, + operations_research::Solver::CROSS_DATE, + date); + } + Constraint* AvoidsDate(int64 date) { + return self->solver()->MakeIntervalVarRelation(self, + operations_research::Solver::AVOID_DATE, + date); + } + IntervalVar* RelaxedMax() { + return self->solver()->MakeIntervalRelaxedMax(self); + } + IntervalVar* RelaxedMin() { + return self->solver()->MakeIntervalRelaxedMin(self); + } +} + +%extend IntExpr { + Constraint* MapTo(const std::vector& vars) { + return self->solver()->MakeMapDomain(self->Var(), vars); + } + IntExpr* IndexOf(const std::vector& vars) { + return self->solver()->MakeElement(vars, self->Var()); + } + IntExpr* IndexOf(const std::vector& vars) { + return self->solver()->MakeElement(vars, self->Var()); + } + IntVar* IsEqual(int64 value) { + return self->solver()->MakeIsEqualCstVar(self->Var(), value); + } + IntVar* IsDifferent(int64 value) { + return self->solver()->MakeIsDifferentCstVar(self->Var(), value); + } + IntVar* IsGreater(int64 value) { + return self->solver()->MakeIsGreaterCstVar(self->Var(), value); + } + IntVar* IsGreaterOrEqual(int64 value) { + return self->solver()->MakeIsGreaterOrEqualCstVar(self->Var(), value); + } + IntVar* IsLess(int64 value) { + return self->solver()->MakeIsLessCstVar(self->Var(), value); + } + IntVar* IsLessOrEqual(int64 value) { + return self->solver()->MakeIsLessOrEqualCstVar(self->Var(), value); + } + IntVar* IsMember(const std::vector& values) { + return self->solver()->MakeIsMemberVar(self->Var(), values); + } + IntVar* IsMember(const std::vector& values) { + return self->solver()->MakeIsMemberVar(self->Var(), values); + } + Constraint* Member(const std::vector& values) { + return self->solver()->MakeMemberCt(self->Var(), values); + } + Constraint* Member(const std::vector& values) { + return self->solver()->MakeMemberCt(self->Var(), values); + } + IntVar* IsEqual(IntExpr* const other) { + return self->solver()->MakeIsEqualVar(self->Var(), other->Var()); + } + IntVar* IsDifferent(IntExpr* const other) { + return self->solver()->MakeIsDifferentVar(self->Var(), other->Var()); + } + IntVar* IsGreater(IntExpr* const other) { + return self->solver()->MakeIsGreaterVar(self->Var(), other->Var()); + } + IntVar* IsGreaterOrEqual(IntExpr* const other) { + return self->solver()->MakeIsGreaterOrEqualVar(self->Var(), other->Var()); + } + IntVar* IsLess(IntExpr* const other) { + return self->solver()->MakeIsLessVar(self->Var(), other->Var()); + } + IntVar* IsLessOrEqual(IntExpr* const other) { + return self->solver()->MakeIsLessOrEqualVar(self->Var(), other->Var()); + } + OptimizeVar* Minimize(long step) { + return self->solver()->MakeMinimize(self->Var(), step); + } + OptimizeVar* Maximize(long step) { + return self->solver()->MakeMaximize(self->Var(), step); + } +} + +%typemap(cscode) Solver %{ + public IntVar[] MakeIntVarArray(int count, long min, long max) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + array[i] = MakeIntVar(min, max); + } + return array; + } + + public IntVar[] MakeIntVarArray(int count, long min, long max, string name) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + string var_name = name + i; + array[i] = MakeIntVar(min, max, var_name); + } + return array; + } + + public IntVar[] MakeIntVarArray(int count, long[] values) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + array[i] = MakeIntVar(values); + } + return array; + } + + public IntVar[] MakeIntVarArray(int count, long[] values, string name) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + string var_name = name + i; + array[i] = MakeIntVar(values, var_name); + } + return array; + } + + public IntVar[] MakeIntVarArray(int count, int[] values) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + array[i] = MakeIntVar(values); + } + return array; + } + + public IntVar[] MakeIntVarArray(int count, int[] values, string name) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + string var_name = name + i; + array[i] = MakeIntVar(values, var_name); + } + return array; + } + + public IntVar[] MakeBoolVarArray(int count) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + array[i] = MakeBoolVar(); + } + return array; + } + + public IntVar[] MakeBoolVarArray(int count, string name) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + string var_name = name + i; + array[i] = MakeBoolVar(var_name); + } + return array; + } + + public IntVar[,] MakeIntVarMatrix(int rows, int cols, long min, long max) { + IntVar[,] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + array[i,j] = MakeIntVar(min, max); + } + } + return array; + } + + public IntVar[,] MakeIntVarMatrix(int rows, int cols, + long min, long max, string name) { + IntVar[,] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "["+ i + ", " + j +"]"; + array[i,j] = MakeIntVar(min, max, var_name); + } + } + return array; + } + + public IntVar[,] MakeIntVarMatrix(int rows, int cols, long[] values) { + IntVar[,] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + array[i,j] = MakeIntVar(values); + } + } + return array; + } + + public IntVar[,] MakeIntVarMatrix(int rows, int cols, + long[] values, string name) { + IntVar[,] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "["+ i + ", " + j +"]"; + array[i,j] = MakeIntVar(values, var_name); + } + } + return array; + } + + public IntVar[,] MakeIntVarMatrix(int rows, int cols, int[] values) { + IntVar[,] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + array[i,j] = MakeIntVar(values); + } + } + return array; + } + + public IntVar[,] MakeIntVarMatrix(int rows, int cols, + int[] values, string name) { + IntVar[,] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "["+ i + ", " + j +"]"; + array[i,j] = MakeIntVar(values, var_name); + } + } + return array; + } + + public IntVar[,] MakeBoolVarMatrix(int rows, int cols) { + IntVar[,] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + array[i,j] = MakeBoolVar(); + } + } + return array; + } + + public IntVar[,] MakeBoolVarMatrix(int rows, int cols, string name) { + IntVar[,] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "["+ i + ", " + j +"]"; + array[i,j] = MakeBoolVar(var_name); + } + } + return array; + } + + public IntervalVar[] MakeFixedDurationIntervalVarArray(int count, + long start_min, + long start_max, + long duration, + bool optional) { + IntervalVar[] array = new IntervalVar[count]; + for (int i = 0; i < count; ++i) { + array[i] = MakeFixedDurationIntervalVar(start_min, + start_max, + duration, + optional, + ""); + } + return array; + } + + public IntervalVar[] MakeFixedDurationIntervalVarArray(int count, + long start_min, + long start_max, + long duration, + bool optional, + string name) { + IntervalVar[] array = new IntervalVar[count]; + for (int i = 0; i < count; ++i) { + array[i] = MakeFixedDurationIntervalVar(start_min, + start_max, + duration, + optional, + name + i); + } + return array; + } + + public IntervalVar[] MakeFixedDurationIntervalVarArray(int count, + long[] start_min, + long[] start_max, + long[] duration, + bool optional, + string name) { + IntervalVar[] array = new IntervalVar[count]; + for (int i = 0; i < count; ++i) { + array[i] = MakeFixedDurationIntervalVar(start_min[i], + start_max[i], + duration[i], + optional, + name + i); + } + return array; + } + + public IntervalVar[] MakeFixedDurationIntervalVarArray(int count, + int[] start_min, + int[] start_max, + int[] duration, + bool optional, + string name) { + IntervalVar[] array = new IntervalVar[count]; + for (int i = 0; i < count; ++i) { + array[i] = MakeFixedDurationIntervalVar(start_min[i], + start_max[i], + duration[i], + optional, + name + i); + } + return array; + } + public IntervalVar[] MakeFixedDurationIntervalVarArray(IntVar[] starts, + int[] durations, + string name) { + int count = starts.Length; + IntervalVar[] array = new IntervalVar[count]; + for (int i = 0; i < count; ++i) { + array[i] = MakeFixedDurationIntervalVar(starts[i], + durations[i], + name + i); + } + return array; + } + public IntervalVar[] MakeFixedDurationIntervalVarArray(IntVar[] starts, + long[] durations, + string name) { + int count = starts.Length; + IntervalVar[] array = new IntervalVar[count]; + for (int i = 0; i < count; ++i) { + array[i] = MakeFixedDurationIntervalVar(starts[i], + durations[i], + name + i); + } + return array; + } + public void NewSearch(DecisionBuilder db) { + pinned_decision_builder_ = db; + pinned_search_monitors_.Clear(); + NewSearchAux(db); + } + + public void NewSearch(DecisionBuilder db, SearchMonitor sm1) { + pinned_decision_builder_ = db; + pinned_search_monitors_.Clear(); + pinned_search_monitors_.Add(sm1); + NewSearchAux(db, sm1); + } + + + public void NewSearch(DecisionBuilder db, + SearchMonitor sm1, + SearchMonitor sm2) { + pinned_decision_builder_ = db; + pinned_search_monitors_.Clear(); + pinned_search_monitors_.Add(sm1); + pinned_search_monitors_.Add(sm2); + NewSearchAux(db, sm1, sm2); + } + + public void NewSearch(DecisionBuilder db, + SearchMonitor sm1, + SearchMonitor sm2, + SearchMonitor sm3) { + pinned_decision_builder_ = db; + pinned_search_monitors_.Clear(); + pinned_search_monitors_.Add(sm1); + pinned_search_monitors_.Add(sm2); + pinned_search_monitors_.Add(sm3); + NewSearchAux(db, sm1, sm2, sm3); + } + + public void NewSearch(DecisionBuilder db, + SearchMonitor sm1, + SearchMonitor sm2, + SearchMonitor sm3, + SearchMonitor sm4) { + pinned_decision_builder_ = db; + pinned_search_monitors_.Clear(); + pinned_search_monitors_.Add(sm1); + pinned_search_monitors_.Add(sm2); + pinned_search_monitors_.Add(sm3); + pinned_search_monitors_.Add(sm4); + NewSearchAux(db, sm1, sm2, sm3, sm4); + } + + public void NewSearch(DecisionBuilder db, SearchMonitor[] monitors) { + pinned_decision_builder_ = db; + pinned_search_monitors_.Clear(); + pinned_search_monitors_.AddRange(monitors); + NewSearchAux(db, monitors); + } + + public void EndSearch() { + pinned_decision_builder_ = null; + pinned_search_monitors_.Clear(); + EndSearchAux(); + } + + private System.Collections.Generic.List pinned_search_monitors_ + = new System.Collections.Generic.List(); + private DecisionBuilder pinned_decision_builder_; +%} + +%extend IntVarLocalSearchFilter { + int Index(IntVar* const var) { + int64 index = -1; + self->FindIndex(var, &index); + return index; + } +} + +} // namespace operations_research + +CS_VECTOR_RETURN1(operations_research, SequenceVarLocalSearchOperator, Sequence, + int, int64) +CS_VECTOR_RETURN1(operations_research, SequenceVarLocalSearchOperator, + OldSequence, int, int64) + +%typemap(cscode) operations_research::SequenceVarLocalSearchOperator %{ + public int[] Sequence(long a) { + int size = SequenceSize(a); + int[] result = new int[size]; + for (int position = 0; position < size; ++position) { + result[position] = SequenceValueAt(a, position); + } + return result; + } + public int[] OldSequence(long a) { + int size = OldSequenceSize(a); + int[] result = new int[size]; + for (int position = 0; position < size; ++position) { + result[position] = OldSequenceValueAt(a, position); + } + return result; + } +%} + +CS_VECTOR_RETURN2(operations_research, SolutionCollector, ForwardSequence, + int, int, SequenceVar*) +CS_VECTOR_RETURN2(operations_research, SolutionCollector, BackwardSequence, + int, int, SequenceVar*) +CS_VECTOR_RETURN2(operations_research, SolutionCollector, Unperformed, + int, int, SequenceVar*) + +%typemap(cscode) operations_research::SolutionCollector %{ + public int[] ForwardSequence(int a, SequenceVar b) { + int size = ForwardSequenceSize(a, b); + int[] result = new int[size]; + for (int position = 0; position < size; ++position) { + result[position] = ForwardSequenceValueAt(a, b, position); + } + return result; + } + public int[] BackwardSequence(int a, SequenceVar b) { + int size = BackwardSequenceSize(a, b); + int[] result = new int[size]; + for (int position = 0; position < size; ++position) { + result[position] = BackwardSequenceValueAt(a, b, position); + } + return result; + } + public int[] Unperformed(int a, SequenceVar b) { + int size = UnperformedSize(a, b); + int[] result = new int[size]; + for (int position = 0; position < size; ++position) { + result[position] = UnperformedValueAt(a, b, position); + } + return result; + } +%} + +CS_VECTOR_RETURN1(operations_research, Assignment, ForwardSequence, + int, const SequenceVar* const) +CS_VECTOR_RETURN1(operations_research, Assignment, BackwardSequence, + int, const SequenceVar* const) +CS_VECTOR_RETURN1(operations_research, Assignment, Unperformed, + int, const SequenceVar* const) + +%typemap(cscode) operations_research::Assignment %{ + public int[] ForwardSequence(SequenceVar a) { + int size = ForwardSequenceSize(a); + int[] result = new int[size]; + for (int position = 0; position < size; ++position) { + result[position] = ForwardSequenceValueAt(a, position); + } + return result; + } + public int[] BackwardSequence(SequenceVar a) { + int size = BackwardSequenceSize(a); + int[] result = new int[size]; + for (int position = 0; position < size; ++position) { + result[position] = BackwardSequenceValueAt(a, position); + } + return result; + } + public int[] Unperformed(SequenceVar a) { + int size = UnperformedSize(a); + int[] result = new int[size]; + for (int position = 0; position < size; ++position) { + result[position] = UnperformedValueAt(a, position); + } + return result; + } +%} + +CS_VECTOR_RETURN0(operations_research, SequenceVarElement, ForwardSequence, + int) +CS_VECTOR_RETURN0(operations_research, SequenceVarElement, BackwardSequence, + int) +CS_VECTOR_RETURN0(operations_research, SequenceVarElement, Unperformed, + int) + +%typemap(cscode) operations_research::SequenceVarElement %{ + public int[] ForwardSequence() { + int size = ForwardSequenceSize(); + int[] result = new int[size]; + for (int position = 0; position < size; ++position) { + result[position] = ForwardSequenceValueAt(position); + } + return result; + } + public int[] BackwardSequence() { + int size = BackwardSequenceSize(); + int[] result = new int[size]; + for (int position = 0; position < size; ++position) { + result[position] = BackwardSequenceValueAt(position); + } + return result; + } + public int[] Unperformed() { + int size = UnperformedSize(); + int[] result = new int[size]; + for (int position = 0; position < size; ++position) { + result[position] = UnperformedValueAt(position); + } + return result; + } +%} + + +%extend operations_research::IntVarLocalSearchOperator { + int64 Value(int64 index) const { return self->Value(index); } + int64 OldValue(int64 index) const { return self->OldValue(index); } +} + +namespace operations_research { +class LocalSearchPhaseParameters { + public: + LocalSearchPhaseParameters(); + ~LocalSearchPhaseParameters(); +}; +} // namespace operations_research + +// Wrap cp includes +%include constraint_solver/constraint_solver.h +%include constraint_solver/constraint_solveri.h + +// Define templates instantiation after wrapping. +namespace operations_research { +%template(RevInteger) Rev; +%template(RevBool) Rev; +typedef Assignment::AssignmentContainer AssignmentContainer; +%template(AssignmentIntContainer) AssignmentContainer; +} diff --git a/src/constraint_solver/csharp/routing.swig b/src/constraint_solver/csharp/routing.swig new file mode 100644 index 0000000000..a24c453aa1 --- /dev/null +++ b/src/constraint_solver/csharp/routing.swig @@ -0,0 +1,98 @@ +// TODO(user): Refactor this file to adhere to the SWIG style guide. + +%include "constraint_solver/csharp/constraint_solver.swig" + +// Include the file we want to wrap a first time. +%{ +#include "constraint_solver/routing.h" +%} + +// Convert RoutingModel::NodeIndex to (32-bit signed) integers. +%typemap(ctype) operations_research::RoutingModel::NodeIndex "int" +%typemap(imtype) operations_research::RoutingModel::NodeIndex "int" +%typemap(cstype) operations_research::RoutingModel::NodeIndex "int" +%typemap(csin) operations_research::RoutingModel::NodeIndex "$csinput" +%typemap(csout) operations_research::RoutingModel::NodeIndex { + return $imcall; +} +%typemap(in) operations_research::RoutingModel::NodeIndex { + $1 = operations_research::RoutingModel::NodeIndex($input); +} +%typemap(out) operations_research::RoutingModel::NodeIndex { + $result = $1.value(); +} +%typemap(csvarin) operations_research::RoutingModel::NodeIndex +%{ + set { $imcall; } +%} +%typemap(csvarout, excode=SWIGEXCODE) operations_research::RoutingModel::NodeIndex +%{ + get { + return $imcall; + } +%} + +// Convert std::vector to/from int arrays. +CS_TYPEMAP_STDVECTOR(operations_research::RoutingModel::NodeIndex, int, int); +CS_TYPEMAP_STDVECTOR_IN1(operations_research::RoutingModel::NodeIndex, int, int); + +// Create input mapping for NodeEvaluator2 +%module(directors="1") main +%feature("director") NodeEvaluator2; +%{ +class NodeEvaluator2 { + public: + int64 RunAux(operations_research::RoutingModel::NodeIndex i, + operations_research::RoutingModel::NodeIndex j) { + return Run(i.value(), j.value()); + } + virtual int64 Run(int i, int j) = 0; + operations_research::RoutingModel::NodeEvaluator2* GetPermanentCallback() { + return NewPermanentCallback(this, &NodeEvaluator2::RunAux); + } + virtual ~NodeEvaluator2() {} +}; +%} + +class NodeEvaluator2 { + public: + virtual ~NodeEvaluator2(); + virtual int64 Run(int i, int j) = 0; + operations_research::RoutingModel::NodeEvaluator2* GetPermanentCallback(); +}; + +%typemap(cstype) operations_research::RoutingModel::NodeEvaluator2* "NodeEvaluator2"; +%typemap(csin) operations_research::RoutingModel::NodeEvaluator2* "$descriptor(ResultCallback2*).getCPtr($csinput.GetPermanentCallback())"; + +%ignore operations_research::RoutingModel::AddVectorDimension( + const int64* values, + int64 capacity, + const string& name); + +%ignore operations_research::RoutingModel::AddMatrixDimension( + const int64* const* values, + int64 capacity, + const string& name); + +%extend operations_research::RoutingModel { + void AddVectorDimension(const std::vector& values, + int64 capacity, + bool fix_start_cumul_to_zero, + const string& name) { + DCHECK_EQ(values.size(), self->nodes()); + self->AddVectorDimension(values.data(), capacity, + fix_start_cumul_to_zero, name); + } +} + +%ignore operations_research::RoutingModel::WrapIndexEvaluator( + Solver::IndexEvaluator2* evaluator); + +%ignore operations_research::RoutingModel::RoutingModel( + int nodes, int vehicles, + const std::vector >& start_end); + +%rename("%(camelcase)s", %$isfunction) ""; + +// Wrap cp includes +%include constraint_solver/routing.h diff --git a/src/graph/csharp/graph.swig b/src/graph/csharp/graph.swig new file mode 100644 index 0000000000..ba8b589689 --- /dev/null +++ b/src/graph/csharp/graph.swig @@ -0,0 +1,54 @@ +// TODO(user): Refactor this file to adhere to the SWIG style guide. + +%include util/csharp/data.swig + +// First phase: #include the file we want to wrap. +%{ +#include "util/zvector.h" +#include "graph/ebert_graph.h" +#include "graph/assignment.h" +#include "graph/max_flow.h" +#include "graph/min_cost_flow.h" +%} + +// Rename rules on EbertGraph. +%rename(EndArcIndex) operations_research::StarGraphBase::end_arc_index; +%rename(EndNodeIndex) operations_research::StarGraphBase::end_node_index; +%rename(MaxEndArcIndex) operations_research::StarGraphBase::max_end_arc_index; +%rename(MaxEndNodeIndex) operations_research::StarGraphBase::max_end_node_index; +%rename(MaxNumArcs) operations_research::StarGraphBase::max_num_arcs; +%rename(MaxNumArcs) operations_research::StarGraphBase::max_num_arcs; +%rename(MaxNumNodes) operations_research::StarGraphBase::max_num_nodes; +%rename(MaxNumNodes) operations_research::StarGraphBase::max_num_nodes; +%rename(NumArcs) operations_research::StarGraphBase::num_arcs; +%rename(NumNodes) operations_research::StarGraphBase::num_nodes; + +// Rename rules on MaxFlow. +%rename (Graph) operations_research::MaxFlow::graph; +%rename (GetStatus) operations_research::MaxFlow::status; + +// Rename rules on MinCostFlow. +%rename (Graph) operations_research::MinCostFlow::graph; +%rename (GetStatus) operations_research::MinCostFlow::status; + +// Use the SimpleLinearSumAssignment. +%rename(ComplexLinearSumAssignment) operations_research::LinearSumAssignment; +%rename(LinearSumAssignment) operations_research::SimpleLinearSumAssignment; + +// Second phase: %include the same files. +%include "util/zvector.h" +%include "graph/ebert_graph.h" +%include "graph/assignment.h" +%include "graph/max_flow.h" +%include "graph/min_cost_flow.h" + +%template(StarStarGraphBase) operations_research::StarGraphBase >; +%template(StarGraphCore) operations_research::EbertGraphBase >; +%template(StarGraph) operations_research::EbertGraph; +%template(ForwardStarStarGraphBase) operations_research::StarGraphBase >; +%template(ForwardStarGraphCore) operations_research::EbertGraphBase >; +%template(ForwardStarGraph) operations_research::ForwardEbertGraph; +%template(ForwardStarStaticStarGraphBase) operations_research::StarGraphBase >; +%template(ForwardStarStaticGraph) operations_research::ForwardStaticGraph; +%template(MaxFlow) operations_research::GenericMaxFlow >; +%template(MinCostFlow) operations_research::GenericMinCostFlow, operations_research::FlowQuantity, operations_research::CostValue>; diff --git a/src/linear_solver/csharp/linear_solver.swig b/src/linear_solver/csharp/linear_solver.swig new file mode 100644 index 0000000000..695d7fc8d8 --- /dev/null +++ b/src/linear_solver/csharp/linear_solver.swig @@ -0,0 +1,488 @@ +// Copyright 2010-2013 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. + +%include base/base.swig +%include util/csharp/data.swig +// Swig doesn't like module initializers. +#define DECLARE_MODULE_INITIALIZER(x); + +// Include the file we want to wrap a first time. +%{ +#include "linear_solver/linear_solver.h" +#include "linear_solver/linear_solver2.pb.h" +#include "linear_solver/linear_solver_ext.h" +%} + +%module(directors="1") operations_research; + +%typemap(csimports) SWIGTYPE %{ + using System; + using System.Collections.Generic; + using System.Runtime.InteropServices; +%} + +namespace operations_research { +// Use system infinity. +%ignore MPSolver::infinity; +// Automatic renaming to camel case. +%rename("%(camelcase)s", %$isfunction) ""; +// Rename MakeRowConstraint into MakeConstraint +%rename (MakeConstraint) MPSolver::MakeRowConstraint; +// Rename classes, remove MP prefix. +%rename (Solver) MPSolver; +%rename (Variable) MPVariable; +%rename (Constraint) MPConstraint; +%rename (Objective) MPObjective; +%rename (SolverParameters) MPSolverParameters; + +// Ignore code on MPSolver, see replacement code below. +%ignore MPSolver::MakeVarArray; +%ignore MPSolver::MakeNumVarArray; +%ignore MPSolver::MakeIntVarArray; +%ignore MPSolver::MakeBoolVarArray; +// The following 3 methods that use protocol buffers as output +// arguments are replaced by methods that return a protocol buffer, +// see code below. +%ignore MPSolver::ExportModel; +%ignore MPSolver::ExportModelToNewProto; +%ignore MPSolver::FillSolutionResponse; +%ignore MPSolver::SolveWithProtocolBuffers; +// Ignore Objective(), use MutableObjective() instead. +%ignore MPSolver::Objective; +%rename (Objective) MPSolver::MutableObjective; +// Ignore export to string methods. +%ignore operations_research::MPSolver::ExportModelAsLpFormat; +%ignore operations_research::MPSolver::ExportModelAsMpsFormat; + +%typemap(cscode) MPVariable %{ + public static LinearExpr operator+(Variable a, double v) + { + return new VarWrapper(a) + v; + } + + public static LinearExpr operator+(double v, Variable a) + { + return a + v; + } + + public static LinearExpr operator+(Variable a, LinearExpr b) + { + return new VarWrapper(a) + b; + } + + public static LinearExpr operator+(Variable a, Variable b) + { + return new VarWrapper(a) + new VarWrapper(b); + } + + public static LinearExpr operator+(LinearExpr a, Variable b) + { + return a + new VarWrapper(b); + } + + public static LinearExpr operator-(Variable a, double v) + { + return new VarWrapper(a) - v; + } + + public static LinearExpr operator-(double v, Variable a) + { + return v - new VarWrapper(a); + } + + public static LinearExpr operator-(Variable a, LinearExpr b) + { + return new VarWrapper(a) - b; + } + + public static LinearExpr operator-(LinearExpr a, Variable b) + { + return a - new VarWrapper(b); + } + + public static LinearExpr operator-(Variable a, Variable b) + { + return new VarWrapper(a) - new VarWrapper(b); + } + + public static LinearExpr operator-(Variable a) + { + return - new VarWrapper(a); + } + + public static LinearExpr operator*(Variable a, double v) + { + return new VarWrapper(a) * v; + } + + public static LinearExpr operator/(Variable a, double v) + { + return new VarWrapper(a) / v; + } + + public static LinearExpr operator*(double v, Variable a) + { + return v * new VarWrapper(a); + } + + public static RangeConstraint operator==(Variable a, double v) + { + return new VarWrapper(a) == v; + } + + public static RangeConstraint operator==(double v, Variable a) + { + return v == new VarWrapper(a); + } + + public static RangeConstraint operator!=(Variable a, double v) + { + return new VarWrapper(a) != v; + } + + public static RangeConstraint operator!=(double v, Variable a) + { + return new VarWrapper(a) != v; + } + + public static Equality operator==(Variable a, LinearExpr b) + { + return new VarWrapper(a) == b; + } + + public static Equality operator==(LinearExpr a, Variable b) + { + return a == new VarWrapper(b); + } + + public static VarEquality operator==(Variable a, Variable b) + { + return new VarEquality(a, b, true); + } + + public static Equality operator!=(Variable a, LinearExpr b) + { + return new VarWrapper(a) != b; + } + + public static Equality operator!=(LinearExpr a, Variable b) + { + return a != new VarWrapper(b); + } + + public static VarEquality operator!=(Variable a, Variable b) + { + return new VarEquality(a, b, false); + } + + public static RangeConstraint operator<=(Variable a, double v) + { + return new VarWrapper(a) <= v; + } + + public static RangeConstraint operator>=(Variable a, double v) + { + return new VarWrapper(a) >= v; + } + + public static RangeConstraint operator<=(double v, Variable a) + { + return new VarWrapper(a) >= v; + } + + public static RangeConstraint operator>=(double v, Variable a) + { + return new VarWrapper(a) <= v; + } + + public static RangeConstraint operator<=(Variable a, LinearExpr b) + { + return new VarWrapper(a) <= b; + } + + public static RangeConstraint operator>=(Variable a, LinearExpr b) + { + return new VarWrapper(a) >= b; + } + + public static RangeConstraint operator<=(Variable a, Variable b) + { + return new VarWrapper(a) <= new VarWrapper(b); + } + + public static RangeConstraint operator>=(Variable a, Variable b) + { + return new VarWrapper(a) >= new VarWrapper(b); + } + + public static RangeConstraint operator<=(LinearExpr a, Variable b) + { + return a <= new VarWrapper(b); + } + + public static RangeConstraint operator>=(LinearExpr a, Variable b) + { + return a >= new VarWrapper(b); + } +%} + +%extend MPSolver { + std::string ExportModelAsLpFormat(bool obfuscated) { + std::string output; + if (!self->ExportModelAsLpFormat(obfuscated, &output)) return ""; + return output; + } + + std::string ExportModelAsMpsFormat(bool fixed_format, bool obfuscated) { + std::string output; + if (!self->ExportModelAsMpsFormat(fixed_format, obfuscated, &output)) { + return ""; + } + return output; + } +} + +// Add csharp code on Solver. +%typemap(cscode) MPSolver %{ + public Variable[] MakeVarArray(int count, + double lb, + double ub, + bool integer) { + Variable[] array = new Variable[count]; + for (int i = 0; i < count; ++i) { + array[i] = MakeVar(lb, ub, integer, ""); + } + return array; + } + + public Variable[] MakeVarArray(int count, + double lb, + double ub, + bool integer, + string var_name) { + Variable[] array = new Variable[count]; + for (int i = 0; i < count; ++i) { + array[i] = MakeVar(lb, ub, integer, var_name + i); + } + return array; + } + + public Variable[,] MakeVarMatrix(int rows, + int cols, + double lb, + double ub, + bool integer) { + Variable[,] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + matrix[i,j] = MakeVar(lb, ub, integer, ""); + } + } + return matrix; + } + + public Variable[,] MakeVarMatrix(int rows, + int cols, + double lb, + double ub, + bool integer, + string name) { + Variable[,] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "[" + i + ", " + j +"]"; + matrix[i,j] = MakeVar(lb, ub, integer, var_name); + } + } + return matrix; + } + + public Variable[] MakeNumVarArray(int count, double lb, double ub) { + return MakeVarArray(count, lb, ub, false); + } + + public Variable[] MakeNumVarArray(int count, + double lb, + double ub, + string var_name) { + return MakeVarArray(count, lb, ub, false, var_name); + } + + public Variable[,] MakeNumVarMatrix(int rows, + int cols, + double lb, + double ub) { + Variable[,] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + matrix[i,j] = MakeNumVar(lb, ub, ""); + } + } + return matrix; + } + + public Variable[,] MakeNumVarMatrix(int rows, + int cols, + double lb, + double ub, + string name) { + Variable[,] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "[" + i + ", " + j +"]"; + matrix[i,j] = MakeNumVar(lb, ub, var_name); + } + } + return matrix; + } + + public Variable[] MakeIntVarArray(int count, double lb, double ub) { + return MakeVarArray(count, lb, ub, true); + } + + public Variable[] MakeIntVarArray(int count, + double lb, + double ub, + string var_name) { + return MakeVarArray(count, lb, ub, true, var_name); + } + + public Variable[,] MakeIntVarMatrix(int rows, + int cols, + double lb, + double ub) { + Variable[,] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + matrix[i,j] = MakeIntVar(lb, ub, ""); + } + } + return matrix; + } + + public Variable[,] MakeIntVarMatrix(int rows, + int cols, + double lb, + double ub, + string name) { + Variable[,] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "[" + i + ", " + j +"]"; + matrix[i,j] = MakeIntVar(lb, ub, var_name); + } + } + return matrix; + } + + public Variable[] MakeBoolVarArray(int count) { + return MakeVarArray(count, 0.0, 1.0, true); + } + + public Variable[] MakeBoolVarArray(int count, string var_name) { + return MakeVarArray(count, 0.0, 1.0, true, var_name); + } + + public Variable[,] MakeBoolVarMatrix(int rows, int cols) { + Variable[,] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + matrix[i,j] = MakeBoolVar(""); + } + } + return matrix; + } + + public Variable[,] MakeBoolVarMatrix(int rows, int cols, string name) { + Variable[,] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "[" + i + ", " + j +"]"; + matrix[i,j] = MakeBoolVar(var_name); + } + } + return matrix; + } + + public static int GetSolverEnum(String solverType) { + System.Reflection.FieldInfo fieldInfo = + typeof(Solver).GetField(solverType); + if (fieldInfo != null) { + return (int)fieldInfo.GetValue(null); + } else { + throw new System.ApplicationException("Solver not supported"); + } + } + + public static Solver CreateSolver(String name, String type) { + System.Reflection.FieldInfo fieldInfo = + typeof(Solver).GetField(type); + if (fieldInfo != null) { + return new Solver(name, (int)fieldInfo.GetValue(null)); + } else { + return null; + } + } + + public Constraint Add(LinearConstraint constraint) { + return constraint.Extract(this); + } + + public void Minimize(LinearExpr expr) + { + Objective().Clear(); + Objective().SetMinimization(); + Dictionary coefficients = + new Dictionary(); + double constant = expr.Visit(coefficients); + foreach (KeyValuePair pair in coefficients) + { + Objective().SetCoefficient(pair.Key, pair.Value); + } + Objective().SetOffset(constant); + } + + public void Maximize(LinearExpr expr) + { + Objective().Clear(); + Objective().SetMaximization(); + Dictionary coefficients = + new Dictionary(); + double constant = expr.Visit(coefficients); + foreach (KeyValuePair pair in coefficients) + { + Objective().SetCoefficient(pair.Key, pair.Value); + } + Objective().SetOffset(constant); + } + + public void Minimize(Variable var) + { + Objective().Clear(); + Objective().SetMinimization(); + Objective().SetCoefficient(var, 1.0); + } + + public void Maximize(Variable var) + { + Objective().Clear(); + Objective().SetMaximization(); + Objective().SetCoefficient(var, 1.0); + } +%} + +} // namespace operations_research + +// Wrap linear_solver includes +%include "linear_solver/linear_solver.h" +%include "linear_solver/linear_solver_ext.h" diff --git a/src/util/csharp/data.swig b/src/util/csharp/data.swig new file mode 100644 index 0000000000..f2ae012360 --- /dev/null +++ b/src/util/csharp/data.swig @@ -0,0 +1,280 @@ +// Copyright 2010-2013 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. + +%include base/base.swig + +%{ +#include +#include "base/integral_types.h" +using std::string; +%} + +%include base/base.swig + +//////////////////////////////////////////////// +// +// CS_TYPEMAP_STDVECTOR +// +// Map c# arrays to c++ vectors for POD types. +// +//////////////////////////////////////////////// + +// This typemap will transform a .net array into a pair length, c array. +// This pair is then used to rebuild a vector from it. +%define CS_TYPEMAP_STDVECTOR(TYPE, CTYPE, CSHARPTYPE) + +%typemap(ctype) const std::vector& %{ int length$argnum, CTYPE* %} +%typemap(imtype) const std::vector& %{ int length$argnum, CSHARPTYPE[] %} +%typemap(cstype) const std::vector& %{ CSHARPTYPE[] %} +%typemap(csin) const std::vector& "$csinput.Length, $csinput" +%typemap(freearg) const std::vector& { delete $1; } +%typemap(in) const std::vector& %{ + $1 = new std::vector; + $1->reserve(length$argnum); + for(int i = 0; i < length$argnum; ++i) { + $1->emplace_back($input[i]); + } +%} +%enddef // CS_TYPEMAP_STDVECTOR + +//////////////////////////////////////////////// +// +// CS_TYPEMAP_STDVECTOR_IN1 +// +// Map c# bi-dimensional arrays to c++ vectors of vectors for POD types. +// +//////////////////////////////////////////////// + +%define CS_TYPEMAP_STDVECTOR_IN1(TYPE, CTYPE, CSHARPTYPE) +%typemap(ctype) const std::vector >& %{ + int len$argnum_1, int len$argnum_2, CTYPE* +%} +%typemap(imtype) const std::vector >& %{ + int len$argnum_1, int len$argnum_2, CSHARPTYPE[] +%} +%typemap(cstype) const std::vector >& %{ CSHARPTYPE[,] %} +%typemap(csin) const std::vector >& "$csinput.GetLength(0),$csinput.GetLength(1), NestedArrayHelper.GetFlatArray($csinput)" +%typemap(in) const std::vector >& (std::vector > result) %{ + const int size_x = len$argnum_1; + const int size_y = len$argnum_2; + + result.clear(); + result.resize(size_x); + + TYPE* inner_array = reinterpret_cast($input); + + for (int index1 = 0; index1 < size_x; ++index1) { + result[index1].reserve(size_y); + for (int index2 = 0; index2 < size_y; ++index2) { + const TYPE value = inner_array[index1 * size_y + index2]; + result[index1].emplace_back(value); + } + } + + $1 = &result; +%} +%enddef // CS_TYPEMAP_STDVECTOR_IN1 + +//////////////////////////////////////////////// +// +// CS_TYPEMAP_PTRARRAY +// +//////////////////////////////////////////////// + +// This typemap will perform the same transformation for an array of object. +// The result is an vector of the C objects. +%define CS_TYPEMAP_PTRARRAY(CTYPE, TYPE) + +%typemap(cscode) CTYPE %{ + public static IntPtr[] getCPtr(TYPE[] arr) { + IntPtr[] pointers = new IntPtr[arr.Length]; + for (int i = 0; i < arr.Length; i++) { + pointers[i] = (IntPtr)TYPE.getCPtr(arr[i]); + } + return pointers; + } +%} + +%typemap(ctype) CTYPE** "CTYPE**" + +%typemap(imtype, + inattributes="[In, Out, MarshalAs(UnmanagedType.LPArray)]", + outattributes="[return: MarshalAs(UnmanagedType.LPArray)]") +CTYPE** "IntPtr[]" + +%typemap(cstype) CTYPE** "TYPE[]" +%typemap(csin) CTYPE** "TYPE.getCPtr($csinput)" +%typemap(in) CTYPE** "$1 = $input;" +%typemap(freearg) CTYPE** "" +%typemap(argout) CTYPE** "" + +%enddef // CS_TYPEMAP_PTRARRAY + +//////////////////////////////////////////////// +// +// CS_TYPEMAP_STDVECTOR_OBJECT +// +// Map c# arrays to c++ vectors for swiged C++ objects. +// +//////////////////////////////////////////////// + +%define CS_TYPEMAP_STDVECTOR_OBJECT(CTYPE, TYPE) + +%typemap(cscode) CTYPE %{ + public static IntPtr[] getCPtr(TYPE[] arr) { + IntPtr[] pointers = new IntPtr[arr.Length]; + for (int i = 0; i < arr.Length; i++) + pointers[i] = (IntPtr)TYPE.getCPtr(arr[i]); + return pointers; + } +%} + +%typemap(ctype) const std::vector& "int length$argnum, CTYPE**" +%typemap(imtype) const std::vector& "int length$argnum, IntPtr[]" +%typemap(cstype) const std::vector& "TYPE[]" +%typemap(csin) const std::vector& "$csinput.Length, TYPE.getCPtr($csinput)" +%typemap(in) const std::vector& (std::vector result) { + result.reserve(length$argnum); + for (int i = 0; i < length$argnum; i++) { + result.emplace_back($input[i]); + } + $1 = &result; +} +%enddef // CS_TYPEMAP_STDVECTOR_OBJECT + +CS_TYPEMAP_STDVECTOR(int64, int64, long) +CS_TYPEMAP_STDVECTOR(int, int, int) +CS_TYPEMAP_STDVECTOR_IN1(int64, int64, long) +CS_TYPEMAP_STDVECTOR_IN1(int, int, int) + +// SWIG macros to be used in generating C# wrappers for C++ protocol +// message parameters. Each protocol message is serialized into +// byte[] before passing into (or returning from) C++ code. + +// If the C++ function expects an input protocol message, transferring +// ownership to the caller (in C++): +// foo(const MyProto* message,...) +// Use PROTO_INPUT macro: +// PROTO_INPUT(MyProto, Google.Proto.Protos.Test.MyProto, message) +// +// if the C++ function returns a protocol message: +// MyProto* foo(); +// Use PROTO2_RETURN macro: +// PROTO2_RETURN(MyProto, Google.Proto.Protos.Test.MyProto, true) +// +// Replace true by false if the C++ function returns a pointer to a +// protocol message object whose ownership is not transferred to the +// (C++) caller. +// +// Passing each protocol message from C# to C++ by value. Each ProtocolMessage +// is serialized into byte[] when it is passed from C# to C++, the C++ code +// deserializes into C++ native protocol message. +// +// @param CppProtoType the fully qualified C++ protocol message type +// @param CSharpProtoType the corresponding fully qualified C# protocol message +// type +// @param param_name the parameter name +// @param deleteCppReturn indicates that the resulting object is a native +// (java, c#, python) object, and thus the C++ proto can be safely deleted +// after the conversion. +%define PROTO_INPUT(CppProtoType, CSharpProtoType, param_name) +%typemap(ctype) PROTO_TYPE* INPUT, PROTO_TYPE& INPUT "int proto_size, char*" +%typemap(imtype) PROTO_TYPE* INPUT, PROTO_TYPE& INPUT "int proto_size, byte[]" +%typemap(cstype) PROTO_TYPE* INPUT, PROTO_TYPE& INPUT "CSharpProtoType" +%typemap(csin) PROTO_TYPE* INPUT, PROTO_TYPE& INPUT "$csinput.GetByteArrayLength(), $csinput.ToByteArray()" +%typemap(in) PROTO_TYPE* INPUT (CppProtoType temp), PROTO_TYPE& INPUT (CppProtoType temp) { + int proto_size = 0; + std::unique_ptr proto_buffer($input); + bool parsed_ok = temp.ParseFromArray(proto_buffer.get(), proto_size); + if (!parsed_ok) { + SWIG_CSharpSetPendingException( + SWIG_CSharpSystemException, + "Unable to parse CppProtoType protocol message."); + } + $1 = &temp; +} + +%apply PROTO_TYPE& INPUT { const CppProtoType& param_name } +%apply PROTO_TYPE& INPUT { CppProtoType& param_name } +%apply PROTO_TYPE* INPUT { const CppProtoType* param_name } +%apply PROTO_TYPE* INPUT { CppProtoType* param_name } + +%enddef // end PROTO_INPUT + +%define PROTO2_RETURN(CppProtoType, CSharpProtoType, deleteCppReturn) +%typemap(ctype) CppProtoType* "char*" +%typemap(imtype) CppProtoType* "byte[]" +%typemap(cstype) CppProtoType* "CSharpProtoType" +%typemap(csout) CppProtoType* { + byte[] buf = $imcall; + if (buf == null || buf.Length == 0) { + return null; + } + try { + return CSharpProtoType.ParseFrom(buf); + } catch (Google.Protobuf.InvalidProtocolBufferException e) { + throw new SystemException( + "Unable to parse CSharpProtoType protocol message."); + } +} +%typemap(out) CppProtoType* { + std::unique_ptr buf(new char[$1->ByteSize()]); + $1->SerializeWithCachedSizesToArray(reinterpret_cast(buf.get())); + $result = buf.get(); + if (deleteCppReturn) { + // To prevent a memory leak. + delete $1; + $1 = NULL; + } +} +%enddef // end PROTO2_RETURN_AND_DELETE + +%define CS_VECTOR_RETURN0(Namespace, Class, Method, RType) +%ignore Namespace::Class::Method; + +%extend Namespace::Class { + int Method ## Size() const { + return self->Method().size(); + } + RType Method ## ValueAt(int index) const { + return self->Method()[index]; + } +} +%enddef // CS_VECTOR_RETURN0 + +%define CS_VECTOR_RETURN1(Namespace, Class, Method, RType, ArgType) +%ignore Namespace::Class::Method; + +%extend Namespace::Class { + int Method ## Size(ArgType a) const { + return self->Method(a).size(); + } + RType Method ## ValueAt(ArgType a, int index) const { + return self->Method(a)[index]; + } +} +%enddef // CS_VECTOR_RETURN1 + +%define CS_VECTOR_RETURN2(Namespace, Class, Method, RType, + ArgType1, ArgType2) +%ignore Namespace::Class::Method; + +%extend Namespace::Class { + int Method ## Size(ArgType1 a, ArgType2 b) const { + return self->Method(a, b).size(); + } + RType Method ## ValueAt(ArgType1 a, ArgType2 b, int index) const { + return self->Method(a, b)[index]; + } +} +%enddef // CS_VECTOR_RETURN2 diff --git a/src/util/csharp/tuple_set.swig b/src/util/csharp/tuple_set.swig new file mode 100644 index 0000000000..0e076f9b50 --- /dev/null +++ b/src/util/csharp/tuple_set.swig @@ -0,0 +1,17 @@ +// This is the C# SWIG wrapper for ../tuple_set.h. See that file. +// TODO(user): Refactor this file to comply with the SWIG style guide. + +%include "base/base.swig" + +// This .swig include provides a lot of typemap conversion tools. +// TODO(user): see if we really need it. +%include util/csharp/data.swig + +%{ +// TODO(user): See if we really need . +#include +#include "base/integral_types.h" +#include "util/tuple_set.h" +%} + +%include util/tuple_set.h