diff --git a/examples/cpp/rcpsp_sat.cc b/examples/cpp/rcpsp_sat.cc index fbfe97f1e6..a4260117e4 100644 --- a/examples/cpp/rcpsp_sat.cc +++ b/examples/cpp/rcpsp_sat.cc @@ -52,7 +52,7 @@ int64 VectorSum(const std::vector& v) { } void LoadAndSolve(const std::string& file_name) { - RcpspParser parser; + util::rcpsp::RcpspParser parser; CHECK(parser.LoadFile(file_name)); LOG(INFO) << "Successfully read '" << file_name << "'."; util::rcpsp::RcpspProblem problem = parser.problem(); diff --git a/examples/python/rcpsp_sat.py b/examples/python/rcpsp_sat.py new file mode 100644 index 0000000000..03b8e9100e --- /dev/null +++ b/examples/python/rcpsp_sat.py @@ -0,0 +1,26 @@ +from __future__ import print_function + +from ortools.sat.python import cp_model +from ortools.util import rcpsp_pb2 +from ortools.util import pywraputil + +import argparse +import time + +parser = argparse.ArgumentParser() + +parser.add_argument('--input', default = "", + help = 'Input file to parse and solve.') + + + +def main(args): + parser = pywraputil.RcpspParser() + parser.LoadFile(args.input) + problem = parser.Problem() + print(str(problem)) + + + +if __name__ == '__main__': + main(parser.parse_args()) diff --git a/makefiles/Makefile.python.mk b/makefiles/Makefile.python.mk index 6e1ecf3429..e1030cbfe9 100755 --- a/makefiles/Makefile.python.mk +++ b/makefiles/Makefile.python.mk @@ -1,4 +1,4 @@ -.PHONY : python install_python_modules pypi_archive pypi_archive_dir pyinit pycp pyalgorithms pygraph pylp pysat +.PHONY : python install_python_modules pypi_archive pypi_archive_dir pyinit pycp pyalgorithms pygraph pylp pysat pyutil # Python support using SWIG @@ -27,7 +27,16 @@ python: test_python: python else -python: install_python_modules pyinit pycp pyalgorithms pygraph pylp pysat +python: \ + install_python_modules \ + pyinit \ + pycp \ + pyalgorithms \ + pygraph \ + pylp \ + pysat \ + pyutil + test_python: test_python_examples BUILT_LANGUAGES +=, python endif @@ -247,9 +256,39 @@ else cp $(LIB_DIR)/_pywrapsat.$(SWIG_LIB_SUFFIX) $(GEN_DIR)/ortools/sat endif +# pywraputil + +pyutil: $(LIB_DIR)/_pywraputil.$(SWIG_LIB_SUFFIX) $(GEN_DIR)/ortools/util/pywraputil.py + +$(GEN_DIR)/ortools/util/rcpsp_pb2.py: $(SRC_DIR)/ortools/util/rcpsp.proto + $(PROTOBUF_DIR)/bin/protoc --proto_path=$(INC_DIR) --python_out=$(GEN_DIR) $(SRC_DIR)/ortools/util/rcpsp.proto + +$(GEN_DIR)/ortools/util/pywraputil.py: \ + $(SRC_DIR)/ortools/util/rcpsp_parser.h \ + $(SRC_DIR)/ortools/base/base.i \ + $(SRC_DIR)/ortools/util/python/util.i \ + $(GEN_DIR)/ortools/util/rcpsp_pb2.py \ + $(UTIL_DEPS) + $(SWIG_BINARY) $(SWIG_INC) -I$(INC_DIR) -c++ -python $(SWIG_PYTHON3_FLAG) -o $(GEN_DIR)$Sortools$Sutil$Sutil_python_wrap.cc -module pywraputil $(SRC_DIR)/ortools/util$Spython$Sutil.i + +$(GEN_DIR)/ortools/util/util_python_wrap.cc: $(GEN_DIR)/ortools/util/pywraputil.py + +$(OBJ_DIR)/swig/util_python_wrap.$O: $(GEN_DIR)/ortools/util/util_python_wrap.cc $(UTIL_DEPS) + $(CCC) $(CFLAGS) $(PYTHON_INC) -c $(GEN_DIR)$Sortools$Sutil$Sutil_python_wrap.cc $(OBJ_OUT)$(OBJ_DIR)$Sswig$Sutil_python_wrap.$O + +$(LIB_DIR)/_pywraputil.$(SWIG_LIB_SUFFIX): \ + $(OBJ_DIR)/swig/util_python_wrap.$O \ + $(OR_TOOLS_LIBS) + $(DYNAMIC_LD) $(LDOUT)$(LIB_DIR)$S_pywraputil.$(SWIG_LIB_SUFFIX) $(OBJ_DIR)$Sswig$Sutil_python_wrap.$O $(OR_TOOLS_LNK) $(SYS_LNK) $(PYTHON_LNK) +ifeq "$(SYSTEM)" "win" + copy $(LIB_DIR)\\_pywraputil.dll $(GEN_DIR)\\ortools\\util\\_pywraputil.pyd +else + cp $(LIB_DIR)/_pywraputil.$(SWIG_LIB_SUFFIX) $(GEN_DIR)/ortools/util +endif + # Run a single example -rpy: $(LIB_DIR)/_pywraplp.$(SWIG_LIB_SUFFIX) $(LIB_DIR)/_pywrapcp.$(SWIG_LIB_SUFFIX) $(LIB_DIR)/_pywrapgraph.$(SWIG_LIB_SUFFIX) $(LIB_DIR)/_pywrapknapsack_solver.$(SWIG_LIB_SUFFIX) $(LIB_DIR)/_pywrapsat.$(SWIG_LIB_SUFFIX) $(EX) +rpy: $(LIB_DIR)/_pywraplp.$(SWIG_LIB_SUFFIX) $(LIB_DIR)/_pywrapcp.$(SWIG_LIB_SUFFIX) $(LIB_DIR)/_pywrapgraph.$(SWIG_LIB_SUFFIX) $(LIB_DIR)/_pywrapknapsack_solver.$(SWIG_LIB_SUFFIX) $(LIB_DIR)/_pywrapsat.$(SWIG_LIB_SUFFIX) $(LIB_DIR)/_pywraputil.$(SWIG_LIB_SUFFIX) $(EX) @echo Running $(EX) $(SET_PYTHONPATH) $(PYTHON_EXECUTABLE) $(EX) $(ARGS) @@ -303,6 +342,7 @@ $(PYPI_ARCHIVE_TEMP_DIR) : $(OR_TOOLS_PYTHON_GEN_SCRIPTS) $(MKDIR) $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Ssat $(MKDIR) $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Sgraph $(MKDIR) $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Salgorithms + $(MKDIR) $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Sutil $(MKDIR) $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sdummy $(COPY) ortools$Sgen$Sortools$Sconstraint_solver$S*.py $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Sconstraint_solver $(COPY) ortools$Slinear_solver$S*.py $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Slinear_solver @@ -311,6 +351,7 @@ $(PYPI_ARCHIVE_TEMP_DIR) : $(OR_TOOLS_PYTHON_GEN_SCRIPTS) $(COPY) ortools$Sgen$Sortools$Ssat$S*.py $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Ssat $(COPY) ortools$Sgen$Sortools$Sgraph$Spywrapgraph.py $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Sgraph $(COPY) ortools$Sgen$Sortools$Salgorithms$Spywrapknapsack_solver.py $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Salgorithms + $(COPY) ortools$Sgen$Sortools$Sutil$S*.py $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Sutil $(COPY) $(GEN_DIR)$Sortools$S__init__.py $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$S__init__.py ifeq ($(SYSTEM),win) echo __version__ = "$(OR_TOOLS_VERSION)" >> $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$S__init__.py @@ -323,6 +364,7 @@ endif $(TOUCH) $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Ssat$S__init__.py $(TOUCH) $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Sgraph$S__init__.py $(TOUCH) $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Salgorithms$S__init__.py + $(TOUCH) $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Sutil$S__init__.py $(COPY) tools$Sdummy_ortools_dependency.cc $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sdummy $(COPY) tools$SREADME.pypi $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$SREADME.txt $(COPY) LICENSE-2.0.txt $(PYPI_ARCHIVE_TEMP_DIR)$Sortools @@ -336,6 +378,7 @@ ifeq ($(SYSTEM),win) copy ortools\gen\ortools\sat\_pywrapsat.pyd $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Ssat copy ortools\gen\ortools\graph\_pywrapgraph.pyd $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Sgraph copy ortools\gen\ortools\algorithms\_pywrapknapsack_solver.pyd $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Salgorithms + copy ortools\gen\ortools\util\_pywraputil.pyd $(PYPI_ARCHIVE_TEMP_DIR)$Sortools$Sortools$Sutil $(SED) -i -e 's/\.dll/\.pyd/' $(PYPI_ARCHIVE_TEMP_DIR)/ortools/setup.py $(SED) -i -e '/DELETEWIN/d' $(PYPI_ARCHIVE_TEMP_DIR)/ortools/setup.py $(SED) -i -e 's/DELETEUNIX/ /g' $(PYPI_ARCHIVE_TEMP_DIR)/ortools/setup.py @@ -346,6 +389,7 @@ else cp lib/_pywrapsat.$(SWIG_LIB_SUFFIX) $(PYPI_ARCHIVE_TEMP_DIR)/ortools/ortools/sat cp lib/_pywrapgraph.$(SWIG_LIB_SUFFIX) $(PYPI_ARCHIVE_TEMP_DIR)/ortools/ortools/graph cp lib/_pywrapknapsack_solver.$(SWIG_LIB_SUFFIX) $(PYPI_ARCHIVE_TEMP_DIR)/ortools/ortools/algorithms + cp lib/_pywraputil.$(SWIG_LIB_SUFFIX) $(PYPI_ARCHIVE_TEMP_DIR)/ortools/ortools/util $(SED) -i -e 's/\.dll/\.so/' $(PYPI_ARCHIVE_TEMP_DIR)/ortools/setup.py $(SED) -i -e 's/DELETEWIN //g' $(PYPI_ARCHIVE_TEMP_DIR)/ortools/setup.py $(SED) -i -e '/DELETEUNIX/d' $(PYPI_ARCHIVE_TEMP_DIR)/ortools/setup.py diff --git a/ortools/util/__init__.py b/ortools/util/__init__.py new file mode 100644 index 0000000000..25c0603a15 --- /dev/null +++ b/ortools/util/__init__.py @@ -0,0 +1,15 @@ +# 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. +import os as _os +__path__.append(_os.path.join(__path__[0], '..', 'gen', 'ortools', 'util')) +__path__.append(_os.path.join(__path__[0], '..', '..', 'lib')) diff --git a/ortools/util/python/util.i b/ortools/util/python/util.i new file mode 100644 index 0000000000..e059b1d469 --- /dev/null +++ b/ortools/util/python/util.i @@ -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. + +// This .i file exposes the data readers. + +%include "ortools/base/base.i" +%include "ortools/util/python/proto.i" + +%{ +#include "ortools/util/rcpsp_parser.h" +#include "ortools/util/rcpsp.pb.h" +%} + +PY_PROTO_TYPEMAP(ortools.util.rcpsp_pb2, + RcpspProblem, + ::operations_research::util::rcpsp::RcpspProblem); + +%ignoreall + +%unignore operations_research; +%unignore operations_research::util; +%unignore operations_research::util::rcpsp; +%unignore operations_research::util::rcpsp::RcpspParser; +%unignore operations_research::util::rcpsp::RcpspParser::RcpspParser; +%rename (Problem) operations_research::util::rcpsp::RcpspParser::problem; +%unignore operations_research::util::rcpsp::RcpspParser::LoadFile; + +%include "ortools/util/rcpsp_parser.h" + +%unignoreall diff --git a/ortools/util/rcpsp_parser.cc b/ortools/util/rcpsp_parser.cc index 287834ef18..74cc8d6a9e 100644 --- a/ortools/util/rcpsp_parser.cc +++ b/ortools/util/rcpsp_parser.cc @@ -20,6 +20,8 @@ #include "ortools/util/filelineiter.h" namespace operations_research { +namespace util { +namespace rcpsp { using ::strings::delimiter::AnyOf; @@ -109,7 +111,6 @@ void RcpspParser::ProcessRcpspLine(const std::string& line) { for (int i = 0; i < atoi32(words[2]); ++i) { util::rcpsp::Resource* const res = rcpsp_.add_resources(); res->set_max_capacity(-1); - res->set_min_capacity(-1); res->set_renewable(true); res->set_unit_cost(0); } @@ -289,7 +290,6 @@ void RcpspParser::ProcessRcpspMaxLine(const std::string& line) { for (int i = 0; i < num_renewable_resources; ++i) { util::rcpsp::Resource* const res = rcpsp_.add_resources(); res->set_max_capacity(-1); - res->set_min_capacity(-1); res->set_renewable(true); res->set_unit_cost(0); } @@ -588,4 +588,6 @@ void RcpspParser::ProcessPattersonLine(const std::string& line) { } } +} // namespace rcpsp +} // namespace util } // namespace operations_research diff --git a/ortools/util/rcpsp_parser.h b/ortools/util/rcpsp_parser.h index 4f7088672a..6f49bf8692 100644 --- a/ortools/util/rcpsp_parser.h +++ b/ortools/util/rcpsp_parser.h @@ -24,6 +24,8 @@ #include "ortools/util/rcpsp.pb.h" namespace operations_research { +namespace util { +namespace rcpsp { // RCPSP parser. // @@ -78,7 +80,9 @@ class RcpspParser { public: RcpspParser(); - util::rcpsp::RcpspProblem problem() const { return rcpsp_; } + ::operations_research::util::rcpsp::RcpspProblem problem() const { + return rcpsp_; + } bool LoadFile(const std::string& file_name); @@ -109,9 +113,11 @@ class RcpspParser { std::vector> temp_delays_; std::vector recipe_sizes_; int unreads_; - util::rcpsp::RcpspProblem rcpsp_; + RcpspProblem rcpsp_; }; +} // namespace rcpsp +} // namespace util } // namespace operations_research #endif // OR_TOOLS_UTIL_RCPSP_PARSER_H_ diff --git a/tools/setup.py b/tools/setup.py index 4401dd013c..400e2c8928 100644 --- a/tools/setup.py +++ b/tools/setup.py @@ -33,7 +33,9 @@ setup( 'ortools.algorithms', 'ortools.constraint_solver', 'ortools.graph', - 'ortools.linear_solver',], + 'ortools.linear_solver', + 'ortools.sat', + 'ortools.util',], ext_modules = [dummy_module], install_requires = [ 'protobuf >= PROTOBUF_TAG', @@ -44,6 +46,8 @@ setup( 'ortools.linear_solver' : ['_pywraplp.dll'], 'ortools.graph' : ['_pywrapgraph.dll'], 'ortools.algorithms' : ['_pywrapknapsack_solver.dll'], + 'ortools.sat' : ['_pywrapsat.dll'], + 'ortools.util' : ['_pywraputil.dll'], DELETEWIN 'ortools' : ['libortools.DLL'] }, license='Apache 2.0',