From b51e77c27d951d8f7524ed0e3bacc0839430959b Mon Sep 17 00:00:00 2001 From: Matthew Moore <mtthw.j.mr@gmail.com> Date: Tue, 24 Apr 2018 02:40:11 -0700 Subject: [PATCH] Initial commit to unify all dotnet under one project --- .gitignore | 5 + Makefile | 5 +- makefiles/Makefile.dotnet.mk | 169 ++++ ortools/dotnet/Google.sln | 34 + ortools/dotnet/OrTools/AssemblyInfo.cs | 11 + ortools/dotnet/OrTools/OrTools.csproj | 536 +++++++++++ ortools/dotnet/OrTools/OrTools.nuspec | 22 + .../OrTools/algorithms/IntArrayHelper.cs | 76 ++ .../constraintsolver/IntArrayHelper.cs | 145 +++ .../constraintsolver/IntVarArrayHelper.cs | 370 ++++++++ .../IntervalVarArrayHelper.cs | 53 ++ .../constraintsolver/NetDecisionBuilder.cs | 205 ++++ .../OrTools/constraintsolver/SolverHelper.cs | 517 ++++++++++ .../OrTools/constraintsolver/ValCstPair.cs | 300 ++++++ .../OrTools/linearsolver/DoubleArrayHelper.cs | 40 + .../OrTools/linearsolver/LinearConstraint.cs | 140 +++ .../dotnet/OrTools/linearsolver/LinearExpr.cs | 344 +++++++ .../OrTools/linearsolver/SolverHelper.cs | 250 +++++ .../OrTools/linearsolver/VariableHelper.cs | 191 ++++ ortools/dotnet/OrTools/sat/Constraints.cs | 47 + ortools/dotnet/OrTools/sat/CpModel.cs | 880 ++++++++++++++++++ ortools/dotnet/OrTools/sat/CpSolver.cs | 257 +++++ .../dotnet/OrTools/sat/IntegerExpressions.cs | 635 +++++++++++++ .../dotnet/OrTools/sat/IntervalVariables.cs | 69 ++ .../dotnet/OrTools/util/NestedArrayHelper.cs | 49 + ortools/dotnet/OrTools/util/ProtoHelper.cs | 30 + ortools/dotnet/README.md | 5 + 27 files changed, 5383 insertions(+), 2 deletions(-) create mode 100644 makefiles/Makefile.dotnet.mk create mode 100644 ortools/dotnet/Google.sln create mode 100644 ortools/dotnet/OrTools/AssemblyInfo.cs create mode 100644 ortools/dotnet/OrTools/OrTools.csproj create mode 100644 ortools/dotnet/OrTools/OrTools.nuspec create mode 100644 ortools/dotnet/OrTools/algorithms/IntArrayHelper.cs create mode 100644 ortools/dotnet/OrTools/constraintsolver/IntArrayHelper.cs create mode 100644 ortools/dotnet/OrTools/constraintsolver/IntVarArrayHelper.cs create mode 100644 ortools/dotnet/OrTools/constraintsolver/IntervalVarArrayHelper.cs create mode 100644 ortools/dotnet/OrTools/constraintsolver/NetDecisionBuilder.cs create mode 100644 ortools/dotnet/OrTools/constraintsolver/SolverHelper.cs create mode 100644 ortools/dotnet/OrTools/constraintsolver/ValCstPair.cs create mode 100644 ortools/dotnet/OrTools/linearsolver/DoubleArrayHelper.cs create mode 100644 ortools/dotnet/OrTools/linearsolver/LinearConstraint.cs create mode 100644 ortools/dotnet/OrTools/linearsolver/LinearExpr.cs create mode 100644 ortools/dotnet/OrTools/linearsolver/SolverHelper.cs create mode 100644 ortools/dotnet/OrTools/linearsolver/VariableHelper.cs create mode 100644 ortools/dotnet/OrTools/sat/Constraints.cs create mode 100644 ortools/dotnet/OrTools/sat/CpModel.cs create mode 100644 ortools/dotnet/OrTools/sat/CpSolver.cs create mode 100644 ortools/dotnet/OrTools/sat/IntegerExpressions.cs create mode 100644 ortools/dotnet/OrTools/sat/IntervalVariables.cs create mode 100644 ortools/dotnet/OrTools/util/NestedArrayHelper.cs create mode 100644 ortools/dotnet/OrTools/util/ProtoHelper.cs create mode 100644 ortools/dotnet/README.md diff --git a/.gitignore b/.gitignore index 440a39b759d..f9510a17ce3 100644 --- a/.gitignore +++ b/.gitignore @@ -82,3 +82,8 @@ tools/netstandard/CreateSigningKey/obj ortools/fsharp/**/bin ortools/fsharp/**/obj ortools/fsharp/**/packages + +ortools/dotnet/**/bin +ortools/dotnet/**/obj +ortools/dotnet/**/packages +*.userprefs diff --git a/Makefile b/Makefile index 32f2b5527d2..9b8d85c936e 100755 --- a/Makefile +++ b/Makefile @@ -55,8 +55,9 @@ include $(OR_ROOT)makefiles/Makefile.third_party.$(SYSTEM).mk include $(OR_ROOT)makefiles/Makefile.cpp.mk include $(OR_ROOT)makefiles/Makefile.python.mk include $(OR_ROOT)makefiles/Makefile.java.mk -include $(OR_ROOT)makefiles/Makefile.csharp.mk -include $(OR_ROOT)makefiles/Makefile.fsharp.mk +include $(OR_ROOT)makefiles/Makefile.dotnet.mk +# include $(OR_ROOT)makefiles/Makefile.csharp.mk +# include $(OR_ROOT)makefiles/Makefile.fsharp.mk include $(OR_ROOT)makefiles/Makefile.archive.mk include $(OR_ROOT)makefiles/Makefile.install.mk diff --git a/makefiles/Makefile.dotnet.mk b/makefiles/Makefile.dotnet.mk new file mode 100644 index 00000000000..388e0f17264 --- /dev/null +++ b/makefiles/Makefile.dotnet.mk @@ -0,0 +1,169 @@ +# ---------- CSharp support using SWIG ---------- +.PHONY: help_dotnet # Generate list of dotnet targets with descriptions. +help_dotnet: + @echo Use one of the following dotnet targets: +ifeq ($(SYSTEM),win) + @tools\grep.exe "^.PHONY: .* #" $(CURDIR)/makefiles/Makefile.dotnet.mk | tools\sed.exe "s/\.PHONY: \(.*\) # \(.*\)/\1\t\2/" + @echo off & echo( +else + @grep "^.PHONY: .* #" $(CURDIR)/makefiles/Makefile.dotnet.mk | sed "s/\.PHONY: \(.*\) # \(.*\)/\1\t\2/" | expand -t20 + @echo +endif + +ORTOOLS_DLL_NAME=OrTools +ORTOOLS_NUSPEC_FILE=$(ORTOOLS_DLL_NAME).nuspec + + +# Check for required build tools +ifeq ($(SYSTEM), win) +DOTNET_EXECUTABLE := $(shell $(WHICH) dotnet.exe 2>nul) +else # UNIX +ifeq ($(PLATFORM),MACOSX) +DOTNET_EXECUTABLE := $(shell dirname ${DOTNET_INSTALL_PATH})$Sdotnet +else # LINUX +DOTNET_EXECUTABLE := $(shell which dotnet) +endif +endif + +.PHONY: csharp_dotnet # Build OrTools +csharp_dotnet: ortoolslib \ + $(GEN_DIR)/com/google/ortools/properties/CommonAssemblyInfo.cs \ + $(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 \ + $(OBJ_DIR)/swig/sat_csharp_wrap.$O \ + $(GEN_DIR)/com/google/ortools/constraintsolver/SearchLimit.g.cs \ + $(GEN_DIR)/com/google/ortools/constraintsolver/SolverParameters.g.cs \ + $(GEN_DIR)/com/google/ortools/constraintsolver/Model.g.cs \ + $(GEN_DIR)/com/google/ortools/constraintsolver/RoutingParameters.g.cs \ + $(GEN_DIR)/com/google/ortools/constraintsolver/RoutingEnums.g.cs \ + $(GEN_DIR)/com/google/ortools/sat/CpModel.g.cs \ + $(GEN_DIR)/com/google/ortools/sat/SatParameters.g.cs + + $(SED) -i -e "s/0.0.0.0/$(OR_TOOLS_VERSION)/" ortools$Sdotnet$S$(ORTOOLS_DLL_NAME)$S$(ORTOOLS_DLL_NAME).csproj + "$(DOTNET_EXECUTABLE)" build ortools$Sdotnet$S$(ORTOOLS_DLL_NAME)$S$(ORTOOLS_DLL_NAME).csproj + + +$(GEN_DIR)/com/google/ortools/properties/GitVersion$(OR_TOOLS_VERSION).txt: \ + | $(GEN_DIR)/com/google/ortools/properties + @echo $(OR_TOOLS_VERSION) > $(GEN_DIR)$Scom$Sgoogle$Sortools$Sproperties$SGitVersion$(OR_TOOLS_VERSION).txt + +# See for background on Windows Explorer File Info Details: +# https://social.msdn.microsoft.com/Forums/vstudio/en-US/27894a09-1eed-48d9-8a0f-2198388d492c/csc-modulelink-or-just-csc-dll-plus-some-external-dllobj-references +# also, https://blogs.msdn.microsoft.com/texblog/2007/04/05/linking-native-c-into-c-applications/ +$(GEN_DIR)/com/google/ortools/properties/CommonAssemblyInfo.cs: \ + $(GEN_DIR)/com/google/ortools/properties/GitVersion$(OR_TOOLS_VERSION).txt + $(COPY) tools$Scsharp$SCommonAssemblyInfo.cs $(GEN_DIR)$Scom$Sgoogle$Sortools$Sproperties + $(SED) -i -e "s/XXXX/$(OR_TOOLS_VERSION)/" $(GEN_DIR)$Scom$Sgoogle$Sortools$Sproperties$SCommonAssemblyInfo.cs + + +$(GEN_DIR)/ortools/linear_solver/linear_solver_csharp_wrap.cc: \ + $(SRC_DIR)/ortools/linear_solver/csharp/linear_solver.i \ + $(SRC_DIR)/ortools/base/base.i \ + $(SRC_DIR)/ortools/util/csharp/proto.i \ + $(LP_DEPS) + $(SWIG_BINARY) $(SWIG_INC) -I$(INC_DIR) -c++ -csharp -o $(GEN_DIR)$Sortools$Slinear_solver$Slinear_solver_csharp_wrap.cc -module operations_research_linear_solver -namespace $(BASE_CLR_ORTOOLS_DLL_NAME).LinearSolver -dllimport "$(CLR_ORTOOLS_IMPORT_DLL_NAME).$(SWIG_LIB_SUFFIX)" -outdir $(GEN_DIR)$Scom$Sgoogle$Sortools$Slinearsolver $(SRC_DIR)$Sortools$Slinear_solver$Scsharp$Slinear_solver.i + +$(OBJ_DIR)/swig/linear_solver_csharp_wrap.$O: $(GEN_DIR)/ortools/linear_solver/linear_solver_csharp_wrap.cc + $(CCC) $(CFLAGS) -c $(GEN_DIR)/ortools/linear_solver/linear_solver_csharp_wrap.cc $(OBJ_OUT)$(OBJ_DIR)$Sswig$Slinear_solver_csharp_wrap.$O + +$(GEN_DIR)/ortools/constraint_solver/constraint_solver_csharp_wrap.cc: \ + $(SRC_DIR)/ortools/constraint_solver/csharp/routing.i \ + $(SRC_DIR)/ortools/constraint_solver/csharp/constraint_solver.i \ + $(SRC_DIR)/ortools/base/base.i \ + $(SRC_DIR)/ortools/util/csharp/proto.i \ + $(SRC_DIR)/ortools/util/csharp/functions.i \ + $(CP_DEPS) + $(SWIG_BINARY) $(SWIG_INC) -I$(INC_DIR) -c++ -csharp -o $(GEN_DIR)$Sortools$Sconstraint_solver$Sconstraint_solver_csharp_wrap.cc -module operations_research_constraint_solver -namespace $(BASE_CLR_ORTOOLS_DLL_NAME).ConstraintSolver -dllimport "$(CLR_ORTOOLS_IMPORT_DLL_NAME).$(SWIG_LIB_SUFFIX)" -outdir $(GEN_DIR)$Scom$Sgoogle$Sortools$Sconstraintsolver $(SRC_DIR)$Sortools$Sconstraint_solver$Scsharp$Srouting.i + $(SED) -i -e 's/CSharp_new_Solver/CSharp_new_CpSolver/g' $(GEN_DIR)/com/google/ortools/constraintsolver/*cs $(GEN_DIR)/ortools/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)/ortools/constraint_solver/constraint_solver_csharp_wrap.* + $(SED) -i -e 's/CSharp_Solver/CSharp_CpSolver/g' $(GEN_DIR)/com/google/ortools/constraintsolver/*cs $(GEN_DIR)/ortools/constraint_solver/constraint_solver_csharp_wrap.* + $(SED) -i -e 's/CSharp_new_Constraint/CSharp_new_CpConstraint/g' $(GEN_DIR)/com/google/ortools/constraintsolver/*cs $(GEN_DIR)/ortools/constraint_solver/constraint_solver_csharp_wrap.* + $(SED) -i -e 's/CSharp_delete_Constraint/CSharp_delete_CpConstraint/g' $(GEN_DIR)/com/google/ortools/constraintsolver/*cs $(GEN_DIR)/ortools/constraint_solver/constraint_solver_csharp_wrap.* + $(SED) -i -e 's/CSharp_Constraint/CSharp_CpConstraint/g' $(GEN_DIR)/com/google/ortools/constraintsolver/*cs $(GEN_DIR)/ortools/constraint_solver/constraint_solver_csharp_wrap.* + +$(OBJ_DIR)/swig/constraint_solver_csharp_wrap.$O: \ + $(GEN_DIR)/ortools/constraint_solver/constraint_solver_csharp_wrap.cc + $(CCC) $(CFLAGS) -c $(GEN_DIR)$Sortools$Sconstraint_solver$Sconstraint_solver_csharp_wrap.cc $(OBJ_OUT)$(OBJ_DIR)$Sswig$Sconstraint_solver_csharp_wrap.$O + +$(GEN_DIR)/ortools/algorithms/knapsack_solver_csharp_wrap.cc: \ + $(SRC_DIR)/ortools/algorithms/csharp/knapsack_solver.i \ + $(SRC_DIR)/ortools/base/base.i \ + $(SRC_DIR)/ortools/util/csharp/proto.i \ + $(SRC_DIR)/ortools/algorithms/knapsack_solver.h + $(SWIG_BINARY) $(SWIG_INC) -I$(INC_DIR) -c++ -csharp -o $(GEN_DIR)$Sortools$Salgorithms$Sknapsack_solver_csharp_wrap.cc -module operations_research_algorithms -namespace $(BASE_CLR_ORTOOLS_DLL_NAME).Algorithms -dllimport "$(CLR_ORTOOLS_IMPORT_DLL_NAME).$(SWIG_LIB_SUFFIX)" -outdir $(GEN_DIR)$Scom$Sgoogle$Sortools$Salgorithms $(SRC_DIR)$Sortools$Salgorithms$Scsharp$Sknapsack_solver.i + +$(OBJ_DIR)/swig/knapsack_solver_csharp_wrap.$O: $(GEN_DIR)/ortools/algorithms/knapsack_solver_csharp_wrap.cc + $(CCC) $(CFLAGS) -c $(GEN_DIR)/ortools/algorithms/knapsack_solver_csharp_wrap.cc $(OBJ_OUT)$(OBJ_DIR)$Sswig$Sknapsack_solver_csharp_wrap.$O + +$(GEN_DIR)/ortools/graph/graph_csharp_wrap.cc: \ + $(SRC_DIR)/ortools/graph/csharp/graph.i \ + $(SRC_DIR)/ortools/base/base.i \ + $(SRC_DIR)/ortools/util/csharp/proto.i \ + $(GRAPH_DEPS) + $(SWIG_BINARY) $(SWIG_INC) -I$(INC_DIR) -c++ -csharp -o $(GEN_DIR)$Sortools$Sgraph$Sgraph_csharp_wrap.cc -module operations_research_graph -namespace $(BASE_CLR_ORTOOLS_DLL_NAME).Graph -dllimport "$(CLR_ORTOOLS_IMPORT_DLL_NAME).$(SWIG_LIB_SUFFIX)" -outdir $(GEN_DIR)$Scom$Sgoogle$Sortools$Sgraph $(SRC_DIR)$Sortools$Sgraph$Scsharp$Sgraph.i + +$(OBJ_DIR)/swig/graph_csharp_wrap.$O: $(GEN_DIR)/ortools/graph/graph_csharp_wrap.cc + $(CCC) $(CFLAGS) -c $(GEN_DIR)$Sortools$Sgraph$Sgraph_csharp_wrap.cc $(OBJ_OUT)$(OBJ_DIR)$Sswig$Sgraph_csharp_wrap.$O + +$(GEN_DIR)/ortools/sat/sat_csharp_wrap.cc: \ + $(SRC_DIR)/ortools/base/base.i \ + $(SRC_DIR)/ortools/sat/csharp/sat.i \ + $(SRC_DIR)/ortools/sat/swig_helper.h \ + $(SRC_DIR)/ortools/util/csharp/proto.i \ + $(SAT_DEPS) + $(SWIG_BINARY) $(SWIG_INC) -I$(INC_DIR) -c++ -csharp -o $(GEN_DIR)$Sortools$Ssat$Ssat_csharp_wrap.cc -module operations_research_sat -namespace $(BASE_CLR_ORTOOLS_DLL_NAME).Sat -dllimport "$(CLR_ORTOOLS_IMPORT_DLL_NAME).$(SWIG_LIB_SUFFIX)" -outdir $(GEN_DIR)$Scom$Sgoogle$Sortools$Ssat $(SRC_DIR)$Sortools$Ssat$Scsharp$Ssat.i + +$(OBJ_DIR)/swig/sat_csharp_wrap.$O: $(GEN_DIR)/ortools/sat/sat_csharp_wrap.cc + $(CCC) $(CFLAGS) -c $(GEN_DIR)/ortools/sat/sat_csharp_wrap.cc $(OBJ_OUT)$(OBJ_DIR)$Sswig$Ssat_csharp_wrap.$O + + +# Protobufs + +$(GEN_DIR)/com/google/ortools/constraintsolver/SearchLimit.g.cs: $(SRC_DIR)/ortools/constraint_solver/search_limit.proto + $(PROTOBUF_DIR)/bin/protoc --proto_path=$(SRC_DIR) --csharp_out=$(GEN_DIR)$Scom$Sgoogle$Sortools$Sconstraintsolver --csharp_opt=file_extension=.g.cs $(SRC_DIR)$Sortools$Sconstraint_solver$Ssearch_limit.proto + +$(GEN_DIR)/com/google/ortools/constraintsolver/SolverParameters.g.cs: $(SRC_DIR)/ortools/constraint_solver/solver_parameters.proto + $(PROTOBUF_DIR)/bin/protoc --proto_path=$(SRC_DIR) --csharp_out=$(GEN_DIR)$Scom$Sgoogle$Sortools$Sconstraintsolver --csharp_opt=file_extension=.g.cs $(SRC_DIR)$Sortools$Sconstraint_solver$Ssolver_parameters.proto + +$(GEN_DIR)/com/google/ortools/constraintsolver/Model.g.cs: $(SRC_DIR)/ortools/constraint_solver/solver_parameters.proto + $(PROTOBUF_DIR)/bin/protoc --proto_path=$(SRC_DIR) --csharp_out=$(GEN_DIR)$Scom$Sgoogle$Sortools$Sconstraintsolver --csharp_opt=file_extension=.g.cs $(SRC_DIR)$Sortools$Sconstraint_solver$Smodel.proto + +$(GEN_DIR)/com/google/ortools/constraintsolver/RoutingParameters.g.cs: $(SRC_DIR)/ortools/constraint_solver/routing_parameters.proto + $(PROTOBUF_DIR)/bin/protoc --proto_path=$(SRC_DIR) --csharp_out=$(GEN_DIR)$Scom$Sgoogle$Sortools$Sconstraintsolver --csharp_opt=file_extension=.g.cs $(SRC_DIR)$Sortools$Sconstraint_solver$Srouting_parameters.proto + +$(GEN_DIR)/com/google/ortools/constraintsolver/RoutingEnums.g.cs: $(SRC_DIR)/ortools/constraint_solver/routing_enums.proto + $(PROTOBUF_DIR)/bin/protoc --proto_path=$(SRC_DIR) --csharp_out=$(GEN_DIR)$Scom$Sgoogle$Sortools$Sconstraintsolver --csharp_opt=file_extension=.g.cs $(SRC_DIR)$Sortools$Sconstraint_solver$Srouting_enums.proto + +$(GEN_DIR)/com/google/ortools/sat/CpModel.g.cs: $(SRC_DIR)/ortools/sat/cp_model.proto + $(PROTOBUF_DIR)/bin/protoc --proto_path=$(SRC_DIR) --csharp_out=$(GEN_DIR)$Scom$Sgoogle$Sortools$Ssat --csharp_opt=file_extension=.g.cs $(SRC_DIR)$Sortools$Ssat$Scp_model.proto + +$(GEN_DIR)/com/google/ortools/sat/SatParameters.g.cs: $(SRC_DIR)/ortools/sat/sat_parameters.proto + $(PROTOBUF_DIR)/bin/protoc --proto_path=$(SRC_DIR) --csharp_out=$(GEN_DIR)$Scom$Sgoogle$Sortools$Ssat --csharp_opt=file_extension=.g.cs $(SRC_DIR)$Sortools$Ssat$Ssat_parameters.proto + + + +.PHONY: pkg_dotnet # Build Nuget Package for distribution. +pkg_dotnet: + $(warning Not Implemented) + +.PHONY: pkg_dotnet-upload # Upload Nuget Package +nuget-pkg_dotnet-upload: nuget_archive + $(warning Not Implemented) + + +.PHONY: detect_dotnet # Show variables used to build dotnet OR-Tools. +detect_dotnet: +ifeq ($(SYSTEM),win) + @echo Relevant info for the dotnet build: +else + @echo Relevant info for the dotnet build: +endif + @echo DOTNET_EXECUTABLE = "$(DOTNET_EXECUTABLE)" + @echo MONO_EXECUTABLE = "$(MONO_EXECUTABLE)" +ifeq ($(SYSTEM),win) + @echo off & echo( +else + @echo +endif diff --git a/ortools/dotnet/Google.sln b/ortools/dotnet/Google.sln new file mode 100644 index 00000000000..f57ebc8f573 --- /dev/null +++ b/ortools/dotnet/Google.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrTools", "OrTools\OrTools.csproj", "{AFA3F878-FB56-4314-B31E-3DA5583B548B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AFA3F878-FB56-4314-B31E-3DA5583B548B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AFA3F878-FB56-4314-B31E-3DA5583B548B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AFA3F878-FB56-4314-B31E-3DA5583B548B}.Debug|x64.ActiveCfg = Debug|x64 + {AFA3F878-FB56-4314-B31E-3DA5583B548B}.Debug|x64.Build.0 = Debug|x64 + {AFA3F878-FB56-4314-B31E-3DA5583B548B}.Debug|x86.ActiveCfg = Debug|x86 + {AFA3F878-FB56-4314-B31E-3DA5583B548B}.Debug|x86.Build.0 = Debug|x86 + {AFA3F878-FB56-4314-B31E-3DA5583B548B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AFA3F878-FB56-4314-B31E-3DA5583B548B}.Release|Any CPU.Build.0 = Release|Any CPU + {AFA3F878-FB56-4314-B31E-3DA5583B548B}.Release|x64.ActiveCfg = Release|x64 + {AFA3F878-FB56-4314-B31E-3DA5583B548B}.Release|x64.Build.0 = Release|x64 + {AFA3F878-FB56-4314-B31E-3DA5583B548B}.Release|x86.ActiveCfg = Release|x86 + {AFA3F878-FB56-4314-B31E-3DA5583B548B}.Release|x86.Build.0 = Release|x86 + EndGlobalSection +EndGlobal diff --git a/ortools/dotnet/OrTools/AssemblyInfo.cs b/ortools/dotnet/OrTools/AssemblyInfo.cs new file mode 100644 index 00000000000..6f5825f7d36 --- /dev/null +++ b/ortools/dotnet/OrTools/AssemblyInfo.cs @@ -0,0 +1,11 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Google.OrTools")] +[assembly: AssemblyDescription(".NET Assembly for the Operations Research Tools project")] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("0a227c4c-8bb3-4db0-808f-55dae227d8c5")] diff --git a/ortools/dotnet/OrTools/OrTools.csproj b/ortools/dotnet/OrTools/OrTools.csproj new file mode 100644 index 00000000000..44cb4b21e16 --- /dev/null +++ b/ortools/dotnet/OrTools/OrTools.csproj @@ -0,0 +1,536 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + + <OutputType>Library</OutputType> + <AssemblyTitle>Google.OrTools</AssemblyTitle> + <TargetFrameworks>netcoreapp2.0</TargetFrameworks> + <AssemblyName>Google.OrTools</AssemblyName> + <UseSharedCompilation>False</UseSharedCompilation> + <NuspecFile>OrTools.nuspec</NuspecFile> + + <GenerateAssemblyInfo>false</GenerateAssemblyInfo> + + <Version>0.0.0.0</Version> + <AssemblyVersion>0.0.0.0</AssemblyVersion> + <FileVersion>0.0.0.0</FileVersion> + + <RootNamespace>Google.OrTools</RootNamespace> + + <AssemblyOriginatorKeyFile>..\..\..\bin\or-tools.snk</AssemblyOriginatorKeyFile> + <SignAssembly>true</SignAssembly> + <PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign> + </PropertyGroup> + + <ItemGroup> + <Compile Include="..\..\..\ortools\gen\com\google\ortools\properties\CommonAssemblyInfo.cs" Link="CommonAssemblyInfo.cs" /> + + <Compile Include="..\..\..\ortools\gen\com\google\ortools\linearsolver\*.cs"> + <Link>linearsolver\%(Filename)%(Extension)</Link> + </Compile> + + <Compile Include="..\..\..\ortools\gen\com\google\ortools\constraintsolver\*.cs"> + <Link>constraintsolver\%(Filename)%(Extension)</Link> + </Compile> + + <Compile Include="..\..\..\ortools\gen\com\google\ortools\algorithms\*.cs"> + <Link>algorithms\%(Filename)%(Extension)</Link> + </Compile> + + <Compile Include="..\..\..\ortools\gen\com\google\ortools\graph\*.cs"> + <Link>graph\%(Filename)%(Extension)</Link> + </Compile> + + <Compile Include="..\..\..\ortools\gen\com\google\ortools\sat\*.cs"> + <Link>sat\%(Filename)%(Extension)</Link> + </Compile> + + </ItemGroup> + + <ItemGroup> + <PackageReference Include="Google.Protobuf" Version="3.5.1" /> + </ItemGroup> + + <ItemGroup> + <Compile Update="..\..\gen\com\google\ortools\linearsolver\Constraint.cs"> + <Link>linearsolver\Constraint.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\linearsolver\MPSolverParameters.cs"> + <Link>linearsolver\MPSolverParameters.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\linearsolver\MpDoubleVector.cs"> + <Link>linearsolver\MpDoubleVector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\linearsolver\Objective.cs"> + <Link>linearsolver\Objective.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\linearsolver\Solver.cs"> + <Link>linearsolver\Solver.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\linearsolver\Variable.cs"> + <Link>linearsolver\Variable.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\linearsolver\operations_research_linear_solver.cs"> + <Link>linearsolver\operations_research_linear_solver.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\linearsolver\operations_research_linear_solverPINVOKE.cs"> + <Link>linearsolver\operations_research_linear_solverPINVOKE.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\Assignment.cs"> + <Link>constraintsolver\Assignment.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\AssignmentElement.cs"> + <Link>constraintsolver\AssignmentElement.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\AssignmentIntContainer.cs"> + <Link>constraintsolver\AssignmentIntContainer.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\BaseIntExpr.cs"> + <Link>constraintsolver\BaseIntExpr.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\BaseLns.cs"> + <Link>constraintsolver\BaseLns.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\BaseObject.cs"> + <Link>constraintsolver\BaseObject.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\BasePathFilter.cs"> + <Link>constraintsolver\BasePathFilter.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\BooleanVar.cs"> + <Link>constraintsolver\BooleanVar.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\CastConstraint.cs"> + <Link>constraintsolver\CastConstraint.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\ChangeValue.cs"> + <Link>constraintsolver\ChangeValue.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\CheapestAdditionFilteredDecisionBuilder.cs"> + <Link>constraintsolver\CheapestAdditionFilteredDecisionBuilder.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\CheapestInsertionFilteredDecisionBuilder.cs"> + <Link>constraintsolver\CheapestInsertionFilteredDecisionBuilder.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\ChristofidesFilteredDecisionBuilder.cs"> + <Link>constraintsolver\ChristofidesFilteredDecisionBuilder.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\ComparatorCheapestAdditionFilteredDecisionBuilder.cs"> + <Link>constraintsolver\ComparatorCheapestAdditionFilteredDecisionBuilder.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\Constraint.cs"> + <Link>constraintsolver\Constraint.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\CpInt64Vector.cs"> + <Link>constraintsolver\CpInt64Vector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\CpInt64VectorVector.cs"> + <Link>constraintsolver\CpInt64VectorVector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\CpIntVector.cs"> + <Link>constraintsolver\CpIntVector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\CpIntVectorVector.cs"> + <Link>constraintsolver\CpIntVectorVector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\CpModelLoader.cs"> + <Link>constraintsolver\CpModelLoader.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\Decision.cs"> + <Link>constraintsolver\Decision.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\DecisionBuilder.cs"> + <Link>constraintsolver\DecisionBuilder.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\DecisionBuilderVector.cs"> + <Link>constraintsolver\DecisionBuilderVector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\DecisionVisitor.cs"> + <Link>constraintsolver\DecisionVisitor.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\DefaultPhaseParameters.cs"> + <Link>constraintsolver\DefaultPhaseParameters.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\Demon.cs"> + <Link>constraintsolver\Demon.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\DisjunctiveConstraint.cs"> + <Link>constraintsolver\DisjunctiveConstraint.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\EvaluatorCheapestAdditionFilteredDecisionBuilder.cs"> + <Link>constraintsolver\EvaluatorCheapestAdditionFilteredDecisionBuilder.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\GlobalCheapestInsertionFilteredDecisionBuilder.cs"> + <Link>constraintsolver\GlobalCheapestInsertionFilteredDecisionBuilder.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\IntExpr.cs"> + <Link>constraintsolver\IntExpr.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\IntIntToLong.cs"> + <Link>constraintsolver\IntIntToLong.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\IntTupleSet.cs"> + <Link>constraintsolver\IntTupleSet.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\IntVar.cs"> + <Link>constraintsolver\IntVar.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\IntVarElement.cs"> + <Link>constraintsolver\IntVarElement.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\IntVarFilteredDecisionBuilder.cs"> + <Link>constraintsolver\IntVarFilteredDecisionBuilder.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\IntVarIterator.cs"> + <Link>constraintsolver\IntVarIterator.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\IntVarLocalSearchFilter.cs"> + <Link>constraintsolver\IntVarLocalSearchFilter.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\IntVarLocalSearchHandler.cs"> + <Link>constraintsolver\IntVarLocalSearchHandler.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\IntVarLocalSearchOperator.cs"> + <Link>constraintsolver\IntVarLocalSearchOperator.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\IntVarLocalSearchOperatorTemplate.cs"> + <Link>constraintsolver\IntVarLocalSearchOperatorTemplate.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\IntVarVector.cs"> + <Link>constraintsolver\IntVarVector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\IntervalVar.cs"> + <Link>constraintsolver\IntervalVar.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\IntervalVarElement.cs"> + <Link>constraintsolver\IntervalVarElement.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\IntervalVarVector.cs"> + <Link>constraintsolver\IntervalVarVector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\LocalCheapestInsertionFilteredDecisionBuilder.cs"> + <Link>constraintsolver\LocalCheapestInsertionFilteredDecisionBuilder.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\LocalSearchFilter.cs"> + <Link>constraintsolver\LocalSearchFilter.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\LocalSearchFilterVector.cs"> + <Link>constraintsolver\LocalSearchFilterVector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\LocalSearchMonitor.cs"> + <Link>constraintsolver\LocalSearchMonitor.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\LocalSearchOperator.cs"> + <Link>constraintsolver\LocalSearchOperator.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\LocalSearchOperatorVector.cs"> + <Link>constraintsolver\LocalSearchOperatorVector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\LocalSearchPhaseParameters.cs"> + <Link>constraintsolver\LocalSearchPhaseParameters.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\LongLongLongToBoolean.cs"> + <Link>constraintsolver\LongLongLongToBoolean.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\LongLongLongToLong.cs"> + <Link>constraintsolver\LongLongLongToLong.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\LongLongToLong.cs"> + <Link>constraintsolver\LongLongToLong.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\LongToBoolean.cs"> + <Link>constraintsolver\LongToBoolean.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\LongToLong.cs"> + <Link>constraintsolver\LongToLong.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\LongToVoid.cs"> + <Link>constraintsolver\LongToVoid.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\Model.g.cs"> + <Link>constraintsolver\Model.g.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\ModelCache.cs"> + <Link>constraintsolver\ModelCache.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\ModelVisitor.cs"> + <Link>constraintsolver\ModelVisitor.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\NoGood.cs"> + <Link>constraintsolver\NoGood.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\NoGoodManager.cs"> + <Link>constraintsolver\NoGoodManager.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\NodeEvaluator2.cs"> + <Link>constraintsolver\NodeEvaluator2.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\NodeEvaluator2Vector.cs"> + <Link>constraintsolver\NodeEvaluator2Vector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\OptimizeVar.cs"> + <Link>constraintsolver\OptimizeVar.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\Pack.cs"> + <Link>constraintsolver\Pack.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\PathOperator.cs"> + <Link>constraintsolver\PathOperator.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\PathWithPreviousNodesOperator.cs"> + <Link>constraintsolver\PathWithPreviousNodesOperator.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\PropagationBaseObject.cs"> + <Link>constraintsolver\PropagationBaseObject.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\PropagationMonitor.cs"> + <Link>constraintsolver\PropagationMonitor.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\RevBool.cs"> + <Link>constraintsolver\RevBool.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\RevInteger.cs"> + <Link>constraintsolver\RevInteger.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\RevPartialSequence.cs"> + <Link>constraintsolver\RevPartialSequence.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\RoutingDimension.cs"> + <Link>constraintsolver\RoutingDimension.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\RoutingEnums.g.cs"> + <Link>constraintsolver\RoutingEnums.g.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\RoutingFilteredDecisionBuilder.cs"> + <Link>constraintsolver\RoutingFilteredDecisionBuilder.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\RoutingLocalSearchFilter.cs"> + <Link>constraintsolver\RoutingLocalSearchFilter.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\RoutingModel.cs"> + <Link>constraintsolver\RoutingModel.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\RoutingModelVisitor.cs"> + <Link>constraintsolver\RoutingModelVisitor.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\RoutingParameters.g.cs"> + <Link>constraintsolver\RoutingParameters.g.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_ResultCallback2T_long_long_RoutingNodeIndex_RoutingNodeIndex_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_ResultCallback2T_long_long_RoutingNodeIndex_RoutingNodeIndex_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_RoutingCostClassIndex.cs"> + <Link>constraintsolver\SWIGTYPE_p_RoutingCostClassIndex.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_RoutingDimensionIndex.cs"> + <Link>constraintsolver\SWIGTYPE_p_RoutingDimensionIndex.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_RoutingDisjunctionIndex.cs"> + <Link>constraintsolver\SWIGTYPE_p_RoutingDisjunctionIndex.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_RoutingVehicleClassIndex.cs"> + <Link>constraintsolver\SWIGTYPE_p_RoutingVehicleClassIndex.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_int.cs"> + <Link>constraintsolver\SWIGTYPE_p_int.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_long_long.cs"> + <Link>constraintsolver\SWIGTYPE_p_long_long.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_operations_research__AssignmentContainerT_operations_research__IntervalVar_operations_research__IntervalVarElement_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_operations_research__AssignmentContainerT_operations_research__IntervalVar_operations_research__IntervalVarElement_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_operations_research__AssignmentContainerT_operations_research__SequenceVar_operations_research__SequenceVarElement_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_operations_research__AssignmentContainerT_operations_research__SequenceVar_operations_research__SequenceVarElement_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_operations_research__AssignmentProto.cs"> + <Link>constraintsolver\SWIGTYPE_p_operations_research__AssignmentProto.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_operations_research__CpModel.cs"> + <Link>constraintsolver\SWIGTYPE_p_operations_research__CpModel.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_operations_research__DemonProfiler.cs"> + <Link>constraintsolver\SWIGTYPE_p_operations_research__DemonProfiler.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_operations_research__IntVarAssignment.cs"> + <Link>constraintsolver\SWIGTYPE_p_operations_research__IntVarAssignment.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_operations_research__IntervalVarAssignment.cs"> + <Link>constraintsolver\SWIGTYPE_p_operations_research__IntervalVarAssignment.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_operations_research__RevIntSetT_int_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_operations_research__RevIntSetT_int_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_operations_research__Search.cs"> + <Link>constraintsolver\SWIGTYPE_p_operations_research__Search.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_operations_research__SequenceVarAssignment.cs"> + <Link>constraintsolver\SWIGTYPE_p_operations_research__SequenceVarAssignment.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_operations_research__SimpleRevFIFOT_operations_research__Demon_p_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_operations_research__SimpleRevFIFOT_operations_research__Demon_p_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_std__functionT_int_flong_longF_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_std__functionT_int_flong_longF_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_std__functionT_long_long_flong_longF_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_std__functionT_long_long_flong_longF_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_std__functionT_long_long_flong_long_long_longF_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_std__functionT_long_long_flong_long_long_longF_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_std__functionT_operations_research__Solver__DecisionModification_fF_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_std__functionT_operations_research__Solver__DecisionModification_fF_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_std__functionT_void_fF_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_std__functionT_void_fF_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_std__functionT_void_flong_longF_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_std__functionT_void_flong_longF_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_std__vectorT_RoutingDisjunctionIndex_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_std__vectorT_RoutingDisjunctionIndex_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_std__vectorT_operations_research__IntVarElement_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_std__vectorT_operations_research__IntVarElement_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_std__vectorT_std__pairT_RoutingNodeIndex_RoutingNodeIndex_t_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_std__vectorT_std__pairT_RoutingNodeIndex_RoutingNodeIndex_t_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_std__vectorT_std__pairT_int_int_t_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_std__vectorT_std__pairT_int_int_t_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_std__vectorT_std__string_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_std__vectorT_std__string_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_std__vectorT_std__vectorT_RoutingNodeIndex_t_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_std__vectorT_std__vectorT_RoutingNodeIndex_t_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SWIGTYPE_p_std__vectorT_unsigned_long_long_t.cs"> + <Link>constraintsolver\SWIGTYPE_p_std__vectorT_unsigned_long_long_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SavingsFilteredDecisionBuilder.cs"> + <Link>constraintsolver\SavingsFilteredDecisionBuilder.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SearchLimit.cs"> + <Link>constraintsolver\SearchLimit.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SearchLimit.g.cs"> + <Link>constraintsolver\SearchLimit.g.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SearchLog.cs"> + <Link>constraintsolver\SearchLog.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SearchMonitor.cs"> + <Link>constraintsolver\SearchMonitor.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SearchMonitorVector.cs"> + <Link>constraintsolver\SearchMonitorVector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SequenceVar.cs"> + <Link>constraintsolver\SequenceVar.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SequenceVarElement.cs"> + <Link>constraintsolver\SequenceVarElement.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SequenceVarLocalSearchHandler.cs"> + <Link>constraintsolver\SequenceVarLocalSearchHandler.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SequenceVarLocalSearchOperator.cs"> + <Link>constraintsolver\SequenceVarLocalSearchOperator.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SequenceVarLocalSearchOperatorTemplate.cs"> + <Link>constraintsolver\SequenceVarLocalSearchOperatorTemplate.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SequenceVarVector.cs"> + <Link>constraintsolver\SequenceVarVector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SolutionCollector.cs"> + <Link>constraintsolver\SolutionCollector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SolutionPool.cs"> + <Link>constraintsolver\SolutionPool.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\Solver.cs"> + <Link>constraintsolver\Solver.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SolverParameters.g.cs"> + <Link>constraintsolver\SolverParameters.g.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SymmetryBreaker.cs"> + <Link>constraintsolver\SymmetryBreaker.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\SymmetryBreakerVector.cs"> + <Link>constraintsolver\SymmetryBreakerVector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\UnsortedNullableRevBitset.cs"> + <Link>constraintsolver\UnsortedNullableRevBitset.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\VoidToBoolean.cs"> + <Link>constraintsolver\VoidToBoolean.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\VoidToString.cs"> + <Link>constraintsolver\VoidToString.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\VoidToVoid.cs"> + <Link>constraintsolver\VoidToVoid.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\operations_research_constraint_solver.cs"> + <Link>constraintsolver\operations_research_constraint_solver.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\constraintsolver\operations_research_constraint_solverPINVOKE.cs"> + <Link>constraintsolver\operations_research_constraint_solverPINVOKE.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\algorithms\KInt64Vector.cs"> + <Link>algorithms\KInt64Vector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\algorithms\KInt64VectorVector.cs"> + <Link>algorithms\KInt64VectorVector.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\algorithms\KnapsackSolver.cs"> + <Link>algorithms\KnapsackSolver.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\algorithms\operations_research_algorithms.cs"> + <Link>algorithms\operations_research_algorithms.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\algorithms\operations_research_algorithmsPINVOKE.cs"> + <Link>algorithms\operations_research_algorithmsPINVOKE.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\graph\LinearSumAssignment.cs"> + <Link>graph\LinearSumAssignment.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\graph\MaxFlow.cs"> + <Link>graph\MaxFlow.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\graph\MinCostFlow.cs"> + <Link>graph\MinCostFlow.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\graph\MinCostFlowBase.cs"> + <Link>graph\MinCostFlowBase.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\graph\SWIGTYPE_p_std__vectorT_int_t.cs"> + <Link>graph\SWIGTYPE_p_std__vectorT_int_t.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\graph\operations_research_graph.cs"> + <Link>graph\operations_research_graph.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\graph\operations_research_graphPINVOKE.cs"> + <Link>graph\operations_research_graphPINVOKE.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\sat\CpModel.g.cs"> + <Link>sat\CpModel.g.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\sat\SatHelper.cs"> + <Link>sat\SatHelper.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\sat\SolutionCallback.cs"> + <Link>sat\SolutionCallback.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\sat\operations_research_sat.cs"> + <Link>sat\operations_research_sat.cs</Link> + </Compile> + <Compile Update="..\..\gen\com\google\ortools\sat\operations_research_satPINVOKE.cs"> + <Link>sat\operations_research_satPINVOKE.cs</Link> + </Compile> + </ItemGroup> +</Project> diff --git a/ortools/dotnet/OrTools/OrTools.nuspec b/ortools/dotnet/OrTools/OrTools.nuspec new file mode 100644 index 00000000000..2832225a92f --- /dev/null +++ b/ortools/dotnet/OrTools/OrTools.nuspec @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<package > + <metadata> + <id>NNNN</id> + <version>VVVV</version> + <authors>Google</authors> + <licenseUrl>https://github.com/google/or-tools/blob/master/LICENSE-2.0.txt</licenseUrl> + <projectUrl>https://developers.google.com/optimization</projectUrl> + <description>.NET Assembly for the Operations Research Tools project</description> + <copyright>Copyright 2018 Google, Inc</copyright> + <tags>Operations Research Math Linear Constraint Programming C# .NET SWIG C++</tags> + <dependencies> + <dependency id="MMMM" version="PROTOBUF_TAG" /> + </dependencies> + </metadata> + <files> + <file src="bin\NNNN.dll" target="lib\net40"/> + <file src="examples\**\*.*" target="examples"/> + <file src="examples\data\**\*.*" target="data"/> + <file src="LICENSE-2.0.txt"/> + </files> +</package> diff --git a/ortools/dotnet/OrTools/algorithms/IntArrayHelper.cs b/ortools/dotnet/OrTools/algorithms/IntArrayHelper.cs new file mode 100644 index 00000000000..ebfcb6e8f4c --- /dev/null +++ b/ortools/dotnet/OrTools/algorithms/IntArrayHelper.cs @@ -0,0 +1,76 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.Algorithms { +using System; +using System.Collections.Generic; + +public partial class KInt64Vector: IDisposable, System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , System.Collections.Generic.IList<long> +#endif +{ + // cast from C# long array + public static implicit operator KInt64Vector(long[] inVal) { + var outVal= new KInt64Vector(); + foreach (long element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# long array + public static implicit operator long[](KInt64Vector inVal) { + var outVal= new long[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; + } +} + +public partial class KInt64VectorVector : IDisposable, System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , System.Collections.Generic.IEnumerable<KInt64Vector> +#endif + { + // cast from C# long matrix + public static implicit operator KInt64VectorVector(long[,] inVal) { + int x_size = inVal.GetLength(0); + int y_size = inVal.GetLength(1); + KInt64VectorVector outVal = new KInt64VectorVector(); + for (int i = 0; i < x_size; ++i) + { + outVal.Add(new KInt64Vector()); + for (int j = 0; j < y_size; ++j) + { + outVal[i].Add(inVal[i, j]); + } + } + return outVal; + } + + // cast to C# long matrix + public static implicit operator long[,](KInt64VectorVector inVal) { + int x_size = inVal.Count; + int y_size = inVal.Count == 0 ? 0 : inVal[0].Count; + var outVal= new long[x_size, y_size]; + for (int i = 0; i < x_size; ++i) + { + for (int j = 0; j < y_size; ++j) + { + outVal[i, j] = inVal[i][j]; + } + } + return outVal; + } +} +} // namespace Google.OrTools.Algorithms diff --git a/ortools/dotnet/OrTools/constraintsolver/IntArrayHelper.cs b/ortools/dotnet/OrTools/constraintsolver/IntArrayHelper.cs new file mode 100644 index 00000000000..bc16cc4ef8f --- /dev/null +++ b/ortools/dotnet/OrTools/constraintsolver/IntArrayHelper.cs @@ -0,0 +1,145 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.ConstraintSolver { +using System; +using System.Collections.Generic; + +// int[] and long[] helper class. +public static class IntArrayHelper { + public static IntExpr Element(this int[] array, IntExpr index) { + return index.solver().MakeElement(array, index.Var()); + } + public static IntExpr Element(this long[] array, IntExpr index) { + return index.solver().MakeElement(array, index.Var()); + } +} + +public partial class CpInt64Vector: IDisposable, System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , System.Collections.Generic.IList<long> +#endif +{ + // cast from C# long array + public static implicit operator CpInt64Vector(long[] inVal) { + var outVal= new CpInt64Vector(); + foreach (long element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# long array + public static implicit operator long[](CpInt64Vector inVal) { + var outVal= new long[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; + } +} + +public partial class CpIntVector: IDisposable, System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , System.Collections.Generic.IList<int> +#endif +{ + // cast from C# int array + public static implicit operator CpIntVector(int[] inVal) { + var outVal= new CpIntVector(); + foreach (int element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# int array + public static implicit operator int[](CpIntVector inVal) { + var outVal= new int[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; + } +} + +public partial class CpIntVectorVector : IDisposable, System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , System.Collections.Generic.IEnumerable<CpIntVector> +#endif + { + // cast from C# int matrix + public static implicit operator CpIntVectorVector(int[,] inVal) { + int x_size = inVal.GetLength(0); + int y_size = inVal.GetLength(1); + CpIntVectorVector outVal = new CpIntVectorVector(); + for (int i = 0; i < x_size; ++i) + { + outVal.Add(new CpIntVector()); + for (int j = 0; j < y_size; ++j) + { + outVal[i].Add(inVal[i, j]); + } + } + return outVal; + } + + // cast to C# int matrix + public static implicit operator int[,](CpIntVectorVector inVal) { + int x_size = inVal.Count; + int y_size = inVal.Count == 0 ? 0 : inVal[0].Count; + var outVal= new int[x_size, y_size]; + for (int i = 0; i < x_size; ++i) + { + for (int j = 0; j < y_size; ++j) + { + outVal[i, j] = inVal[i][j]; + } + } + return outVal; + } +} + +public partial class CpInt64VectorVector : IDisposable, System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , System.Collections.Generic.IEnumerable<CpInt64Vector> +#endif + { + // cast from C# long matrix + public static implicit operator CpInt64VectorVector(long[,] inVal) { + int x_size = inVal.GetLength(0); + int y_size = inVal.GetLength(1); + CpInt64VectorVector outVal = new CpInt64VectorVector(); + for (int i = 0; i < x_size; ++i) + { + outVal.Add(new CpInt64Vector()); + for (int j = 0; j < y_size; ++j) + { + outVal[i].Add(inVal[i, j]); + } + } + return outVal; + } + + // cast to C# long matrix + public static implicit operator long[,](CpInt64VectorVector inVal) { + int x_size = inVal.Count; + int y_size = inVal.Count == 0 ? 0 : inVal[0].Count; + var outVal= new long[x_size, y_size]; + for (int i = 0; i < x_size; ++i) + { + for (int j = 0; j < y_size; ++j) + { + outVal[i, j] = inVal[i][j]; + } + } + return outVal; + } +} +} // namespace Google.OrTools.ConstraintSolver diff --git a/ortools/dotnet/OrTools/constraintsolver/IntVarArrayHelper.cs b/ortools/dotnet/OrTools/constraintsolver/IntVarArrayHelper.cs new file mode 100644 index 00000000000..186eac7c541 --- /dev/null +++ b/ortools/dotnet/OrTools/constraintsolver/IntVarArrayHelper.cs @@ -0,0 +1,370 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.ConstraintSolver +{ +using System; +using System.Collections.Generic; + +// IntVar[] helper class. +public static class IntVarArrayHelper +{ + // All Different + public static Constraint AllDifferent(this IntVar[] vars) + { + Solver solver = GetSolver(vars); + return solver.MakeAllDifferent(vars); + } + // Allowed assignment + public static Constraint AllowedAssignments(this IntVar[] vars, + IntTupleSet tuples) + { + Solver solver = GetSolver(vars); + return solver.MakeAllowedAssignments(vars, tuples); + } + // sum of all vars. + public static IntExpr Sum(this IntVar[] vars) + { + Solver solver = GetSolver(vars); + return solver.MakeSum(vars); + } + // sum of all constraints. + public static IntExpr Sum(this IConstraintWithStatus[] cts) + { + Solver solver = GetSolver(cts); + IntVar[] vars = new IntVar[cts.Length]; + for (int i = 0; i < cts.Length; ++i) + { + vars[i] = cts[i].Var(); + } + return solver.MakeSum(vars); + } + public static IntExpr Sum(this IntExpr[] exprs) + { + Solver solver = GetSolver(exprs); + IntVar[] vars = new IntVar[exprs.Length]; + for (int i = 0; i < exprs.Length; ++i) + { + vars[i] = exprs[i].Var(); + } + return solver.MakeSum(vars); + } + + // scalar product + public static IntExpr ScalProd(this IntVar[] vars, long[] coefs) + { + Solver solver = GetSolver(vars); + return solver.MakeScalProd(vars, coefs); + } + + // scalar product + public static IntExpr ScalProd(this IntVar[] vars, int[] coefs) + { + Solver solver = GetSolver(vars); + return solver.MakeScalProd(vars, coefs); + } + + // get solver from array of integer variables + private static Solver GetSolver(IntVar[] vars) + { + if (vars == null || vars.Length <= 0) + throw new ArgumentException("Array <vars> cannot be null or empty"); + + return vars[0].solver(); + } + // get solver from array of integer expressions + private static Solver GetSolver(IntExpr[] expressions) + { + if (expressions == null || expressions.Length <= 0) + throw new ArgumentException("Array <expr> cannot be null or empty"); + + return expressions[0].solver(); + } + private static Solver GetSolver(IConstraintWithStatus[] cts) + { + if (cts == null || cts.Length <= 0) + throw new ArgumentException("Array <cts> cannot be null or empty"); + + return cts[0].solver(); + } + public static IntExpr Element(this IntVar[] array, IntExpr index) { + return index.solver().MakeElement(array, index.Var()); + } + // min of all vars. + public static IntExpr Min(this IntVar[] vars) + { + Solver solver = GetSolver(vars); + return solver.MakeMin(vars); + } + // min of all vars. + public static IntExpr Max(this IntVar[] vars) + { + Solver solver = GetSolver(vars); + return solver.MakeMax(vars); + } + // count of all vars. + public static Constraint Count(this IntVar[] vars, long value, long count) + { + Solver solver = GetSolver(vars); + return solver.MakeCount(vars, value, count); + } + // count of all vars. + public static Constraint Count(this IntVar[] vars, + long value, + IntExpr count) + { + Solver solver = GetSolver(vars); + return solver.MakeCount(vars, value, count.Var()); + } + public static Constraint Distribute(this IntVar[] vars, + long[] values, + IntVar[] cards) + { + Solver solver = GetSolver(vars); + return solver.MakeDistribute(vars, values, cards); + } + public static Constraint Distribute(this IntVar[] vars, + int[] values, + IntVar[] cards) + { + Solver solver = GetSolver(vars); + return solver.MakeDistribute(vars, values, cards); + } + public static Constraint Distribute(this IntVar[] vars, + IntVar[] cards) + { + Solver solver = GetSolver(vars); + return solver.MakeDistribute(vars, cards); + } + public static Constraint Distribute(this IntVar[] vars, + long card_min, + long card_max, + long card_size) + { + Solver solver = GetSolver(vars); + return solver.MakeDistribute(vars, card_min, card_max, card_size); + } + public static Constraint Transition(this IntVar[] vars, + IntTupleSet transitions, + long initial_state, + long[] final_states) { + Solver solver = GetSolver(vars); + return solver.MakeTransitionConstraint(vars, + transitions, + initial_state, + final_states); + } + public static Constraint Transition(this IntVar[] vars, + IntTupleSet transitions, + long initial_state, + int[] final_states) { + Solver solver = GetSolver(vars); + return solver.MakeTransitionConstraint(vars, + transitions, + initial_state, + final_states); + } + + // Matrix API + public static IntVar[] Flatten(this IntVar[,] vars) + { + int rows = vars.GetLength(0); + int cols = vars.GetLength(1); + IntVar[] flat = new IntVar[cols * rows]; + for(int i = 0; i < rows; i++) { + for(int j = 0; j < cols; j++) { + flat[i * cols + j] = vars[i, j]; + } + } + return flat; + } +} + + +// TODO(user): Try to move this code back to the .swig with @define macros. +public partial class IntVarVector: IDisposable, System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , System.Collections.Generic.IList<IntVar> +#endif +{ + // cast from C# IntVar array + public static implicit operator IntVarVector(IntVar[] inVal) { + var outVal= new IntVarVector(); + foreach (IntVar element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# IntVar array + public static implicit operator IntVar[](IntVarVector inVal) { + var outVal= new IntVar[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; + } +} + +public partial class SearchMonitorVector: IDisposable, System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , System.Collections.Generic.IList<SearchMonitor> +#endif +{ + // cast from C# SearchMonitor array + public static implicit operator SearchMonitorVector(SearchMonitor[] inVal) { + var outVal= new SearchMonitorVector(); + foreach (SearchMonitor element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# SearchMonitor array + public static implicit operator SearchMonitor[](SearchMonitorVector inVal) { + var outVal= new SearchMonitor[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; + } +} + +public partial class DecisionBuilderVector: IDisposable, System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , System.Collections.Generic.IList<DecisionBuilder> +#endif +{ + // cast from C# DecisionBuilder array + public static implicit operator DecisionBuilderVector(DecisionBuilder[] inVal) { + var outVal= new DecisionBuilderVector(); + foreach (DecisionBuilder element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# DecisionBuilder array + public static implicit operator DecisionBuilder[](DecisionBuilderVector inVal) { + var outVal= new DecisionBuilder[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; + } +} + +public partial class IntervalVarVector: IDisposable, System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , System.Collections.Generic.IList<IntervalVar> +#endif +{ + // cast from C# IntervalVar array + public static implicit operator IntervalVarVector(IntervalVar[] inVal) { + var outVal= new IntervalVarVector(); + foreach (IntervalVar element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# IntervalVar array + public static implicit operator IntervalVar[](IntervalVarVector inVal) { + var outVal= new IntervalVar[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; + } +} + +public partial class SequenceVarVector: IDisposable, System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , System.Collections.Generic.IList<SequenceVar> +#endif +{ + // cast from C# SequenceVar array + public static implicit operator SequenceVarVector(SequenceVar[] inVal) { + var outVal= new SequenceVarVector(); + foreach (SequenceVar element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# SequenceVar array + public static implicit operator SequenceVar[](SequenceVarVector inVal) { + var outVal= new SequenceVar[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; + } +} + +public partial class LocalSearchOperatorVector: IDisposable, System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , System.Collections.Generic.IList<LocalSearchOperator> +#endif +{ + // cast from C# LocalSearchOperator array + public static implicit operator LocalSearchOperatorVector(LocalSearchOperator[] inVal) { + var outVal= new LocalSearchOperatorVector(); + foreach (LocalSearchOperator element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# LocalSearchOperator array + public static implicit operator LocalSearchOperator[](LocalSearchOperatorVector inVal) { + var outVal= new LocalSearchOperator[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; + } +} + +public partial class LocalSearchFilterVector: IDisposable, System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , System.Collections.Generic.IList<LocalSearchFilter> +#endif +{ + // cast from C# LocalSearchFilter array + public static implicit operator LocalSearchFilterVector(LocalSearchFilter[] inVal) { + var outVal= new LocalSearchFilterVector(); + foreach (LocalSearchFilter element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# LocalSearchFilter array + public static implicit operator LocalSearchFilter[](LocalSearchFilterVector inVal) { + var outVal= new LocalSearchFilter[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; + } +} + +public partial class SymmetryBreakerVector: IDisposable, System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , System.Collections.Generic.IList<SymmetryBreaker> +#endif +{ + // cast from C# SymmetryBreaker array + public static implicit operator SymmetryBreakerVector(SymmetryBreaker[] inVal) { + var outVal= new SymmetryBreakerVector(); + foreach (SymmetryBreaker element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# SymmetryBreaker array + public static implicit operator SymmetryBreaker[](SymmetryBreakerVector inVal) { + var outVal= new SymmetryBreaker[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; + } +} +} // namespace Google.OrTools.ConstraintSolver diff --git a/ortools/dotnet/OrTools/constraintsolver/IntervalVarArrayHelper.cs b/ortools/dotnet/OrTools/constraintsolver/IntervalVarArrayHelper.cs new file mode 100644 index 00000000000..b78d1b46a62 --- /dev/null +++ b/ortools/dotnet/OrTools/constraintsolver/IntervalVarArrayHelper.cs @@ -0,0 +1,53 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.ConstraintSolver +{ + using System; + using System.Collections.Generic; + + // IntervalVar[] helper class. + public static class IntervalVarArrayHelper + { + // get solver from array of interval variables + private static Solver GetSolver(IntervalVar[] vars) + { + if (vars == null || vars.Length <= 0) + throw new ArgumentException("Array <vars> cannot be null or empty"); + + return vars[0].solver(); + } + public static DisjunctiveConstraint Disjunctive(this IntervalVar[] vars, + String name) + { + Solver solver = GetSolver(vars); + return solver.MakeDisjunctiveConstraint(vars, name); + } + public static Constraint Cumulative(this IntervalVar[] vars, + long[] demands, + long capacity, + String name) + { + Solver solver = GetSolver(vars); + return solver.MakeCumulative(vars, demands, capacity, name); + } + public static Constraint Cumulative(this IntervalVar[] vars, + int[] demands, + long capacity, + String name) + { + Solver solver = GetSolver(vars); + return solver.MakeCumulative(vars, demands, capacity, name); + } + } +} // namespace Google.OrTools.ConstraintSolver diff --git a/ortools/dotnet/OrTools/constraintsolver/NetDecisionBuilder.cs b/ortools/dotnet/OrTools/constraintsolver/NetDecisionBuilder.cs new file mode 100644 index 00000000000..9c3ee0c9357 --- /dev/null +++ b/ortools/dotnet/OrTools/constraintsolver/NetDecisionBuilder.cs @@ -0,0 +1,205 @@ +// Copyright 2010-2017 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; + +namespace Google.OrTools.ConstraintSolver +{ +/** + * This class acts as a intermediate step between a c++ decision builder and a + * .Net one. Its main purpose is to catch the .Net application exception + * launched when a failure occurs during the Next() call, and to return + * silently a System.ApplicationException that will propagate the failure back + * to the C++ code. + * + */ +public class NetDecisionBuilder : DecisionBuilder +{ + /** + * This methods wraps the calls to next() and catches fail exceptions. + * It currently catches all application exceptions. + */ + public override Decision NextWrapper(Solver solver) + { + try + { + return Next(solver); + } + catch (ApplicationException e) + { + // TODO(user): Catch only fail exceptions. + return solver.MakeFailDecision(); + } + } + /** + * This is the new method to subclass when defining a .Net decision builder. + */ + public virtual Decision Next(Solver solver) + { + return null; + } +} + +/** + * This class acts as a intermediate step between a c++ decision and a + * .Net one. Its main purpose is to catch the .Net application + * exception launched when a failure occurs during the + * Apply()/Refute() calls, and to set the ShouldFail() flag on the + * solver that will propagate the failure back to the C++ code. + * + */ +public class NetDecision : Decision +{ + /** + * This methods wraps the calls to Apply() and catches fail exceptions. + * It currently catches all application exceptions. + */ + public override void ApplyWrapper(Solver solver) + { + try + { + Apply(solver); + } + catch (ApplicationException e) + { + // TODO(user): Catch only fail exceptions. + solver.ShouldFail(); + } + } + /** + * This is a new method to subclass when defining a .Net decision. + */ + public virtual void Apply(Solver solver) + { + // By default, do nothing + } + + public override void RefuteWrapper(Solver solver) + { + try + { + Refute(solver); + } + catch (ApplicationException e) + { + // TODO(user): Catch only fail exceptions. + solver.ShouldFail(); + } + } + /** + * This is a new method to subclass when defining a .Net decision. + */ + public virtual void Refute(Solver solver) + { + } +} + +public class NetDemon : Demon +{ + /** + * This methods wraps the calls to next() and catches fail exceptions. + */ + public override void RunWrapper(Solver solver) + { + try + { + Run(solver); + } + catch (ApplicationException e) + { + // TODO(user): Check that this is indeed a fail. Try implementing + // custom exceptions (hard). + solver.ShouldFail(); + } + } + /** + * This is the new method to subclass when defining a .Net decision builder. + */ + public virtual void Run(Solver solver) {} + public override int Priority() { + return Solver.NORMAL_PRIORITY; + } + public override string ToString() { + return "NetDemon"; + } +} + +public class NetConstraint : Constraint { + public NetConstraint(Solver s) : base(s) {} + + public override void InitialPropagateWrapper() { + try { + InitialPropagate(); + } catch (ApplicationException e) { + solver().ShouldFail(); + } + } + public virtual void InitialPropagate() {} + public override string ToString() { + return "NetConstraint"; + } +} + +public class IntVarEnumerator : IEnumerator { + private IntVarIterator iterator_; + + // Enumerators are positioned before the first element + // until the first MoveNext() call. + private bool first_ = true; + + public IntVarEnumerator(IntVarIterator iterator) { + iterator_ = iterator; + } + + public bool MoveNext() { + if (first_) { + iterator_.Init(); + first_ = false; + } else { + iterator_.Next(); + } + return iterator_.Ok(); + } + + public void Reset() { + first_ = true; + } + + object IEnumerator.Current { + get { + return Current; + } + } + + public long Current { + get { + if (!first_ && iterator_.Ok()) { + return iterator_.Value(); + } else { + throw new InvalidOperationException(); + } + } + } +} + +public partial class IntVarIterator : BaseObject, IEnumerable { + IEnumerator IEnumerable.GetEnumerator() { + return (IEnumerator) GetEnumerator(); + } + + public IntVarEnumerator GetEnumerator() { + return new IntVarEnumerator(this); + } +} +} // namespace Google.OrTools.ConstraintSolver diff --git a/ortools/dotnet/OrTools/constraintsolver/SolverHelper.cs b/ortools/dotnet/OrTools/constraintsolver/SolverHelper.cs new file mode 100644 index 00000000000..bf11a4b2520 --- /dev/null +++ b/ortools/dotnet/OrTools/constraintsolver/SolverHelper.cs @@ -0,0 +1,517 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.ConstraintSolver { +using System; +using System.Collections.Generic; + +public partial class Solver : IDisposable { + 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<SearchMonitor> pinned_search_monitors_ + = new System.Collections.Generic.List<SearchMonitor>(); + private DecisionBuilder pinned_decision_builder_; +} + +public partial class IntExpr : PropagationBaseObject { + 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, long v) { + return a.solver().MakeModulo(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())); + } +} + +public partial class Constraint : PropagationBaseObject, IConstraintWithStatus { + 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); + } +} +} // namespace Google.OrTools.ConstraintSolver diff --git a/ortools/dotnet/OrTools/constraintsolver/ValCstPair.cs b/ortools/dotnet/OrTools/constraintsolver/ValCstPair.cs new file mode 100644 index 00000000000..b964a05ae65 --- /dev/null +++ b/ortools/dotnet/OrTools/constraintsolver/ValCstPair.cs @@ -0,0 +1,300 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.ConstraintSolver +{ +using System; +using System.Collections.Generic; + +public interface IConstraintWithStatus +{ + Solver solver(); + IntVar Var(); +} + +public abstract class BaseEquality : IConstraintWithStatus +{ + abstract public Solver solver(); + abstract public IntVar Var(); + + public static IntExpr operator+(BaseEquality a, BaseEquality b) { + return a.solver().MakeSum(a.Var(), b.Var()); + } + public static IntExpr operator+(BaseEquality a, long v) { + return a.solver().MakeSum(a.Var(), v); + } + public static IntExpr operator+(long v, BaseEquality a) { + return a.solver().MakeSum(a.Var(), v); + } + public static IntExpr operator-(BaseEquality a, BaseEquality b) { + return a.solver().MakeDifference(a.Var(), b.Var()); + } + public static IntExpr operator-(BaseEquality a, long v) { + return a.solver().MakeSum(a.Var(), -v); + } + public static IntExpr operator-(long v, BaseEquality a) { + return a.solver().MakeDifference(v, a.Var()); + } + public static IntExpr operator*(BaseEquality a, BaseEquality b) { + return a.solver().MakeProd(a.Var(), b.Var()); + } + public static IntExpr operator*(BaseEquality a, long v) { + return a.solver().MakeProd(a.Var(), v); + } + public static IntExpr operator*(long v, BaseEquality a) { + return a.solver().MakeProd(a.Var(), v); + } + public static IntExpr operator/(BaseEquality a, long v) { + return a.solver().MakeDiv(a.Var(), v); + } + public static IntExpr operator-(BaseEquality 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 ==(BaseEquality a, long v) { + return new WrappedConstraint(a.solver().MakeEquality(a.Var(), v)); + } + public static WrappedConstraint operator ==(long v, BaseEquality a) { + return new WrappedConstraint(a.solver().MakeEquality(a.Var(), v)); + } + public static WrappedConstraint operator !=(BaseEquality a, long v) { + return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v)); + } + public static WrappedConstraint operator !=(long v, BaseEquality a) { + return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v)); + } + public static WrappedConstraint operator >=(BaseEquality a, long v) { + return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator >=(long v, BaseEquality a) { + return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator >(BaseEquality a, long v) { + return new WrappedConstraint(a.solver().MakeGreater(a.Var(), v)); + } + public static WrappedConstraint operator >(long v, BaseEquality a) { + return new WrappedConstraint(a.solver().MakeLess(a.Var(), v)); + } + public static WrappedConstraint operator <=(BaseEquality a, long v) { + return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator <=(long v, BaseEquality a) { + return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator <(BaseEquality a, long v) { + return new WrappedConstraint(a.solver().MakeLess(a.Var(), v)); + } + public static WrappedConstraint operator <(long v, BaseEquality a) { + return new WrappedConstraint(a.solver().MakeGreater(a.Var(), v)); + } + public static WrappedConstraint operator >=(BaseEquality a, BaseEquality b) { + return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), + b.Var())); + } + public static WrappedConstraint operator >(BaseEquality a, BaseEquality b) { + return new WrappedConstraint(a.solver().MakeGreater(a.Var(), b.Var())); + } + public static WrappedConstraint operator <=(BaseEquality a, BaseEquality b) { + return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), b.Var())); + } + public static WrappedConstraint operator <(BaseEquality a, BaseEquality b) { + return new WrappedConstraint(a.solver().MakeLess(a.Var(), b.Var())); + } + public static ConstraintEquality operator ==(BaseEquality a, BaseEquality b) { + return new ConstraintEquality(a, b, true); + } + public static ConstraintEquality operator !=(BaseEquality a, BaseEquality b) { + return new ConstraintEquality(a, b, false); + } +} + +public class WrappedConstraint : BaseEquality +{ + public bool Val { get; set; } + + public Constraint Cst { get; set; } + + public WrappedConstraint(Constraint cst) : this(true, cst) {} + + public WrappedConstraint(bool val) : this(val, null) {} + + public WrappedConstraint(bool val, Constraint cst) + { + this.Val = val; + this.Cst = cst; + } + + public static implicit operator bool(WrappedConstraint valCstPair) + { + return valCstPair.Val; + } + + public static implicit operator Constraint(WrappedConstraint valCstPair) + { + return valCstPair.Cst; + } + + public static implicit operator IntVar(WrappedConstraint eq) + { + return eq.Var(); + } + + public static implicit operator IntExpr(WrappedConstraint eq) + { + return eq.Var(); + } + + public override Solver solver() + { + return this.Cst.solver(); + } + + public override IntVar Var() + { + return Cst.Var(); + } +} + +public class IntExprEquality : BaseEquality +{ + public IntExprEquality(IntExpr a, IntExpr b, bool equality) + { + this.left_ = a; + this.right_ = b; + this.equality_ = equality; + } + + bool IsTrue() + { + return (object)left_ == (object)right_ ? equality_ : !equality_; + } + + Constraint ToConstraint() + { + return equality_ ? + left_.solver().MakeEquality(left_.Var(), right_.Var()) : + left_.solver().MakeNonEquality(left_.Var(), right_.Var()); + } + + public static bool operator true(IntExprEquality eq) + { + return eq.IsTrue(); + } + + public static bool operator false(IntExprEquality eq) + { + return !eq.IsTrue(); + } + + public static implicit operator Constraint(IntExprEquality eq) + { + return eq.ToConstraint(); + } + + public override IntVar Var() + { + return equality_ ? + left_.solver().MakeIsEqualVar(left_, right_) : + left_.solver().MakeIsDifferentVar(left_, right_); + } + + public static implicit operator IntVar(IntExprEquality eq) + { + return eq.Var(); + } + + public static implicit operator IntExpr(IntExprEquality eq) + { + return eq.Var(); + } + + public override Solver solver() + { + return left_.solver(); + } + + private IntExpr left_; + private IntExpr right_; + private bool equality_; +} + +public class ConstraintEquality : BaseEquality +{ + public ConstraintEquality(IConstraintWithStatus a, + IConstraintWithStatus b, + bool equality) + { + this.left_ = a; + this.right_ = b; + this.equality_ = equality; + } + + bool IsTrue() + { + return (object)left_ == (object)right_ ? equality_ : !equality_; + } + + Constraint ToConstraint() + { + return equality_ ? + left_.solver().MakeEquality(left_.Var(), right_.Var()) : + left_.solver().MakeNonEquality(left_.Var(), right_.Var()); + } + + public static bool operator true(ConstraintEquality eq) + { + return eq.IsTrue(); + } + + public static bool operator false(ConstraintEquality eq) + { + return !eq.IsTrue(); + } + + public static implicit operator Constraint(ConstraintEquality eq) + { + return eq.ToConstraint(); + } + + public override IntVar Var() + { + return equality_ ? + left_.solver().MakeIsEqualVar(left_.Var(), right_.Var()) : + left_.solver().MakeIsDifferentVar(left_.Var(), right_.Var()); + } + + public static implicit operator IntVar(ConstraintEquality eq) + { + return eq.Var(); + } + + public static implicit operator IntExpr(ConstraintEquality eq) + { + return eq.Var(); + } + + public override Solver solver() + { + return left_.solver(); + } + + private IConstraintWithStatus left_; + private IConstraintWithStatus right_; + private bool equality_; +} +} // namespace Google.OrTools.ConstraintSolver diff --git a/ortools/dotnet/OrTools/linearsolver/DoubleArrayHelper.cs b/ortools/dotnet/OrTools/linearsolver/DoubleArrayHelper.cs new file mode 100644 index 00000000000..829ce269c06 --- /dev/null +++ b/ortools/dotnet/OrTools/linearsolver/DoubleArrayHelper.cs @@ -0,0 +1,40 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.LinearSolver { +using System; +using System.Collections.Generic; + +// double[] helper class. +public partial class MpDoubleVector: IDisposable, System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , System.Collections.Generic.IList<double> +#endif +{ + // cast from C# double array + public static implicit operator MpDoubleVector(double[] inVal) { + var outVal= new MpDoubleVector(); + foreach (double element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# double array + public static implicit operator double[](MpDoubleVector inVal) { + var outVal= new double[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; + } +} +} // namespace Google.OrTools.LinearSolver diff --git a/ortools/dotnet/OrTools/linearsolver/LinearConstraint.cs b/ortools/dotnet/OrTools/linearsolver/LinearConstraint.cs new file mode 100644 index 00000000000..3442ad5a335 --- /dev/null +++ b/ortools/dotnet/OrTools/linearsolver/LinearConstraint.cs @@ -0,0 +1,140 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.LinearSolver +{ + using System; + using System.Collections.Generic; + +public class LinearConstraint +{ + + public virtual String ToString() + { + return "LinearConstraint"; + } + + public virtual Constraint Extract(Solver solver) + { + return null; + } +} + +public class RangeConstraint : LinearConstraint +{ + + public RangeConstraint(LinearExpr expr, double lb, double ub) + { + this.expr_ = expr; + this.lb_ = lb; + this.ub_ = ub; + } + + public override String ToString() + { + return "" + lb_ + " <= " + expr_.ToString() + " <= " + ub_; + } + + public override Constraint Extract(Solver solver) + { + Dictionary<Variable, double> coefficients = + new Dictionary<Variable, double>(); + double constant = expr_.Visit(coefficients); + Constraint ct = solver.MakeConstraint(lb_ - constant, ub_ - constant); + foreach (KeyValuePair<Variable, double> pair in coefficients) + { + ct.SetCoefficient(pair.Key, pair.Value); + } + return ct; + } + + public static implicit operator bool(RangeConstraint ct) + { + return false; + } + + private LinearExpr expr_; + private double lb_; + private double ub_; +} + +public class Equality : LinearConstraint +{ + public Equality(LinearExpr left, LinearExpr right, bool equality) + { + this.left_ = left; + this.right_ = right; + this.equality_ = equality; + } + + public override String ToString() + { + return "" + left_.ToString() + " == " + right_.ToString(); + } + + public override Constraint Extract(Solver solver) + { + Dictionary<Variable, double> coefficients = + new Dictionary<Variable, double>(); + double constant = left_.Visit(coefficients); + constant += right_.DoVisit(coefficients, -1); + Constraint ct = solver.MakeConstraint(-constant, -constant); + foreach (KeyValuePair<Variable, double> pair in coefficients) + { + ct.SetCoefficient(pair.Key, pair.Value); + } + return ct; + } + + public static implicit operator bool(Equality ct) + { + return (object)ct.left_ == (object)ct.right_ ? ct.equality_ : !ct.equality_; + } + + private LinearExpr left_; + private LinearExpr right_; + private bool equality_; +} + +public class VarEquality : LinearConstraint +{ + public VarEquality(Variable left, Variable right, bool equality) + { + this.left_ = left; + this.right_ = right; + this.equality_ = equality; + } + + public override String ToString() + { + return "" + left_.Name() + " == " + right_.Name(); + } + + public override Constraint Extract(Solver solver) + { + Constraint ct = solver.MakeConstraint(0.0, 0.0); + ct.SetCoefficient(left_, 1.0); + ct.SetCoefficient(right_, -1.0); + return ct; + } + + public static implicit operator bool(VarEquality ct) + { + return (object)ct.left_ == (object)ct.right_ ? ct.equality_ : !ct.equality_; + } + + private Variable left_; + private Variable right_; + private bool equality_; +} +} // namespace Google.OrTools.LinearSolver diff --git a/ortools/dotnet/OrTools/linearsolver/LinearExpr.cs b/ortools/dotnet/OrTools/linearsolver/LinearExpr.cs new file mode 100644 index 00000000000..7abded015ac --- /dev/null +++ b/ortools/dotnet/OrTools/linearsolver/LinearExpr.cs @@ -0,0 +1,344 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.LinearSolver +{ + using System; + using System.Collections.Generic; + +public class LinearExpr +{ + public virtual double DoVisit(Dictionary<Variable, double> coefficients, + double multiplier) + { + return 0; + } + + public double Visit(Dictionary<Variable, double> coefficients) + { + return DoVisit(coefficients, 1.0); + } + + public static LinearExpr operator+(LinearExpr a, double v) + { + return new SumCst(a, v); + } + + public static LinearExpr operator+(double v, LinearExpr a) + { + return new SumCst(a, v); + } + + public static LinearExpr operator+(LinearExpr a, LinearExpr b) + { + return new Sum(a, b); + } + + public static LinearExpr operator-(LinearExpr a, double v) + { + return new SumCst(a, -v); + } + + public static LinearExpr operator-(double v, LinearExpr a) + { + return new SumCst(new ProductCst(a, -1.0), v); + } + + public static LinearExpr operator-(LinearExpr a, LinearExpr b) + { + return new Sum(a, new ProductCst(b, -1.0)); + } + + public static LinearExpr operator-(LinearExpr a) + { + return new ProductCst(a, -1.0); + } + + public static LinearExpr operator*(LinearExpr a, double v) + { + return new ProductCst(a, v); + } + + public static LinearExpr operator/(LinearExpr a, double v) + { + return new ProductCst(a, 1 / v); + } + + public static LinearExpr operator*(double v, LinearExpr a) + { + return new ProductCst(a, v); + } + + public static RangeConstraint operator==(LinearExpr a, double v) + { + return new RangeConstraint(a, v, v); + } + + public static RangeConstraint operator==(double v, LinearExpr a) + { + return new RangeConstraint(a, v, v); + } + + public static RangeConstraint operator!=(LinearExpr a, double v) + { + return new RangeConstraint(a, 1, -1); + } + + public static RangeConstraint operator!=(double v, LinearExpr a) + { + return new RangeConstraint(a, 1, -1); + } + + public static Equality operator==(LinearExpr a, LinearExpr b) + { + return new Equality(a, b, true); + } + + public static Equality operator!=(LinearExpr a, LinearExpr b) + { + return new Equality(a, b, false); + } + + public static RangeConstraint operator<=(LinearExpr a, double v) + { + return new RangeConstraint(a, double.NegativeInfinity, v); + } + + public static RangeConstraint operator>=(LinearExpr a, double v) + { + return new RangeConstraint(a, v, double.PositiveInfinity); + } + + public static RangeConstraint operator<=(LinearExpr a, LinearExpr b) + { + return a - b <= 0; + } + + public static RangeConstraint operator>=(LinearExpr a, LinearExpr b) + { + return a - b >= 0; + } + + public static implicit operator LinearExpr(Variable a) + { + return new VarWrapper(a); + } +} + +public static class LinearExprArrayHelper +{ + public static LinearExpr Sum(this LinearExpr[] exprs) + { + return new SumArray(exprs); + } + + public static LinearExpr Sum(this Variable[] vars) + { + return new SumVarArray(vars); + } +} + + // def __ge__(self, arg): + // if isinstance(arg, (int, long, float)): + // return LinearConstraint(self, arg, 1e308) + // else: + // return LinearConstraint(Sum(self, ProductCst(arg, -1)), 0.0, 1e308) + + // def __le__(self, arg): + // if isinstance(arg, (int, long, float)): + // return LinearConstraint(self, -1e308, arg) + // else: + // return LinearConstraint(Sum(self, ProductCst(arg, -1)), -1e308, 0.0) + + +class ProductCst : LinearExpr +{ + public ProductCst(LinearExpr expr, double coeff) + { + this.coeff_ = coeff; + this.expr_ = expr; + } + + public override String ToString() + { + return "(" + expr_.ToString() + " * " + coeff_ + ")"; + } + + public override double DoVisit(Dictionary<Variable, double> coefficients, + double multiplier) + { + double current_multiplier = multiplier * coeff_; + if (current_multiplier != 0.0) + { + return expr_.DoVisit(coefficients, current_multiplier); + } + else + { + return 0.0; + } + } + + private LinearExpr expr_; + private double coeff_; +} + +class SumCst : LinearExpr +{ + public SumCst(LinearExpr expr, double coeff) + { + this.coeff_ = coeff; + this.expr_ = expr; + } + + public override String ToString() + { + return "(" + expr_.ToString() + " + " + coeff_ + ")"; + } + + public override double DoVisit(Dictionary<Variable, double> coefficients, + double multiplier) + { + if (multiplier != 0.0) + { + return coeff_ * multiplier + expr_.DoVisit(coefficients, multiplier); + } + else + { + return 0.0; + } + } + + private LinearExpr expr_; + private double coeff_; +} + +class VarWrapper : LinearExpr +{ + public VarWrapper(Variable var) + { + this.var_ = var; + } + + public override String ToString() + { + return var_.Name(); + } + + public override double DoVisit(Dictionary<Variable, double> coefficients, + double multiplier) + { + if (multiplier != 0.0) + { + if (coefficients.ContainsKey(var_)) + { + coefficients[var_] += multiplier; + } + else + { + coefficients[var_] = multiplier; + } + } + return 0.0; + } + + private Variable var_; +} + + +class Sum : LinearExpr +{ + public Sum(LinearExpr left, LinearExpr right) + { + this.left_ = left; + this.right_ = right; + } + + public override String ToString() + { + return "(" + left_.ToString() + " + " + right_.ToString() + ")"; + } + + public override double DoVisit(Dictionary<Variable, double> coefficients, + double multiplier) + { + if (multiplier != 0.0) + { + return left_.DoVisit(coefficients, multiplier) + + right_.DoVisit(coefficients, multiplier); + } + else + { + return 0.0; + } + } + + private LinearExpr left_; + private LinearExpr right_; +} + +public class SumArray : LinearExpr +{ + public SumArray(LinearExpr[] array) + { + this.array_ = array; + } + + public override double DoVisit(Dictionary<Variable, double> coefficients, + double multiplier) { + if (multiplier != 0.0) + { + double constant = 0.0; + foreach (LinearExpr expr in array_) + { + constant += expr.DoVisit(coefficients, multiplier); + } + return constant; + } + else + { + return 0.0; + } + } + + private LinearExpr[] array_; +} + +public class SumVarArray : LinearExpr +{ + public SumVarArray(Variable[] array) + { + this.array_ = array; + } + + public override double DoVisit(Dictionary<Variable, double> coefficients, + double multiplier) { + if (multiplier != 0.0) + { + foreach (Variable var in array_) + { + if (coefficients.ContainsKey(var)) + { + coefficients[var] += multiplier; + } + else + { + coefficients[var] = multiplier; + } + } + } + return 0.0; + } + + private Variable[] array_; +} +} // namespace Google.OrTools.LinearSolver diff --git a/ortools/dotnet/OrTools/linearsolver/SolverHelper.cs b/ortools/dotnet/OrTools/linearsolver/SolverHelper.cs new file mode 100644 index 00000000000..870a14b15ab --- /dev/null +++ b/ortools/dotnet/OrTools/linearsolver/SolverHelper.cs @@ -0,0 +1,250 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.LinearSolver { +using System; +using System.Collections.Generic; + +// Patch the MPSolver class to: +// - support custom versions of the array-based APIs (MakeVarArray, etc). +// - customize the construction, and the OptimizationProblemType enum. +// - support the natural language API. +public partial class Solver { + 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<Variable, double> coefficients = + new Dictionary<Variable, double>(); + double constant = expr.Visit(coefficients); + foreach (KeyValuePair<Variable, double> pair in coefficients) + { + Objective().SetCoefficient(pair.Key, pair.Value); + } + Objective().SetOffset(constant); + } + + public void Maximize(LinearExpr expr) + { + Objective().Clear(); + Objective().SetMaximization(); + Dictionary<Variable, double> coefficients = + new Dictionary<Variable, double>(); + double constant = expr.Visit(coefficients); + foreach (KeyValuePair<Variable, double> 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 Google.OrTools.LinearSolver diff --git a/ortools/dotnet/OrTools/linearsolver/VariableHelper.cs b/ortools/dotnet/OrTools/linearsolver/VariableHelper.cs new file mode 100644 index 00000000000..81b314a2c7d --- /dev/null +++ b/ortools/dotnet/OrTools/linearsolver/VariableHelper.cs @@ -0,0 +1,191 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.LinearSolver { +using System; +using System.Collections.Generic; + +// Patch the MPVariable class to support the natural language API. +public partial class Variable { + 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); + } +} + +} // namespace Google.OrTools.LinearSolver diff --git a/ortools/dotnet/OrTools/sat/Constraints.cs b/ortools/dotnet/OrTools/sat/Constraints.cs new file mode 100644 index 00000000000..51d95599ca6 --- /dev/null +++ b/ortools/dotnet/OrTools/sat/Constraints.cs @@ -0,0 +1,47 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.Sat +{ +using System; +using System.Collections.Generic; + +public class Constraint +{ + public Constraint(CpModelProto model) + { + index_ = model.Constraints.Count; + constraint_ = new ConstraintProto(); + model.Constraints.Add(constraint_); + } + + public void OnlyEnforceIf(ILiteral lit) + { + constraint_.EnforcementLiteral.Add(lit.GetIndex()); + } + + public int Index + { + get { return index_; } + } + + public ConstraintProto Proto + { + get { return constraint_; } + } + + private int index_; + private ConstraintProto constraint_; +} + +} // namespace Google.OrTools.Sat diff --git a/ortools/dotnet/OrTools/sat/CpModel.cs b/ortools/dotnet/OrTools/sat/CpModel.cs new file mode 100644 index 00000000000..8e4438d2391 --- /dev/null +++ b/ortools/dotnet/OrTools/sat/CpModel.cs @@ -0,0 +1,880 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.Sat +{ +using System; +using System.Collections.Generic; + +public class CpModel +{ + public CpModel() + { + model_ = new CpModelProto(); + constant_map_ = new Dictionary<long, int>(); + } + + // Getters. + + public CpModelProto Model + { + get { return model_; } + } + + int Negated(int index) + { + return -index - 1; + } + + // Integer variables and constraints. + + public IntVar NewIntVar(long lb, long ub, string name) + { + long[] bounds = { lb, ub }; + return new IntVar(model_, bounds, name); + } + + public IntVar NewEnumeratedIntVar(IEnumerable<long> bounds, string name) + { + return new IntVar(model_, bounds, name); + } + + public IntVar NewOptionalIntVar( + long lb, long ub, ILiteral is_present, string name) + { + long[] bounds = { lb, ub }; + return new IntVar(model_, bounds, is_present.GetIndex(), name); + } + + public IntVar NewOptionalEnumeratedIntVar( + IEnumerable<long> bounds, ILiteral is_present, string name) + { + return new IntVar(model_, bounds, is_present.GetIndex(), name); + } + + // Constants (named or not). + + // TODO: Cache constant. + public IntVar NewConstant(long value) + { + long[] bounds = { value, value }; + return new IntVar(model_, bounds, String.Format("{0}", value)); + } + + public IntVar NewConstant(long value, string name) + { + long[] bounds = { value, value }; + return new IntVar(model_, bounds, name); + } + + public IntVar NewOptionalConstant( + long value, ILiteral is_present, string name) + { + long[] bounds = { value, value }; + return new IntVar(model_, bounds, is_present.GetIndex(), name); + } + + public IntVar NewBoolVar(string name) + { + long[] bounds = { 0L, 1L }; + return new IntVar(model_, bounds, name); + } + + public Constraint AddLinearConstraint(IEnumerable<Tuple<IntVar, long>> terms, + long lb, long ub) + { + Constraint ct = new Constraint(model_); + LinearConstraintProto lin = new LinearConstraintProto(); + foreach (Tuple<IntVar, long> term in terms) + { + lin.Vars.Add(term.Item1.Index); + lin.Coeffs.Add(term.Item2); + } + lin.Domain.Add(lb); + lin.Domain.Add(ub); + ct.Proto.Linear = lin; + return ct; + } + + public Constraint AddLinearConstraint(IEnumerable<IntVar> vars, + IEnumerable<long> coeffs, + long lb, long ub) + { + Constraint ct = new Constraint(model_); + LinearConstraintProto lin = new LinearConstraintProto(); + foreach (IntVar var in vars) + { + lin.Vars.Add(var.Index); + } + foreach (long coeff in coeffs) + { + lin.Coeffs.Add(coeff); + } + lin.Domain.Add(lb); + lin.Domain.Add(ub); + ct.Proto.Linear = lin; + return ct; + } + + public Constraint AddLinearConstraint(IEnumerable<IntVar> vars, + IEnumerable<int> coeffs, + long lb, long ub) + { + Constraint ct = new Constraint(model_); + LinearConstraintProto lin = new LinearConstraintProto(); + foreach (IntVar var in vars) + { + lin.Vars.Add(var.Index); + } + foreach (int coeff in coeffs) + { + lin.Coeffs.Add(coeff); + } + lin.Domain.Add(lb); + lin.Domain.Add(ub); + ct.Proto.Linear = lin; + return ct; + } + + public Constraint AddLinearConstraintWithBounds( + IEnumerable<Tuple<IntVar, long>> terms, IEnumerable<long> bounds) + { + Constraint ct = new Constraint(model_); + LinearConstraintProto lin = new LinearConstraintProto(); + foreach (Tuple<IntVar, long> term in terms) + { + lin.Vars.Add(term.Item1.Index); + lin.Coeffs.Add(term.Item2); + } + foreach (long b in bounds) + { + lin.Domain.Add(b); + } + ct.Proto.Linear = lin; + return ct; + } + + public Constraint AddLinearConstraintWithBounds(IEnumerable<IntVar> vars, + IEnumerable<long> coeffs, + IEnumerable<long> bounds) + { + Constraint ct = new Constraint(model_); + LinearConstraintProto lin = new LinearConstraintProto(); + foreach (IntVar var in vars) + { + lin.Vars.Add(var.Index); + } + foreach (long coeff in coeffs) + { + lin.Coeffs.Add(coeff); + } + foreach (long b in bounds) + { + lin.Domain.Add(b); + } + ct.Proto.Linear = lin; + return ct; + } + + public Constraint AddLinearConstraintWithBounds(IEnumerable<IntVar> vars, + IEnumerable<int> coeffs, + IEnumerable<long> bounds) + { + Constraint ct = new Constraint(model_); + LinearConstraintProto lin = new LinearConstraintProto(); + foreach (IntVar var in vars) + { + lin.Vars.Add(var.Index); + } + foreach (int coeff in coeffs) + { + lin.Coeffs.Add(coeff); + } + foreach (long b in bounds) + { + lin.Domain.Add(b); + } + ct.Proto.Linear = lin; + return ct; + } + + public Constraint AddSumConstraint(IEnumerable<IntVar> vars, long lb, + long ub) + { + Constraint ct = new Constraint(model_); + LinearConstraintProto lin = new LinearConstraintProto(); + foreach (IntVar var in vars) + { + lin.Vars.Add(var.Index); + lin.Coeffs.Add(1L); + } + lin.Domain.Add(lb); + lin.Domain.Add(ub); + ct.Proto.Linear = lin; + return ct; + } + + public Constraint Add(BoundIntegerExpression lin) + { + switch (lin.CtType) + { + case BoundIntegerExpression.Type.BoundExpression: + { + Dictionary<IntVar, long> dict = new Dictionary<IntVar, long>(); + long constant = IntegerExpression.GetVarValueMap(lin.Left, 1L, dict); + Constraint ct = new Constraint(model_); + LinearConstraintProto linear = new LinearConstraintProto(); + foreach (KeyValuePair<IntVar, long> term in dict) + { + linear.Vars.Add(term.Key.Index); + linear.Coeffs.Add(term.Value); + } + linear.Domain.Add(lin.Lb == Int64.MinValue ? Int64.MinValue + : lin.Lb - constant); + linear.Domain.Add(lin.Ub == Int64.MaxValue ? Int64.MaxValue + : lin.Ub - constant); + ct.Proto.Linear = linear; + return ct; + } + case BoundIntegerExpression.Type.VarEqVar: + { + Dictionary<IntVar, long> dict = new Dictionary<IntVar, long>(); + long constant = IntegerExpression.GetVarValueMap(lin.Left, 1L, dict); + constant += IntegerExpression.GetVarValueMap(lin.Right, -1L, dict); + Constraint ct = new Constraint(model_); + LinearConstraintProto linear = new LinearConstraintProto(); + foreach (KeyValuePair<IntVar, long> term in dict) + { + linear.Vars.Add(term.Key.Index); + linear.Coeffs.Add(term.Value); + } + linear.Domain.Add(-constant); + linear.Domain.Add(-constant); + ct.Proto.Linear = linear; + return ct; + } + case BoundIntegerExpression.Type.VarDiffVar: + { + Dictionary<IntVar, long> dict = new Dictionary<IntVar, long>(); + long constant = IntegerExpression.GetVarValueMap(lin.Left, 1L, dict); + constant += IntegerExpression.GetVarValueMap(lin.Right, -1L, dict); + Constraint ct = new Constraint(model_); + LinearConstraintProto linear = new LinearConstraintProto(); + foreach (KeyValuePair<IntVar, long> term in dict) + { + linear.Vars.Add(term.Key.Index); + linear.Coeffs.Add(term.Value); + } + linear.Domain.Add(Int64.MinValue); + linear.Domain.Add(-constant - 1); + linear.Domain.Add(-constant + 1); + linear.Domain.Add(Int64.MaxValue); + ct.Proto.Linear = linear; + return ct; + } + case BoundIntegerExpression.Type.VarEqCst: + { + Dictionary<IntVar, long> dict = new Dictionary<IntVar, long>(); + long constant = IntegerExpression.GetVarValueMap(lin.Left, 1L, dict); + Constraint ct = new Constraint(model_); + LinearConstraintProto linear = new LinearConstraintProto(); + foreach (KeyValuePair<IntVar, long> term in dict) + { + linear.Vars.Add(term.Key.Index); + linear.Coeffs.Add(term.Value); + } + linear.Domain.Add(lin.Lb - constant); + linear.Domain.Add(lin.Lb - constant); + ct.Proto.Linear = linear; + return ct; + } + case BoundIntegerExpression.Type.VarDiffCst: + { + Dictionary<IntVar, long> dict = new Dictionary<IntVar, long>(); + long constant = IntegerExpression.GetVarValueMap(lin.Left, 1L, dict); + Constraint ct = new Constraint(model_); + LinearConstraintProto linear = new LinearConstraintProto(); + foreach (KeyValuePair<IntVar, long> term in dict) + { + linear.Vars.Add(term.Key.Index); + linear.Coeffs.Add(term.Value); + } + linear.Domain.Add(Int64.MinValue); + linear.Domain.Add(lin.Lb - constant - 1); + linear.Domain.Add(lin.Lb - constant + 1); + linear.Domain.Add(Int64.MaxValue); + ct.Proto.Linear = linear; + return ct; + } + } + return null; + } + + public Constraint AddAllDifferent(IEnumerable<IntVar> vars) + { + Constraint ct = new Constraint(model_); + AllDifferentConstraintProto alldiff = new AllDifferentConstraintProto(); + foreach (IntVar var in vars) + { + alldiff.Vars.Add(var.Index); + } + ct.Proto.AllDiff = alldiff; + return ct; + } + + public Constraint AddElement(IntVar index, IEnumerable<IntVar> vars, + IntVar target) + { + Constraint ct = new Constraint(model_); + ElementConstraintProto element = new ElementConstraintProto(); + element.Index = index.Index; + foreach (IntVar var in vars) + { + element.Vars.Add(var.Index); + } + element.Target = target.Index; + ct.Proto.Element = element; + return ct; + } + + public Constraint AddElement(IntVar index, IEnumerable<long> values, + IntVar target) + { + Constraint ct = new Constraint(model_); + ElementConstraintProto element = new ElementConstraintProto(); + element.Index = index.Index; + foreach (long value in values) + { + element.Vars.Add(ConvertConstant(value)); + } + element.Target = target.Index; + ct.Proto.Element = element; + return ct; + } + + public Constraint AddElement(IntVar index, IEnumerable<int> values, + IntVar target) + { + Constraint ct = new Constraint(model_); + ElementConstraintProto element = new ElementConstraintProto(); + element.Index = index.Index; + foreach (int value in values) + { + element.Vars.Add(ConvertConstant(value)); + } + element.Target = target.Index; + ct.Proto.Element = element; + return ct; + } + + public Constraint AddCircuit(IEnumerable<Tuple<int, int, ILiteral>> arcs) + { + Constraint ct = new Constraint(model_); + CircuitConstraintProto circuit = new CircuitConstraintProto(); + foreach (var arc in arcs) + { + circuit.Tails.Add(arc.Item1); + circuit.Heads.Add(arc.Item2); + circuit.Literals.Add(arc.Item3.GetIndex()); + } + ct.Proto.Circuit = circuit; + return ct; + } + + public Constraint AddAllowedAssignments(IEnumerable<IntVar> vars, + long[,] tuples) + { + Constraint ct = new Constraint(model_); + TableConstraintProto table = new TableConstraintProto(); + foreach (IntVar var in vars) + { + table.Vars.Add(var.Index); + } + for (int i = 0; i < tuples.GetLength(0); ++i) + { + for (int j = 0; j < tuples.GetLength(1);++j) + { + table.Values.Add(tuples[i, j]); + } + } + ct.Proto.Table = table; + return ct; + } + + public Constraint AddForbiddenAssignments(IEnumerable<IntVar> vars, + long[,] tuples) + { + Constraint ct = AddAllowedAssignments(vars, tuples); + ct.Proto.Table.Negated = true; + return ct; + } + + public Constraint AddAutomata(IEnumerable<IntVar> vars, + long starting_state, + long[,] transitions, + IEnumerable<long> final_states) { + Constraint ct = new Constraint(model_); + AutomataConstraintProto aut = new AutomataConstraintProto(); + foreach (IntVar var in vars) + { + aut.Vars.Add(var.Index); + } + aut.StartingState = starting_state; + foreach (long f in final_states) + { + aut.FinalStates.Add(f); + } + for (int i = 0; i < transitions.GetLength(0); ++i) + { + aut.TransitionTail.Add(transitions[i, 0]); + aut.TransitionLabel.Add(transitions[i, 1]); + aut.TransitionHead.Add(transitions[i, 2]); + } + + ct.Proto.Automata = aut; + return ct; + } + + public Constraint AddAutomata( + IEnumerable<IntVar> vars, + long starting_state, + IEnumerable<Tuple<long, long, long>> transitions, + IEnumerable<long> final_states) { + Constraint ct = new Constraint(model_); + AutomataConstraintProto aut = new AutomataConstraintProto(); + foreach (IntVar var in vars) + { + aut.Vars.Add(var.Index); + } + aut.StartingState = starting_state; + foreach (long f in final_states) + { + aut.FinalStates.Add(f); + } + foreach (Tuple<long, long, long> transition in transitions) + { + + aut.TransitionHead.Add(transition.Item1); + aut.TransitionLabel.Add(transition.Item2); + aut.TransitionTail.Add(transition.Item3); + } + + ct.Proto.Automata = aut; + return ct; + } + + public Constraint AddInverse(IEnumerable<IntVar> direct, + IEnumerable<IntVar> reverse) + { + Constraint ct = new Constraint(model_); + InverseConstraintProto inverse = new InverseConstraintProto(); + foreach (IntVar var in direct) + { + inverse.FDirect.Add(var.Index); + } + foreach (IntVar var in reverse) + { + inverse.FInverse.Add(var.Index); + } + ct.Proto.Inverse = inverse; + return ct; + } + + public Constraint AddReservoirConstraint(IEnumerable<IntVar> times, + IEnumerable<long> demands, + long min_level, long max_level) + { + Constraint ct = new Constraint(model_); + ReservoirConstraintProto res = new ReservoirConstraintProto(); + foreach (IntVar var in times) + { + res.Times.Add(var.Index); + } + foreach (long d in demands) + { + res.Demands.Add(d); + } + + ct.Proto.Reservoir = res; + return ct; + } + + public Constraint AddReservoirConstraint(IEnumerable<IntVar> times, + IEnumerable<int> demands, + long min_level, long max_level) + { + Constraint ct = new Constraint(model_); + ReservoirConstraintProto res = new ReservoirConstraintProto(); + foreach (IntVar var in times) + { + res.Times.Add(var.Index); + } + foreach (int d in demands) + { + res.Demands.Add(d); + } + + ct.Proto.Reservoir = res; + return ct; + } + + public void AddMapDomain( + IntVar var, IEnumerable<IntVar> bool_vars, long offset = 0) + { + int i = 0; + foreach (IntVar bool_var in bool_vars) + { + int b_index = bool_var.Index; + int var_index = var.Index; + + ConstraintProto ct1 = new ConstraintProto(); + LinearConstraintProto lin1 = new LinearConstraintProto(); + lin1.Vars.Add(var_index); + lin1.Coeffs.Add(1L); + lin1.Domain.Add(offset + i); + lin1.Domain.Add(offset + i); + ct1.Linear = lin1; + ct1.EnforcementLiteral.Add(b_index); + model_.Constraints.Add(ct1); + + ConstraintProto ct2 = new ConstraintProto(); + LinearConstraintProto lin2 = new LinearConstraintProto(); + lin2.Vars.Add(var_index); + lin2.Coeffs.Add(1L); + lin2.Domain.Add(Int64.MinValue); + lin2.Domain.Add(offset + i - 1); + lin2.Domain.Add(offset + i + 1); + lin2.Domain.Add(Int64.MaxValue); + ct2.Linear = lin2; + ct2.EnforcementLiteral.Add(-b_index - 1); + model_.Constraints.Add(ct2); + + i++; + } + } + + public Constraint AddImplication(ILiteral a, ILiteral b) + { + Constraint ct = new Constraint(model_); + BoolArgumentProto or = new BoolArgumentProto(); + or.Literals.Add(a.Not().GetIndex()); + or.Literals.Add(b.GetIndex()); + ct.Proto.BoolOr = or; + return ct; + } + + public Constraint AddBoolOr(IEnumerable<ILiteral> literals) + { + Constraint ct = new Constraint(model_); + BoolArgumentProto bool_argument = new BoolArgumentProto(); + foreach (ILiteral lit in literals) + { + bool_argument.Literals.Add(lit.GetIndex()); + } + ct.Proto.BoolOr = bool_argument; + return ct; + } + + public Constraint AddBoolAnd(IEnumerable<ILiteral> literals) + { + Constraint ct = new Constraint(model_); + BoolArgumentProto bool_argument = new BoolArgumentProto(); + foreach (ILiteral lit in literals) + { + bool_argument.Literals.Add(lit.GetIndex()); + } + ct.Proto.BoolAnd = bool_argument; + return ct; + } + + public Constraint AddBoolXor(IEnumerable<ILiteral> literals) + { + Constraint ct = new Constraint(model_); + BoolArgumentProto bool_argument = new BoolArgumentProto(); + foreach (ILiteral lit in literals) + { + bool_argument.Literals.Add(lit.GetIndex()); + } + ct.Proto.BoolXor = bool_argument; + return ct; + } + + public Constraint AddMinEquality(IntVar target, IEnumerable<IntVar> vars) + { + Constraint ct = new Constraint(model_); + IntegerArgumentProto args = new IntegerArgumentProto(); + foreach (IntVar var in vars) + { + args.Vars.Add(var.Index); + } + args.Target = target.Index; + ct.Proto.IntMin = args; + return ct; + } + + public Constraint AddMaxEquality(IntVar target, IEnumerable<IntVar> vars) + { + Constraint ct = new Constraint(model_); + IntegerArgumentProto args = new IntegerArgumentProto(); + foreach (IntVar var in vars) + { + args.Vars.Add(var.Index); + } + args.Target = target.Index; + ct.Proto.IntMax = args; + return ct; + } + + public Constraint AddDivisionEquality<T, N, D>(T target, N num, D denom) + { + Constraint ct = new Constraint(model_); + IntegerArgumentProto args = new IntegerArgumentProto(); + args.Vars.Add(GetOrCreateIndex(num)); + args.Vars.Add(GetOrCreateIndex(denom)); + args.Target = GetOrCreateIndex(target); + ct.Proto.IntDiv = args; + return ct; + } + + public Constraint AddModuloEquality<T, V, M>(T target, V v, M m) + { + Constraint ct = new Constraint(model_); + IntegerArgumentProto args = new IntegerArgumentProto(); + args.Vars.Add(GetOrCreateIndex(v)); + args.Vars.Add(GetOrCreateIndex(m)); + args.Target = GetOrCreateIndex(target); + ct.Proto.IntMod = args; + return ct; + } + + public Constraint AddProdEquality(IntVar target, IEnumerable<IntVar> vars) + { + Constraint ct = new Constraint(model_); + IntegerArgumentProto args = new IntegerArgumentProto(); + args.Target = target.Index; + foreach (IntVar var in vars) + { + args.Vars.Add(var.Index); + } + ct.Proto.IntProd = args; + return ct; + } + + // Scheduling support + + public IntervalVar NewIntervalVar<S, D, E>( + S start, D duration, E end, string name) { + return new IntervalVar(model_, + GetOrCreateIndex(start), + GetOrCreateIndex(duration), + GetOrCreateIndex(end), + name); + } + + + public IntervalVar NewOptionalIntervalVar<S, D, E>( + S start, D duration, E end, ILiteral is_present, string name) { + int i = is_present.GetIndex(); + return new IntervalVar(model_, + GetOrCreateOptionalIndex(start, i), + // Size is currently not optional. + GetOrCreateIndex(duration), + GetOrCreateOptionalIndex(end, i), + i, + name); + } + + public Constraint AddNoOverlap(IEnumerable<IntervalVar> intervals) + { + Constraint ct = new Constraint(model_); + NoOverlapConstraintProto args = new NoOverlapConstraintProto(); + foreach (IntervalVar var in intervals) + { + args.Intervals.Add(var.GetIndex()); + } + ct.Proto.NoOverlap = args; + return ct; + } + + public Constraint AddNoOverlap2D(IEnumerable<IntervalVar> x_intervals, + IEnumerable<IntervalVar> y_intervals) + { + Constraint ct = new Constraint(model_); + NoOverlap2DConstraintProto args = new NoOverlap2DConstraintProto(); + foreach (IntervalVar var in x_intervals) + { + args.XIntervals.Add(var.GetIndex()); + } + foreach (IntervalVar var in y_intervals) + { + args.YIntervals.Add(var.GetIndex()); + } + ct.Proto.NoOverlap2D = args; + return ct; + } + + public Constraint AddCumulative<D, C>(IEnumerable<IntervalVar> intervals, + IEnumerable<D> demands, + C capacity) { + Constraint ct = new Constraint(model_); + CumulativeConstraintProto cumul = new CumulativeConstraintProto(); + foreach (IntervalVar var in intervals) + { + cumul.Intervals.Add(var.GetIndex()); + } + foreach (D demand in demands) + { + cumul.Demands.Add(GetOrCreateIndex(demand)); + } + cumul.Capacity = GetOrCreateIndex(capacity); + ct.Proto.Cumulative = cumul; + return ct; + } + + + // Objective. + public void Minimize(IntegerExpression obj) + { + SetObjective(obj, true); + } + + public void Maximize(IntegerExpression obj) + { + SetObjective(obj, false); + } + + bool HasObjective() + { + return model_.Objective == null; + } + + // Internal methods. + + void SetObjective(IntegerExpression obj, bool minimize) + { + CpObjectiveProto objective = new CpObjectiveProto(); + if (obj is IntVar) + { + objective.Coeffs.Add(1L); + objective.Offset = 0L; + if (minimize) + { + objective.Vars.Add(obj.Index); + objective.ScalingFactor = 1L; + } + else + { + objective.Vars.Add(Negated(obj.Index)); + objective.ScalingFactor = -1L; + } + } + else + { + Dictionary<IntVar, long> dict = new Dictionary<IntVar, long>(); + long constant = IntegerExpression.GetVarValueMap(obj, 1L, dict); + if (minimize) + { + objective.ScalingFactor = 1L; + objective.Offset = constant; + } + else + { + objective.ScalingFactor = -1L; + objective.Offset = -constant; + } + foreach (KeyValuePair<IntVar, long> it in dict) + { + objective.Coeffs.Add(it.Value); + if (minimize) + { + objective.Vars.Add(it.Key.Index); + } + else + { + objective.Vars.Add(Negated(it.Key.Index)); + } + } + } + model_.Objective = objective; + } + + private int ConvertConstant(long value) + { + if (constant_map_.ContainsKey(value)) + { + return constant_map_[value]; + } + else + { + int index = model_.Variables.Count; + IntegerVariableProto var = new IntegerVariableProto(); + var.Domain.Add(value); + var.Domain.Add(value); + constant_map_.Add(value, index); + model_.Variables.Add(var); + return index; + } + } + + private int ConvertOptionalConstant(long value, int is_present_index) + { + if (constant_map_.ContainsKey(value)) + { + return constant_map_[value]; + } + else + { + int index = model_.Variables.Count; + IntegerVariableProto var = new IntegerVariableProto(); + var.Domain.Add(value); + var.Domain.Add(value); + constant_map_.Add(value, index); + var.EnforcementLiteral.Add(is_present_index); + model_.Variables.Add(var); + return index; + } + } + + private int GetOrCreateIndex<X>(X x) + { + if (typeof(X) == typeof(IntVar)) + { + IntVar vx = (IntVar)(Object)x; + return vx.Index; + } + if (typeof(X) == typeof(long) || typeof(X) == typeof(int)) + { + return ConvertConstant(Convert.ToInt64(x)); + } + throw new ArgumentException("Cannot extract index from argument"); + } + + private int GetOrCreateOptionalIndex<X>(X x, int is_present_index) + { + if (typeof(X) == typeof(IntVar)) + { + IntVar vx = (IntVar)(Object)x; + return vx.Index; + } + if (typeof(X) == typeof(long) || typeof(X) == typeof(int)) + { + return ConvertOptionalConstant(Convert.ToInt64(x), is_present_index); + } + throw new ArgumentException("Cannot extract index from argument"); + } + + private CpModelProto model_; + private Dictionary<long, int> constant_map_; +} + +} // namespace Google.OrTools.Sat \ No newline at end of file diff --git a/ortools/dotnet/OrTools/sat/CpSolver.cs b/ortools/dotnet/OrTools/sat/CpSolver.cs new file mode 100644 index 00000000000..62a94d93d4b --- /dev/null +++ b/ortools/dotnet/OrTools/sat/CpSolver.cs @@ -0,0 +1,257 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.Sat +{ +using System; +using System.Collections.Generic; + +public class CpSolverSolutionCallback : SolutionCallback +{ + public long Value(IntegerExpression e) + { + List<IntegerExpression> exprs = new List<IntegerExpression>(); + List<long> coeffs = new List<long>(); + exprs.Add(e); + coeffs.Add(1L); + long constant = 0; + + while (exprs.Count > 0) + { + IntegerExpression expr = exprs[0]; + exprs.RemoveAt(0); + long coeff = coeffs[0]; + coeffs.RemoveAt(0); + if (coeff == 0) continue; + + if (expr is ProductCst) + { + ProductCst p = (ProductCst)expr; + if (p.Coeff != 0) + { + exprs.Add(p.Expr); + coeffs.Add(p.Coeff * coeff); + } + } + else if (expr is SumArray) + { + SumArray a = (SumArray)expr; + constant += coeff * a.Constant; + foreach (IntegerExpression sub in a.Expressions) + { + exprs.Add(sub); + coeffs.Add(coeff); + } + } + else if (expr is IntVar) + { + int index = expr.Index; + long value = SolutionIntegerValue(index); + constant += coeff * value; + } + else if (expr is NotBooleanVariable) + { + throw new ArgumentException( + "Cannot evaluate a literal in an integer expression."); + } + else + { + throw new ArgumentException("Cannot evaluate '" + expr.ToString() + + "' in an integer expression"); + } + } + return constant; + } + + public Boolean BooleanValue(ILiteral literal) + { + if (literal is IntVar || literal is NotBooleanVariable) + { + int index = literal.GetIndex(); + return SolutionBooleanValue(index); + } + else + { + throw new ArgumentException("Cannot evaluate '" + literal.ToString() + + "' as a boolean literal"); + } + } +} + +public class CpSolver +{ + + public CpSolverStatus Solve(CpModel model) + { + if (string_parameters_ != null) + { + response_ = SatHelper.SolveWithStringParameters(model.Model, + string_parameters_); + } + else + { + response_ = SatHelper.Solve(model.Model); + } + return response_.Status; + } + + public CpSolverStatus SolveWithSolutionCallback(CpModel model, + SolutionCallback cb) + { + if (string_parameters_ != null) + { + response_ = SatHelper.SolveWithStringParametersAndSolutionCallback( + model.Model, string_parameters_, cb); + } + else + { + response_ = SatHelper.Solve(model.Model); + } + return response_.Status; + } + + public CpSolverStatus SearchAllSolutions(CpModel model, SolutionCallback cb) + { + if (string_parameters_ != null) + { + string extra_parameters = + " enumerate_all_solutions:true, cp_model_presolve:false"; + response_ = + SatHelper.SolveWithStringParametersAndSolutionCallback( + model.Model, string_parameters_ + extra_parameters, cb); + } + else + { + string parameters = + "enumerate_all_solutions:true, cp_model_presolve:false"; + response_ = SatHelper.SolveWithStringParametersAndSolutionCallback( + model.Model, parameters, cb); + } + return response_.Status; + } + + public double ObjectiveValue + { + get { return response_.ObjectiveValue; } + } + + public string StringParameters + { + get { return string_parameters_; } + set { string_parameters_ = value; } + } + + public CpSolverResponse Response + { + get { return response_; } + } + + public long Value(IntegerExpression e) + { + List<IntegerExpression> exprs = new List<IntegerExpression>(); + List<long> coeffs = new List<long>(); + exprs.Add(e); + coeffs.Add(1L); + long constant = 0; + + while (exprs.Count > 0) + { + IntegerExpression expr = exprs[0]; + exprs.RemoveAt(0); + long coeff = coeffs[0]; + coeffs.RemoveAt(0); + if (coeff == 0) continue; + + if (expr is ProductCst) + { + ProductCst p = (ProductCst)expr; + if (p.Coeff != 0) + { + exprs.Add(p.Expr); + coeffs.Add(p.Coeff * coeff); + } + } + else if (expr is SumArray) + { + SumArray a = (SumArray)expr; + constant += coeff * a.Constant; + foreach (IntegerExpression sub in a.Expressions) + { + exprs.Add(sub); + coeffs.Add(coeff); + } + } + else if (expr is IntVar) + { + int index = expr.Index; + long value = index >= 0 ? response_.Solution[index] + : -response_.Solution[-index - 1]; + constant += coeff * value; + } + else if (expr is NotBooleanVariable) + { + throw new ArgumentException( + "Cannot evaluate a literal in an integer expression."); + } + else + { + throw new ArgumentException("Cannot evaluate '" + expr.ToString() + + "' in an integer expression"); + } + } + return constant; + } + + public Boolean BooleanValue(ILiteral literal) + { + if (literal is IntVar || literal is NotBooleanVariable) + { + int index = literal.GetIndex(); + if (index >= 0) + { + return response_.Solution[index] != 0; + } + else + { + return response_.Solution[index] == 0; + } + } + else + { + throw new ArgumentException("Cannot evaluate '" + literal.ToString() + + "' as a boolean literal"); + } + } + + public long NumBranches() + { + return response_.NumBranches; + } + + public long NumConflicts() + { + return response_.NumConflicts; + } + + public double WallTime() + { + return response_.WallTime; + } + + + private CpModelProto model_; + private CpSolverResponse response_; + string string_parameters_; +} + +} // namespace Google.OrTools.Sat diff --git a/ortools/dotnet/OrTools/sat/IntegerExpressions.cs b/ortools/dotnet/OrTools/sat/IntegerExpressions.cs new file mode 100644 index 00000000000..287ca5e55ed --- /dev/null +++ b/ortools/dotnet/OrTools/sat/IntegerExpressions.cs @@ -0,0 +1,635 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.Sat +{ +using System; +using System.Collections.Generic; + +// Helpers. + +// IntVar[] helper class. +public static class IntVarArrayHelper +{ + public static SumArray Sum(this IntVar[] vars) + { + return new SumArray(vars); + } +} + +public interface ILiteral +{ + ILiteral Not(); + int GetIndex(); +} + +// Holds an integer expression. +public class IntegerExpression +{ + + public int Index + { + get { return GetIndex(); } + } + + public virtual int GetIndex() + { + throw new NotImplementedException(); + } + + public virtual string ShortString() + { + return ToString(); + } + + public static IntegerExpression operator+(IntegerExpression a, + IntegerExpression b) { + return new SumArray(a, b); + } + + public static IntegerExpression operator+(IntegerExpression a, long v) { + return new SumArray(a, v); + } + + public static IntegerExpression operator+(long v, IntegerExpression a) { + return new SumArray(a, v); + } + + public static IntegerExpression operator-(IntegerExpression a, + IntegerExpression b) { + return new SumArray(a, Prod(b, -1)); + } + + public static IntegerExpression operator-(IntegerExpression a, long v) { + return new SumArray(a, -v); + } + + public static IntegerExpression operator-(long v, IntegerExpression a) { + return new SumArray(Prod(a, -1), v); + } + + public static IntegerExpression operator*(IntegerExpression a, long v) { + return Prod(a, v); + } + + public static IntegerExpression operator*(long v, IntegerExpression a) { + return Prod(a, v); + } + + public static IntegerExpression operator-(IntegerExpression a) { + return Prod(a, -1); + } + + public static BoundIntegerExpression operator ==(IntegerExpression a, + IntegerExpression b) { + return new BoundIntegerExpression(a, b, true); + } + + public static BoundIntegerExpression operator !=(IntegerExpression a, + IntegerExpression b) { + return new BoundIntegerExpression(a, b, false); + } + + public static BoundIntegerExpression operator ==(IntegerExpression a, + long v) { + return new BoundIntegerExpression(a, v, true); + } + + public static BoundIntegerExpression operator !=(IntegerExpression a, + long v) { + return new BoundIntegerExpression(a, v, false); + } + + public static BoundIntegerExpression operator >=(IntegerExpression a, + long v) { + return new BoundIntegerExpression(v, a, Int64.MaxValue); + } + + public static BoundIntegerExpression operator >=(long v, + IntegerExpression a) { + return a <= v; + } + + public static BoundIntegerExpression operator >(IntegerExpression a, + long v) { + return new BoundIntegerExpression(v + 1, a, Int64.MaxValue); + } + + public static BoundIntegerExpression operator >(long v, IntegerExpression a) { + return a < v; + } + + public static BoundIntegerExpression operator <=(IntegerExpression a, + long v) { + return new BoundIntegerExpression(Int64.MinValue, a, v); + } + + public static BoundIntegerExpression operator <=(long v, + IntegerExpression a) { + return a >= v; + } + + public static BoundIntegerExpression operator <(IntegerExpression a, + long v) { + return new BoundIntegerExpression(Int64.MinValue, a, v - 1); + } + + public static BoundIntegerExpression operator <(long v, IntegerExpression a) { + return a > v; + } + + public static BoundIntegerExpression operator >=(IntegerExpression a, + IntegerExpression b) { + return new BoundIntegerExpression(0, a - b, Int64.MaxValue); + } + + public static BoundIntegerExpression operator >(IntegerExpression a, + IntegerExpression b) { + return new BoundIntegerExpression(1, a - b, Int64.MaxValue); + } + + public static BoundIntegerExpression operator <=(IntegerExpression a, + IntegerExpression b) { + return new BoundIntegerExpression(Int64.MinValue, a - b, 0); + } + + public static BoundIntegerExpression operator <(IntegerExpression a, + IntegerExpression b) { + return new BoundIntegerExpression(Int64.MinValue, a - b, -1); + } + + public static IntegerExpression Prod(IntegerExpression e, long v) + { + if (v == 1) + { + return e; + } + else if (e is ProductCst) + { + ProductCst p = (ProductCst)e; + return new ProductCst(p.Expr, p.Coeff * v); + } + else + { + return new ProductCst(e, v); + } + } + + public static long GetVarValueMap(IntegerExpression e, + long initial_coeff, + Dictionary<IntVar, long> dict) + { + List<IntegerExpression> exprs = new List<IntegerExpression>(); + List<long> coeffs = new List<long>(); + exprs.Add(e); + coeffs.Add(initial_coeff); + long constant = 0; + + while (exprs.Count > 0) + { + IntegerExpression expr = exprs[0]; + exprs.RemoveAt(0); + long coeff = coeffs[0]; + coeffs.RemoveAt(0); + if (coeff == 0) continue; + + if (expr is ProductCst) + { + ProductCst p = (ProductCst)expr; + if (p.Coeff != 0) + { + exprs.Add(p.Expr); + coeffs.Add(p.Coeff * coeff); + } + } + else if (expr is SumArray) + { + SumArray a = (SumArray)expr; + constant += coeff * a.Constant; + foreach (IntegerExpression sub in a.Expressions) + { + exprs.Add(sub); + coeffs.Add(coeff); + } + } + else if (expr is IntVar) + { + IntVar i = (IntVar)expr; + if (dict.ContainsKey(i)) + { + dict[i] += coeff; + } + else + { + dict.Add(i, coeff); + } + + } + else if (expr is NotBooleanVariable) + { + throw new ArgumentException( + "Cannot interpret a literal in an integer expression."); + } + else + { + throw new ArgumentException("Cannot interpret '" + expr.ToString() + + "' in an integer expression"); + } + } + return constant; + } +} + +public class ProductCst : IntegerExpression +{ + public ProductCst(IntegerExpression e, long v) + { + expr_ = e; + coeff_ = v; + } + + public IntegerExpression Expr + { + get { return expr_; } + } + + public long Coeff + { + get { return coeff_; } + } + + private IntegerExpression expr_; + private long coeff_; + +} + +public class SumArray : IntegerExpression +{ + public SumArray(IntegerExpression a, IntegerExpression b) + { + expressions_ = new List<IntegerExpression>(); + expressions_.Add(a); + expressions_.Add(b); + constant_ = 0L; + } + + public SumArray(IntegerExpression a, long b) + { + expressions_.Add(a); + constant_ = b; + } + + public SumArray(IEnumerable<IntegerExpression> exprs) + { + expressions_ = new List<IntegerExpression>(); + foreach (IntegerExpression e in exprs) + { + if (e != null) + { + expressions_.Add(e); + } + } + constant_ = 0L; + } + + public SumArray(IEnumerable<IntegerExpression> exprs, long cte) + { + expressions_ = new List<IntegerExpression>(); + foreach (IntegerExpression e in exprs) + { + if (e != null) + { + expressions_.Add(e); + } + } + constant_ = cte; + } + + public List<IntegerExpression> Expressions + { + get { return expressions_; } + } + + public long Constant + { + get { return constant_; } + } + + public override string ShortString() + { + return String.Format("({0})", ToString()); + } + + public override string ToString() + { + string result = ""; + for (int i = 0; i < expressions_.Count; ++i) + { + bool negated = false; + IntegerExpression expr = expressions_[i]; + if (i != 0) + { + if (expr is ProductCst && ((ProductCst)expr).Coeff < 0) + { + result += String.Format(" - "); + negated = true; + } + else + { + result += String.Format(" + "); + } + } + + if (expr is IntVar) + { + result += expr.ShortString(); + } + else if (expr is ProductCst) + { + ProductCst p = (ProductCst)expr; + long coeff = negated ? -p.Coeff : p.Coeff; + IntegerExpression sub = p.Expr; + if (coeff == 1) + { + result += sub.ShortString(); + } + else if (coeff == -1) + { + result += String.Format("-{0}", coeff, sub.ShortString()); + } + else + { + result += String.Format("{0}*{1}", coeff, sub.ShortString()); + } + } + else + { + result += String.Format("({0})", expr.ShortString()); + } + } + return result; + } + + private List<IntegerExpression> expressions_; + private long constant_; + +} + +public class IntVar : IntegerExpression, ILiteral +{ + public IntVar(CpModelProto model, IEnumerable<long> bounds, + int is_present_index, string name) { + model_ = model; + index_ = model.Variables.Count; + var_ = new IntegerVariableProto(); + var_.Name = name; + var_.Domain.Add(bounds); + var_.EnforcementLiteral.Add(is_present_index); + model.Variables.Add(var_); + negation_ = null; + } + + public IntVar(CpModelProto model, IEnumerable<long> bounds, string name) { + model_ = model; + index_ = model.Variables.Count; + var_ = new IntegerVariableProto(); + var_.Name = name; + var_.Domain.Add(bounds); + model.Variables.Add(var_); + negation_ = null; + } + + public override int GetIndex() + { + return index_; + } + + public override string ToString() + { + return var_.ToString(); + } + + public override string ShortString() + { + if (var_.Name != null) + { + return var_.Name; + } + else + { + return var_.ToString(); + } + } + + public ILiteral Not() + { + foreach (long b in var_.Domain) + { + if (b < 0 || b > 1) + { + throw new ArgumentException( + "Cannot call Not() on a non boolean variable"); + } + } + if (negation_ == null) + { + negation_ = new NotBooleanVariable(this); + } + return negation_; + } + + + private CpModelProto model_; + private int index_; + private List<long> bounds_; + private IntegerVariableProto var_; + private NotBooleanVariable negation_; +} + +public class NotBooleanVariable : IntegerExpression, ILiteral +{ + public NotBooleanVariable(IntVar boolvar) + { + boolvar_ = boolvar; + } + + public override int GetIndex() + { + return -boolvar_.Index - 1; + } + + public ILiteral Not() + { + return boolvar_; + } + + public string ShortString() + { + return String.Format("Not({0})", boolvar_.ShortString()); + } + + private IntVar boolvar_; +} + +public class BoundIntegerExpression +{ + public enum Type + { + BoundExpression, + VarEqVar, + VarDiffVar, + VarEqCst, + VarDiffCst, + } + + public BoundIntegerExpression(long lb, IntegerExpression expr, long ub) + { + left_ = expr; + right_ = null; + lb_ = lb; + ub_ = ub; + type_ = Type.BoundExpression; + } + + public BoundIntegerExpression(IntegerExpression left, IntegerExpression right, + bool equality) { + left_ = left; + right_ = right; + lb_ = 0; + ub_ = 0; + type_ = equality ? Type.VarEqVar : Type.VarDiffVar; + } + + public BoundIntegerExpression(IntegerExpression left, long v, bool equality) { + left_ = left; + right_ = null; + lb_ = v; + ub_ = 0; + type_ = equality ? Type.VarEqCst : Type.VarDiffCst; + } + + bool IsTrue() + { + if (type_ == Type.VarEqVar) + { + return (object)left_ == (object)right_; + } + else if (type_ == Type.VarDiffVar) + { + return (object)left_ != (object)right_; + } + return false; + } + + public static bool operator true(BoundIntegerExpression bie) + { + return bie.IsTrue(); + } + + public static bool operator false(BoundIntegerExpression bie) + { + return !bie.IsTrue(); + } + + public override string ToString() + { + switch (type_) + { + case Type.BoundExpression: + return String.Format("{0} <= {1} <= {2}", lb_, left_, ub_); + case Type.VarEqVar: + return String.Format("{0} == {1}", left_, right_); + case Type.VarDiffVar: + return String.Format("{0} != {1}", left_, right_); + case Type.VarEqCst: + return String.Format("{0} == {1}", left_, lb_); + case Type.VarDiffCst: + return String.Format("{0} != {1}", left_, lb_); + default: + throw new ArgumentException("Wrong mode in BoundIntegerExpression."); + } + } + + public static BoundIntegerExpression operator <=(BoundIntegerExpression a, + long v) { + if (a.CtType != Type.BoundExpression || a.Ub != Int64.MaxValue) + { + throw new ArgumentException( + "Operator <= not supported for this BoundIntegerExpression"); + } + return new BoundIntegerExpression(a.Lb, a.Left, v); + } + + public static BoundIntegerExpression operator <(BoundIntegerExpression a, + long v) { + if (a.CtType != Type.BoundExpression || a.Ub != Int64.MaxValue) + { + throw new ArgumentException( + "Operator < not supported for this BoundIntegerExpression"); + } + return new BoundIntegerExpression(a.Lb, a.Left, v - 1); + } + + public static BoundIntegerExpression operator >=(BoundIntegerExpression a, + long v) { + if (a.CtType != Type.BoundExpression || a.Lb != Int64.MinValue) + { + throw new ArgumentException( + "Operator >= not supported for this BoundIntegerExpression"); + } + return new BoundIntegerExpression(v, a.Left, a.Ub); + } + + public static BoundIntegerExpression operator >(BoundIntegerExpression a, + long v) { + if (a.CtType != Type.BoundExpression || a.Lb != Int64.MinValue) + { + throw new ArgumentException( + "Operator < not supported for this BoundIntegerExpression"); + } + return new BoundIntegerExpression(v + 1, a.Left, a.Ub); + } + + public IntegerExpression Left + { + get { return left_; } + } + + public IntegerExpression Right + { + get { return right_; } + } + + public long Lb + { + get { return lb_; } + } + + public long Ub + { + get { return ub_; } + } + + public Type CtType + { + get { return type_; } + } + + private IntegerExpression left_; + private IntegerExpression right_; + private long lb_; + private long ub_; + private Type type_; +} + +} // namespace Google.OrTools.Sat diff --git a/ortools/dotnet/OrTools/sat/IntervalVariables.cs b/ortools/dotnet/OrTools/sat/IntervalVariables.cs new file mode 100644 index 00000000000..a1c324ec6a6 --- /dev/null +++ b/ortools/dotnet/OrTools/sat/IntervalVariables.cs @@ -0,0 +1,69 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools.Sat +{ +using System; +using System.Collections.Generic; + +public class IntervalVar +{ + public IntervalVar(CpModelProto model, + int start_index, int size_index, int end_index, + int is_present_index, string name) { + model_ = model; + index_ = model.Constraints.Count; + interval_ = new IntervalConstraintProto(); + interval_.Start = start_index; + interval_.Size = size_index; + interval_.End = end_index; + + ConstraintProto ct = new ConstraintProto(); + ct.Interval = interval_; + ct.Name = name; + ct.EnforcementLiteral.Add(is_present_index); + model.Constraints.Add(ct); + } + + public IntervalVar(CpModelProto model, + int start_index, int size_index, int end_index, + string name) { + model_ = model; + index_ = model.Constraints.Count; + interval_ = new IntervalConstraintProto(); + interval_.Start = start_index; + interval_.Size = size_index; + interval_.End = end_index; + + ConstraintProto ct = new ConstraintProto(); + ct.Interval = interval_; + ct.Name = name; + model_.Constraints.Add(ct); + } + + public int GetIndex() + { + return index_; + } + + public override string ToString() + { + return model_.Constraints[index_].ToString(); + } + + private CpModelProto model_; + private int index_; + private IntervalConstraintProto interval_; +} + +} // namespace Google.OrTools.Sat diff --git a/ortools/dotnet/OrTools/util/NestedArrayHelper.cs b/ortools/dotnet/OrTools/util/NestedArrayHelper.cs new file mode 100644 index 00000000000..e543047862e --- /dev/null +++ b/ortools/dotnet/OrTools/util/NestedArrayHelper.cs @@ -0,0 +1,49 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools { + +using System; +using System.Collections.Generic; + +public static class NestedArrayHelper +{ + public static T[] GetFlatArray<T>(T[][] arr) + { + int flatLength = 0; + for (var i = 0; i < arr.GetLength(0); i++) + flatLength += arr[i].GetLength(0); + + int idx = 0; + T[] flat = new T[flatLength]; + + for (int i = 0; i < arr.GetLength(0); i++) + { + for (int j = 0; j < arr[i].GetLength(0); j++) + flat[idx++] = arr[i][j]; + } + + return flat; + } + public static int[] GetArraySecondSize<T>(T[][]arr) + { + var result = new int[arr.GetLength(0)]; + for (var i=0; i<arr.GetLength(0); i++) + { + if (arr[i] != null) + result[i] = arr[i].Length; + } + return result; + } +} +} // namespace Google.OrTools diff --git a/ortools/dotnet/OrTools/util/ProtoHelper.cs b/ortools/dotnet/OrTools/util/ProtoHelper.cs new file mode 100644 index 00000000000..e82c32b1948 --- /dev/null +++ b/ortools/dotnet/OrTools/util/ProtoHelper.cs @@ -0,0 +1,30 @@ +// Copyright 2010-2017 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. + +namespace Google.OrTools { + +using System; +using Google.Protobuf; + +public static class ProtoHelper +{ + public static byte[] ProtoToByteArray(IMessage message) + { + int size = message.CalculateSize(); + byte[] buffer = new byte[size]; + CodedOutputStream output = new CodedOutputStream(buffer); + message.WriteTo(output); + return buffer; + } +} +} // namespace Google.OrTools diff --git a/ortools/dotnet/README.md b/ortools/dotnet/README.md new file mode 100644 index 00000000000..e06bedc45aa --- /dev/null +++ b/ortools/dotnet/README.md @@ -0,0 +1,5 @@ +# Google OrTools + +## Pre-requisites +- dotnet core 2.0 +- mono 5.4