commit
9b9f4d968d
@ -0,0 +1,10 @@
|
|||||||
|
*.jl.*.cov
|
||||||
|
*.jl.cov
|
||||||
|
*.jl.mem
|
||||||
|
deps/build.log
|
||||||
|
deps/deps.jl
|
||||||
|
deps/downloads/
|
||||||
|
deps/src/
|
||||||
|
deps/usr/
|
||||||
|
docs/build/
|
||||||
|
docs/site/
|
@ -0,0 +1,25 @@
|
|||||||
|
Copyright © 2020, UChicago Argonne, LLC
|
||||||
|
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
Software Name: MIPLearn
|
||||||
|
|
||||||
|
By: Argonne National Laboratory
|
||||||
|
|
||||||
|
OPEN SOURCE LICENSE
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
********************************************************************************
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
----------
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
********************************************************************************
|
@ -0,0 +1,339 @@
|
|||||||
|
# This file is machine-generated - editing it directly is not advised
|
||||||
|
|
||||||
|
[[Base64]]
|
||||||
|
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
||||||
|
|
||||||
|
[[BenchmarkTools]]
|
||||||
|
deps = ["JSON", "Logging", "Printf", "Statistics", "UUIDs"]
|
||||||
|
git-tree-sha1 = "9e62e66db34540a0c919d72172cc2f642ac71260"
|
||||||
|
uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
|
||||||
|
version = "0.5.0"
|
||||||
|
|
||||||
|
[[Bzip2_jll]]
|
||||||
|
deps = ["Libdl", "Pkg"]
|
||||||
|
git-tree-sha1 = "03a44490020826950c68005cafb336e5ba08b7e8"
|
||||||
|
uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0"
|
||||||
|
version = "1.0.6+4"
|
||||||
|
|
||||||
|
[[CPLEX]]
|
||||||
|
deps = ["Libdl", "LinearAlgebra", "MathOptInterface", "MathProgBase", "SparseArrays"]
|
||||||
|
git-tree-sha1 = "c3d7c4c3e4d4bd01c5ac89dee420be93ef7ef20b"
|
||||||
|
uuid = "a076750e-1247-5638-91d2-ce28b192dca0"
|
||||||
|
version = "0.6.6"
|
||||||
|
|
||||||
|
[[Calculus]]
|
||||||
|
deps = ["LinearAlgebra"]
|
||||||
|
git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad"
|
||||||
|
uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9"
|
||||||
|
version = "0.5.1"
|
||||||
|
|
||||||
|
[[CodeTracking]]
|
||||||
|
deps = ["InteractiveUtils", "UUIDs"]
|
||||||
|
git-tree-sha1 = "ccc043a0df446cac279dca29d13e2827b40aceb5"
|
||||||
|
uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
|
||||||
|
version = "0.5.12"
|
||||||
|
|
||||||
|
[[CodecBzip2]]
|
||||||
|
deps = ["Bzip2_jll", "Libdl", "TranscodingStreams"]
|
||||||
|
git-tree-sha1 = "2e62a725210ce3c3c2e1a3080190e7ca491f18d7"
|
||||||
|
uuid = "523fee87-0ab8-5b00-afb7-3ecf72e48cfd"
|
||||||
|
version = "0.7.2"
|
||||||
|
|
||||||
|
[[CodecZlib]]
|
||||||
|
deps = ["TranscodingStreams", "Zlib_jll"]
|
||||||
|
git-tree-sha1 = "ded953804d019afa9a3f98981d99b33e3db7b6da"
|
||||||
|
uuid = "944b1d66-785c-5afd-91f1-9de20f533193"
|
||||||
|
version = "0.7.0"
|
||||||
|
|
||||||
|
[[CommonSubexpressions]]
|
||||||
|
deps = ["MacroTools", "Test"]
|
||||||
|
git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7"
|
||||||
|
uuid = "bbf7d656-a473-5ed7-a52c-81e309532950"
|
||||||
|
version = "0.3.0"
|
||||||
|
|
||||||
|
[[CompilerSupportLibraries_jll]]
|
||||||
|
deps = ["Libdl", "Pkg"]
|
||||||
|
git-tree-sha1 = "7c4f882c41faa72118841185afc58a2eb00ef612"
|
||||||
|
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
|
||||||
|
version = "0.3.3+0"
|
||||||
|
|
||||||
|
[[Conda]]
|
||||||
|
deps = ["JSON", "VersionParsing"]
|
||||||
|
git-tree-sha1 = "7a58bb32ce5d85f8bf7559aa7c2842f9aecf52fc"
|
||||||
|
uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d"
|
||||||
|
version = "1.4.1"
|
||||||
|
|
||||||
|
[[DataStructures]]
|
||||||
|
deps = ["InteractiveUtils", "OrderedCollections"]
|
||||||
|
git-tree-sha1 = "88d48e133e6d3dd68183309877eac74393daa7eb"
|
||||||
|
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
|
||||||
|
version = "0.17.20"
|
||||||
|
|
||||||
|
[[Dates]]
|
||||||
|
deps = ["Printf"]
|
||||||
|
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
||||||
|
|
||||||
|
[[DiffResults]]
|
||||||
|
deps = ["StaticArrays"]
|
||||||
|
git-tree-sha1 = "da24935df8e0c6cf28de340b958f6aac88eaa0cc"
|
||||||
|
uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5"
|
||||||
|
version = "1.0.2"
|
||||||
|
|
||||||
|
[[DiffRules]]
|
||||||
|
deps = ["NaNMath", "Random", "SpecialFunctions"]
|
||||||
|
git-tree-sha1 = "eb0c34204c8410888844ada5359ac8b96292cfd1"
|
||||||
|
uuid = "b552c78f-8df3-52c6-915a-8e097449b14b"
|
||||||
|
version = "1.0.1"
|
||||||
|
|
||||||
|
[[Distributed]]
|
||||||
|
deps = ["Random", "Serialization", "Sockets"]
|
||||||
|
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"
|
||||||
|
|
||||||
|
[[FileWatching]]
|
||||||
|
uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
|
||||||
|
|
||||||
|
[[ForwardDiff]]
|
||||||
|
deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "NaNMath", "Random", "SpecialFunctions", "StaticArrays"]
|
||||||
|
git-tree-sha1 = "1d090099fb82223abc48f7ce176d3f7696ede36d"
|
||||||
|
uuid = "f6369f11-7733-5829-9624-2563aa707210"
|
||||||
|
version = "0.10.12"
|
||||||
|
|
||||||
|
[[Gurobi]]
|
||||||
|
deps = ["Libdl", "LinearAlgebra", "MathOptInterface", "MathProgBase", "SparseArrays"]
|
||||||
|
git-tree-sha1 = "f36a2fa62909675681aec582ccfc4a4a629406e4"
|
||||||
|
uuid = "2e9cd046-0924-5485-92f1-d5272153d98b"
|
||||||
|
version = "0.8.1"
|
||||||
|
|
||||||
|
[[HTTP]]
|
||||||
|
deps = ["Base64", "Dates", "IniFile", "MbedTLS", "Sockets"]
|
||||||
|
git-tree-sha1 = "2ac03263ce44be4222342bca1c51c36ce7566161"
|
||||||
|
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
|
||||||
|
version = "0.8.17"
|
||||||
|
|
||||||
|
[[IniFile]]
|
||||||
|
deps = ["Test"]
|
||||||
|
git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8"
|
||||||
|
uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f"
|
||||||
|
version = "0.5.0"
|
||||||
|
|
||||||
|
[[InteractiveUtils]]
|
||||||
|
deps = ["Markdown"]
|
||||||
|
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
|
||||||
|
|
||||||
|
[[JSON]]
|
||||||
|
deps = ["Dates", "Mmap", "Parsers", "Unicode"]
|
||||||
|
git-tree-sha1 = "b34d7cef7b337321e97d22242c3c2b91f476748e"
|
||||||
|
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
|
||||||
|
version = "0.21.0"
|
||||||
|
|
||||||
|
[[JSON2]]
|
||||||
|
deps = ["Dates", "Parsers", "Test"]
|
||||||
|
git-tree-sha1 = "66397cc6c08922f98a28ab05a8d3002f9853b129"
|
||||||
|
uuid = "2535ab7d-5cd8-5a07-80ac-9b1792aadce3"
|
||||||
|
version = "0.3.2"
|
||||||
|
|
||||||
|
[[JSONSchema]]
|
||||||
|
deps = ["HTTP", "JSON", "ZipFile"]
|
||||||
|
git-tree-sha1 = "a9ecdbc90be216912a2e3e8a8e38dc4c93f0d065"
|
||||||
|
uuid = "7d188eb4-7ad8-530c-ae41-71a32a6d4692"
|
||||||
|
version = "0.3.2"
|
||||||
|
|
||||||
|
[[JuMP]]
|
||||||
|
deps = ["Calculus", "DataStructures", "ForwardDiff", "LinearAlgebra", "MathOptInterface", "MutableArithmetics", "NaNMath", "Random", "SparseArrays", "Statistics"]
|
||||||
|
git-tree-sha1 = "cbab42e2e912109d27046aa88f02a283a9abac7c"
|
||||||
|
uuid = "4076af6c-e467-56ae-b986-b466b2749572"
|
||||||
|
version = "0.21.3"
|
||||||
|
|
||||||
|
[[JuliaInterpreter]]
|
||||||
|
deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"]
|
||||||
|
git-tree-sha1 = "7b2a1b650cec61a7d8cd8ee9ee7a818b5764d502"
|
||||||
|
uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"
|
||||||
|
version = "0.7.26"
|
||||||
|
|
||||||
|
[[LibGit2]]
|
||||||
|
deps = ["Printf"]
|
||||||
|
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"
|
||||||
|
|
||||||
|
[[Libdl]]
|
||||||
|
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
|
||||||
|
|
||||||
|
[[LinearAlgebra]]
|
||||||
|
deps = ["Libdl"]
|
||||||
|
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
||||||
|
|
||||||
|
[[Logging]]
|
||||||
|
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
|
||||||
|
|
||||||
|
[[LoweredCodeUtils]]
|
||||||
|
deps = ["JuliaInterpreter"]
|
||||||
|
git-tree-sha1 = "dbd9336b43c2d6fa492efa09ba3bb10fbdbeeb64"
|
||||||
|
uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
|
||||||
|
version = "0.4.9"
|
||||||
|
|
||||||
|
[[MacroTools]]
|
||||||
|
deps = ["Markdown", "Random"]
|
||||||
|
git-tree-sha1 = "f7d2e3f654af75f01ec49be82c231c382214223a"
|
||||||
|
uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
|
||||||
|
version = "0.5.5"
|
||||||
|
|
||||||
|
[[Markdown]]
|
||||||
|
deps = ["Base64"]
|
||||||
|
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
|
||||||
|
|
||||||
|
[[MathOptInterface]]
|
||||||
|
deps = ["BenchmarkTools", "CodecBzip2", "CodecZlib", "JSON", "JSONSchema", "LinearAlgebra", "MutableArithmetics", "OrderedCollections", "SparseArrays", "Test", "Unicode"]
|
||||||
|
git-tree-sha1 = "cd2049c055c7d192a235670d50faa375361624ba"
|
||||||
|
uuid = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
|
||||||
|
version = "0.9.14"
|
||||||
|
|
||||||
|
[[MathProgBase]]
|
||||||
|
deps = ["LinearAlgebra", "SparseArrays"]
|
||||||
|
git-tree-sha1 = "9abbe463a1e9fc507f12a69e7f29346c2cdc472c"
|
||||||
|
uuid = "fdba3010-5040-5b88-9595-932c9decdf73"
|
||||||
|
version = "0.7.8"
|
||||||
|
|
||||||
|
[[MbedTLS]]
|
||||||
|
deps = ["Dates", "MbedTLS_jll", "Random", "Sockets"]
|
||||||
|
git-tree-sha1 = "426a6978b03a97ceb7ead77775a1da066343ec6e"
|
||||||
|
uuid = "739be429-bea8-5141-9913-cc70e7f3736d"
|
||||||
|
version = "1.0.2"
|
||||||
|
|
||||||
|
[[MbedTLS_jll]]
|
||||||
|
deps = ["Libdl", "Pkg"]
|
||||||
|
git-tree-sha1 = "a0cb0d489819fa7ea5f9fa84c7e7eba19d8073af"
|
||||||
|
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
|
||||||
|
version = "2.16.6+1"
|
||||||
|
|
||||||
|
[[Mmap]]
|
||||||
|
uuid = "a63ad114-7e13-5084-954f-fe012c677804"
|
||||||
|
|
||||||
|
[[MutableArithmetics]]
|
||||||
|
deps = ["LinearAlgebra", "SparseArrays", "Test"]
|
||||||
|
git-tree-sha1 = "6cf09794783b9de2e662c4e8b60d743021e338d0"
|
||||||
|
uuid = "d8a4904e-b15c-11e9-3269-09a3773c0cb0"
|
||||||
|
version = "0.2.10"
|
||||||
|
|
||||||
|
[[NaNMath]]
|
||||||
|
git-tree-sha1 = "c84c576296d0e2fbb3fc134d3e09086b3ea617cd"
|
||||||
|
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
|
||||||
|
version = "0.3.4"
|
||||||
|
|
||||||
|
[[OpenSpecFun_jll]]
|
||||||
|
deps = ["CompilerSupportLibraries_jll", "Libdl", "Pkg"]
|
||||||
|
git-tree-sha1 = "d51c416559217d974a1113522d5919235ae67a87"
|
||||||
|
uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e"
|
||||||
|
version = "0.5.3+3"
|
||||||
|
|
||||||
|
[[OrderedCollections]]
|
||||||
|
git-tree-sha1 = "293b70ac1780f9584c89268a6e2a560d938a7065"
|
||||||
|
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
|
||||||
|
version = "1.3.0"
|
||||||
|
|
||||||
|
[[PackageCompiler]]
|
||||||
|
deps = ["Libdl", "Pkg", "UUIDs"]
|
||||||
|
git-tree-sha1 = "98aa9c653e1dc3473bb5050caf8501293db9eee1"
|
||||||
|
uuid = "9b87118b-4619-50d2-8e1e-99f35a4d4d9d"
|
||||||
|
version = "1.2.1"
|
||||||
|
|
||||||
|
[[Parsers]]
|
||||||
|
deps = ["Dates", "Test"]
|
||||||
|
git-tree-sha1 = "8077624b3c450b15c087944363606a6ba12f925e"
|
||||||
|
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
|
||||||
|
version = "1.0.10"
|
||||||
|
|
||||||
|
[[Pkg]]
|
||||||
|
deps = ["Dates", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"]
|
||||||
|
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
|
||||||
|
|
||||||
|
[[Printf]]
|
||||||
|
deps = ["Unicode"]
|
||||||
|
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
|
||||||
|
|
||||||
|
[[PyCall]]
|
||||||
|
deps = ["Conda", "Dates", "Libdl", "LinearAlgebra", "MacroTools", "Serialization", "VersionParsing"]
|
||||||
|
git-tree-sha1 = "3a3fdb9000d35958c9ba2323ca7c4958901f115d"
|
||||||
|
uuid = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
|
||||||
|
version = "1.91.4"
|
||||||
|
|
||||||
|
[[REPL]]
|
||||||
|
deps = ["InteractiveUtils", "Markdown", "Sockets"]
|
||||||
|
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
|
||||||
|
|
||||||
|
[[Random]]
|
||||||
|
deps = ["Serialization"]
|
||||||
|
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
||||||
|
|
||||||
|
[[Revise]]
|
||||||
|
deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "UUIDs", "Unicode"]
|
||||||
|
git-tree-sha1 = "db20b9938ed44ea2f5b48f92a9b4e0a0afe37823"
|
||||||
|
uuid = "295af30f-e4ad-537b-8983-00126c2a3abe"
|
||||||
|
version = "2.7.4"
|
||||||
|
|
||||||
|
[[SHA]]
|
||||||
|
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
|
||||||
|
|
||||||
|
[[Serialization]]
|
||||||
|
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
|
||||||
|
|
||||||
|
[[Sockets]]
|
||||||
|
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
|
||||||
|
|
||||||
|
[[SparseArrays]]
|
||||||
|
deps = ["LinearAlgebra", "Random"]
|
||||||
|
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
|
||||||
|
|
||||||
|
[[SpecialFunctions]]
|
||||||
|
deps = ["OpenSpecFun_jll"]
|
||||||
|
git-tree-sha1 = "d8d8b8a9f4119829410ecd706da4cc8594a1e020"
|
||||||
|
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
|
||||||
|
version = "0.10.3"
|
||||||
|
|
||||||
|
[[StaticArrays]]
|
||||||
|
deps = ["LinearAlgebra", "Random", "Statistics"]
|
||||||
|
git-tree-sha1 = "016d1e1a00fabc556473b07161da3d39726ded35"
|
||||||
|
uuid = "90137ffa-7385-5640-81b9-e52037218182"
|
||||||
|
version = "0.12.4"
|
||||||
|
|
||||||
|
[[Statistics]]
|
||||||
|
deps = ["LinearAlgebra", "SparseArrays"]
|
||||||
|
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
|
||||||
|
|
||||||
|
[[Test]]
|
||||||
|
deps = ["Distributed", "InteractiveUtils", "Logging", "Random"]
|
||||||
|
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||||
|
|
||||||
|
[[TimerOutputs]]
|
||||||
|
deps = ["Printf"]
|
||||||
|
git-tree-sha1 = "f458ca23ff80e46a630922c555d838303e4b9603"
|
||||||
|
uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f"
|
||||||
|
version = "0.5.6"
|
||||||
|
|
||||||
|
[[TranscodingStreams]]
|
||||||
|
deps = ["Random", "Test"]
|
||||||
|
git-tree-sha1 = "7c53c35547de1c5b9d46a4797cf6d8253807108c"
|
||||||
|
uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
|
||||||
|
version = "0.9.5"
|
||||||
|
|
||||||
|
[[UUIDs]]
|
||||||
|
deps = ["Random", "SHA"]
|
||||||
|
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
||||||
|
|
||||||
|
[[Unicode]]
|
||||||
|
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
|
||||||
|
|
||||||
|
[[VersionParsing]]
|
||||||
|
git-tree-sha1 = "80229be1f670524750d905f8fc8148e5a8c4537f"
|
||||||
|
uuid = "81def892-9a0e-5fdd-b105-ffc91e053289"
|
||||||
|
version = "1.2.0"
|
||||||
|
|
||||||
|
[[ZipFile]]
|
||||||
|
deps = ["Libdl", "Printf", "Zlib_jll"]
|
||||||
|
git-tree-sha1 = "254975fef2fc526583bb9b7c9420fe66ffe09f2f"
|
||||||
|
uuid = "a5390f91-8eb1-5f08-bee0-b1d1ffed6cea"
|
||||||
|
version = "0.9.2"
|
||||||
|
|
||||||
|
[[Zlib_jll]]
|
||||||
|
deps = ["Libdl", "Pkg"]
|
||||||
|
git-tree-sha1 = "fdd89e5ab270ea0f2a0174bd9093e557d06d4bfa"
|
||||||
|
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
|
||||||
|
version = "1.2.11+16"
|
@ -0,0 +1,22 @@
|
|||||||
|
name = "MIPLearn"
|
||||||
|
uuid = "2b1277c3-b477-4c49-a15e-7ba350325c68"
|
||||||
|
authors = ["Alinson S Xavier <git@axavier.org>"]
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
CPLEX = "a076750e-1247-5638-91d2-ce28b192dca0"
|
||||||
|
Gurobi = "2e9cd046-0924-5485-92f1-d5272153d98b"
|
||||||
|
JSON2 = "2535ab7d-5cd8-5a07-80ac-9b1792aadce3"
|
||||||
|
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
|
||||||
|
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
|
||||||
|
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
|
||||||
|
PackageCompiler = "9b87118b-4619-50d2-8e1e-99f35a4d4d9d"
|
||||||
|
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
|
||||||
|
PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
|
||||||
|
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
|
||||||
|
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||||
|
TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f"
|
||||||
|
|
||||||
|
[compat]
|
||||||
|
CPLEX = "0.6"
|
||||||
|
JuMP = "0.21"
|
@ -0,0 +1,41 @@
|
|||||||
|
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||||
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
__precompile__(false)
|
||||||
|
module MIPLearn
|
||||||
|
|
||||||
|
using PyCall
|
||||||
|
miplearn = pyimport("miplearn")
|
||||||
|
Instance = miplearn.Instance
|
||||||
|
BenchmarkRunner = miplearn.BenchmarkRunner
|
||||||
|
|
||||||
|
macro pycall(expr)
|
||||||
|
quote
|
||||||
|
err_msg = nothing
|
||||||
|
result = nothing
|
||||||
|
try
|
||||||
|
result = $(esc(expr))
|
||||||
|
catch err
|
||||||
|
args = err.val.args[1]
|
||||||
|
if (err isa PyCall.PyError) && (args isa String) && startswith(args, "Julia")
|
||||||
|
err_msg = replace(args, r"Stacktrace.*" => "")
|
||||||
|
else
|
||||||
|
rethrow(err)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if err_msg != nothing
|
||||||
|
error(err_msg)
|
||||||
|
end
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
include("log.jl")
|
||||||
|
include("jump_solver.jl")
|
||||||
|
include("learning_solver.jl")
|
||||||
|
include("instance.jl")
|
||||||
|
|
||||||
|
export Instance, BenchmarkRunner
|
||||||
|
|
||||||
|
end # module
|
@ -0,0 +1,61 @@
|
|||||||
|
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||||
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
using JSON2
|
||||||
|
import Base: dump
|
||||||
|
|
||||||
|
get_instance_features(instance) = [0.]
|
||||||
|
get_variable_features(instance, var, index) = [0.]
|
||||||
|
find_violated_lazy_constraints(instance, model) = []
|
||||||
|
build_lazy_constraint(instance, model, v) = nothing
|
||||||
|
|
||||||
|
dump(instance::PyCall.PyObject, filename) = @pycall instance.dump(filename)
|
||||||
|
load!(instance::PyCall.PyObject, filename) = @pycall instance.load(filename)
|
||||||
|
|
||||||
|
macro Instance(klass)
|
||||||
|
quote
|
||||||
|
@pydef mutable struct Wrapper <: Instance
|
||||||
|
function __init__(self, args...; kwargs...)
|
||||||
|
self.data = $(esc(klass))(args...; kwargs...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function dump(self, filename)
|
||||||
|
prev_data = self.data
|
||||||
|
self.data = JSON2.write(prev_data)
|
||||||
|
Instance.dump(self, filename)
|
||||||
|
self.data = prev_data
|
||||||
|
end
|
||||||
|
|
||||||
|
function load(self, filename)
|
||||||
|
Instance.load(self, filename)
|
||||||
|
self.data = JSON2.read(self.data, $(esc(klass)))
|
||||||
|
end
|
||||||
|
|
||||||
|
to_model(self) =
|
||||||
|
$(esc(:to_model))(self.data)
|
||||||
|
|
||||||
|
get_instance_features(self) =
|
||||||
|
get_instance_features(self.data)
|
||||||
|
|
||||||
|
get_variable_features(self, var, index) =
|
||||||
|
get_variable_features(self.data, var, index)
|
||||||
|
|
||||||
|
function find_violated_lazy_constraints(self, model)
|
||||||
|
find_violated_lazy_constraints(self.data, model)
|
||||||
|
end
|
||||||
|
|
||||||
|
function build_lazy_constraint(self, model, v)
|
||||||
|
build_lazy_constraint(self.data, model, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
export get_instance_features,
|
||||||
|
get_variable_features,
|
||||||
|
find_violated_lazy_constraints,
|
||||||
|
build_lazy_constraint,
|
||||||
|
dump,
|
||||||
|
load!,
|
||||||
|
@Instance
|
@ -0,0 +1,254 @@
|
|||||||
|
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||||
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
using JuMP
|
||||||
|
using CPLEX
|
||||||
|
using MathOptInterface
|
||||||
|
const MOI = MathOptInterface
|
||||||
|
using TimerOutputs
|
||||||
|
|
||||||
|
|
||||||
|
mutable struct JuMPSolverData
|
||||||
|
basename_idx_to_var
|
||||||
|
var_to_basename_idx
|
||||||
|
optimizer
|
||||||
|
instance
|
||||||
|
model
|
||||||
|
bin_vars
|
||||||
|
solution::Union{Nothing,Dict{String,Dict{String,Float64}}}
|
||||||
|
time_limit::Union{Nothing, Float64}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function varname_split(varname::String)
|
||||||
|
m = match(r"([^[]*)\[(.*)\]", varname)
|
||||||
|
if m == nothing
|
||||||
|
return varname, ""
|
||||||
|
end
|
||||||
|
return m.captures[1], m.captures[2]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
optimize_and_capture_output!(model; tee=tee)
|
||||||
|
|
||||||
|
Optimizes a given JuMP model while capturing the solver log, then returns that log.
|
||||||
|
If tee=true, prints the solver log to the standard output as the optimization takes place.
|
||||||
|
"""
|
||||||
|
function optimize_and_capture_output!(model; tee::Bool=false)
|
||||||
|
original_stdout = stdout
|
||||||
|
rd, wr = redirect_stdout()
|
||||||
|
task = @async begin
|
||||||
|
log = ""
|
||||||
|
while true
|
||||||
|
line = String(readavailable(rd))
|
||||||
|
isopen(rd) || break
|
||||||
|
log *= String(line)
|
||||||
|
if tee
|
||||||
|
print(original_stdout, line)
|
||||||
|
flush(original_stdout)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return log
|
||||||
|
end
|
||||||
|
JuMP.optimize!(model)
|
||||||
|
sleep(1)
|
||||||
|
redirect_stdout(original_stdout)
|
||||||
|
close(rd)
|
||||||
|
return fetch(task)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function solve(data::JuMPSolverData; tee::Bool=false)
|
||||||
|
instance, model = data.instance, data.model
|
||||||
|
if data.time_limit != nothing
|
||||||
|
JuMP.set_time_limit_sec(model, data.time_limit)
|
||||||
|
end
|
||||||
|
wallclock_time = 0
|
||||||
|
found_lazy = []
|
||||||
|
log = ""
|
||||||
|
while true
|
||||||
|
log *= optimize_and_capture_output!(model, tee=tee)
|
||||||
|
wallclock_time += JuMP.solve_time(model)
|
||||||
|
violations = instance.find_violated_lazy_constraints(model)
|
||||||
|
if length(violations) == 0
|
||||||
|
break
|
||||||
|
end
|
||||||
|
append!(found_lazy, violations)
|
||||||
|
for v in violations
|
||||||
|
instance.build_lazy_constraint(data.model, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
update_solution!(data)
|
||||||
|
instance.found_violated_lazy_constraints = found_lazy
|
||||||
|
instance.found_violated_user_cuts = []
|
||||||
|
primal_bound = JuMP.objective_value(model)
|
||||||
|
dual_bound = JuMP.objective_bound(model)
|
||||||
|
if JuMP.objective_sense(model) == MOI.MIN_SENSE
|
||||||
|
sense = "min"
|
||||||
|
lower_bound = dual_bound
|
||||||
|
upper_bound = primal_bound
|
||||||
|
else
|
||||||
|
sense = "max"
|
||||||
|
lower_bound = primal_bound
|
||||||
|
upper_bound = dual_bound
|
||||||
|
end
|
||||||
|
return Dict("Lower bound" => lower_bound,
|
||||||
|
"Upper bound" => upper_bound,
|
||||||
|
"Sense" => sense,
|
||||||
|
"Wallclock time" => wallclock_time,
|
||||||
|
"Nodes" => 1,
|
||||||
|
"Log" => log,
|
||||||
|
"Warm start value" => nothing)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function solve_lp(data::JuMPSolverData; tee::Bool=false)
|
||||||
|
model, bin_vars = data.model, data.bin_vars
|
||||||
|
for var in bin_vars
|
||||||
|
JuMP.unset_binary(var)
|
||||||
|
JuMP.set_upper_bound(var, 1.0)
|
||||||
|
JuMP.set_lower_bound(var, 0.0)
|
||||||
|
end
|
||||||
|
log = optimize_and_capture_output!(model, tee=tee)
|
||||||
|
update_solution!(data)
|
||||||
|
obj_value = JuMP.objective_value(model)
|
||||||
|
for var in bin_vars
|
||||||
|
JuMP.set_binary(var)
|
||||||
|
end
|
||||||
|
return Dict("Optimal value" => obj_value,
|
||||||
|
"Log" => log)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function update_solution!(data::JuMPSolverData)
|
||||||
|
var_to_basename_idx, model = data.var_to_basename_idx, data.model
|
||||||
|
solution = Dict{String,Dict{String,Float64}}()
|
||||||
|
for var in JuMP.all_variables(model)
|
||||||
|
var in keys(var_to_basename_idx) || continue
|
||||||
|
basename, idx = var_to_basename_idx[var]
|
||||||
|
if !haskey(solution, basename)
|
||||||
|
solution[basename] = Dict{String,Float64}()
|
||||||
|
end
|
||||||
|
solution[basename][idx] = JuMP.value(var)
|
||||||
|
end
|
||||||
|
data.solution = solution
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function get_variables(data::JuMPSolverData)
|
||||||
|
var_to_basename_idx, model = data.var_to_basename_idx, data.model
|
||||||
|
variables = Dict()
|
||||||
|
for var in JuMP.all_variables(model)
|
||||||
|
var in keys(var_to_basename_idx) || continue
|
||||||
|
basename, idx = var_to_basename_idx[var]
|
||||||
|
if !haskey(variables, basename)
|
||||||
|
variables[basename] = []
|
||||||
|
end
|
||||||
|
push!(variables[basename], idx)
|
||||||
|
end
|
||||||
|
return variables
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function set_instance!(data::JuMPSolverData, instance, model)
|
||||||
|
data.instance = instance
|
||||||
|
data.model = model
|
||||||
|
data.var_to_basename_idx = Dict(var => varname_split(JuMP.name(var))
|
||||||
|
for var in JuMP.all_variables(model))
|
||||||
|
data.basename_idx_to_var = Dict(varname_split(JuMP.name(var)) => var
|
||||||
|
for var in JuMP.all_variables(model))
|
||||||
|
data.bin_vars = [var
|
||||||
|
for var in JuMP.all_variables(model)
|
||||||
|
if JuMP.is_binary(var)]
|
||||||
|
if data.optimizer != nothing
|
||||||
|
JuMP.set_optimizer(model, data.optimizer)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function fix!(data::JuMPSolverData, solution)
|
||||||
|
count = 0
|
||||||
|
for (basename, subsolution) in solution
|
||||||
|
for (idx, value) in subsolution
|
||||||
|
value != nothing || continue
|
||||||
|
var = data.basename_idx_to_var[basename, idx]
|
||||||
|
JuMP.fix(var, value, force=true)
|
||||||
|
count += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@info "Fixing $count variables"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function set_warm_start!(data::JuMPSolverData, solution)
|
||||||
|
count = 0
|
||||||
|
for (basename, subsolution) in solution
|
||||||
|
for (idx, value) in subsolution
|
||||||
|
value != nothing || continue
|
||||||
|
var = data.basename_idx_to_var[basename, idx]
|
||||||
|
JuMP.set_start_value(var, value)
|
||||||
|
count += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@info "Setting warm start values for $count variables"
|
||||||
|
end
|
||||||
|
|
||||||
|
@pydef mutable struct JuMPSolver <: miplearn.solvers.internal.InternalSolver
|
||||||
|
function __init__(self; optimizer)
|
||||||
|
self.data = JuMPSolverData(nothing, # basename_idx_to_var
|
||||||
|
nothing, # var_to_basename_idx
|
||||||
|
optimizer,
|
||||||
|
nothing, # instance
|
||||||
|
nothing, # model
|
||||||
|
nothing, # bin_vars
|
||||||
|
nothing, # solution
|
||||||
|
nothing, # time limit
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
set_warm_start(self, solution) =
|
||||||
|
set_warm_start!(self.data, solution)
|
||||||
|
|
||||||
|
fix(self, solution) =
|
||||||
|
fix!(self.data, solution)
|
||||||
|
|
||||||
|
set_instance(self, instance, model) =
|
||||||
|
set_instance!(self.data, instance, model)
|
||||||
|
|
||||||
|
solve(self; tee=false) =
|
||||||
|
solve(self.data, tee=tee)
|
||||||
|
|
||||||
|
solve_lp(self; tee=false) =
|
||||||
|
solve_lp(self.data, tee=tee)
|
||||||
|
|
||||||
|
get_solution(self) =
|
||||||
|
self.data.solution
|
||||||
|
|
||||||
|
get_variables(self) =
|
||||||
|
get_variables(self.data)
|
||||||
|
|
||||||
|
set_time_limit(self, time_limit) =
|
||||||
|
self.data.time_limit = time_limit
|
||||||
|
|
||||||
|
set_gap_tolerance(self, gap_tolerance) =
|
||||||
|
@warn "JuMPSolver: set_gap_tolerance not implemented"
|
||||||
|
|
||||||
|
set_node_limit(self) =
|
||||||
|
@warn "JuMPSolver: set_node_limit not implemented"
|
||||||
|
|
||||||
|
set_threads(self, threads) =
|
||||||
|
@warn "JuMPSolver: set_threads not implemented"
|
||||||
|
|
||||||
|
set_branching_priorities(self, priorities) =
|
||||||
|
@warn "JuMPSolver: set_branching_priorities not implemented"
|
||||||
|
|
||||||
|
add_constraint(self, constraint) = nothing
|
||||||
|
|
||||||
|
clear_warm_start(self) =
|
||||||
|
error("JuMPSolver.clear_warm_start should never be called")
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
export JuMPSolver, solve!, fit!, add!
|
@ -0,0 +1,28 @@
|
|||||||
|
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||||
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
struct LearningSolver
|
||||||
|
py::PyCall.PyObject
|
||||||
|
end
|
||||||
|
|
||||||
|
function LearningSolver(;
|
||||||
|
optimizer,
|
||||||
|
kwargs...,
|
||||||
|
)::LearningSolver
|
||||||
|
py = @pycall miplearn.LearningSolver(;
|
||||||
|
kwargs...,
|
||||||
|
solver=JuMPSolver(optimizer=optimizer))
|
||||||
|
return LearningSolver(py)
|
||||||
|
end
|
||||||
|
|
||||||
|
solve!(solver::LearningSolver, instance; kwargs...) =
|
||||||
|
@pycall solver.py.solve(instance; kwargs...)
|
||||||
|
|
||||||
|
fit!(solver::LearningSolver, instances; kwargs...) =
|
||||||
|
@pycall solver.py.fit(instances; kwargs...)
|
||||||
|
|
||||||
|
add!(solver::LearningSolver, component; kwargs...) =
|
||||||
|
@pycall solver.py.add(component; kwargs...)
|
||||||
|
|
||||||
|
export LearningSolver
|
@ -0,0 +1,62 @@
|
|||||||
|
import Logging: min_enabled_level, shouldlog, handle_message
|
||||||
|
using Base.CoreLogging, Logging, Printf
|
||||||
|
|
||||||
|
struct TimeLogger <: AbstractLogger
|
||||||
|
initial_time::Float64
|
||||||
|
file::Union{Nothing, IOStream}
|
||||||
|
screen_log_level
|
||||||
|
io_log_level
|
||||||
|
end
|
||||||
|
|
||||||
|
function TimeLogger(;
|
||||||
|
initial_time::Float64,
|
||||||
|
file::Union{Nothing, IOStream} = nothing,
|
||||||
|
screen_log_level = CoreLogging.Info,
|
||||||
|
io_log_level = CoreLogging.Info,
|
||||||
|
) :: TimeLogger
|
||||||
|
return TimeLogger(initial_time, file, screen_log_level, io_log_level)
|
||||||
|
end
|
||||||
|
|
||||||
|
min_enabled_level(logger::TimeLogger) = logger.io_log_level
|
||||||
|
shouldlog(logger::TimeLogger, level, _module, group, id) = true
|
||||||
|
|
||||||
|
function handle_message(logger::TimeLogger,
|
||||||
|
level,
|
||||||
|
message,
|
||||||
|
_module,
|
||||||
|
group,
|
||||||
|
id,
|
||||||
|
filepath,
|
||||||
|
line;
|
||||||
|
kwargs...)
|
||||||
|
elapsed_time = time() - logger.initial_time
|
||||||
|
time_string = @sprintf("[%12.3f] ", elapsed_time)
|
||||||
|
|
||||||
|
if level >= Logging.Error
|
||||||
|
color = :light_red
|
||||||
|
elseif level >= Logging.Warn
|
||||||
|
color = :light_yellow
|
||||||
|
else
|
||||||
|
color = :light_green
|
||||||
|
end
|
||||||
|
|
||||||
|
if level >= logger.screen_log_level
|
||||||
|
printstyled(time_string, color=color)
|
||||||
|
println(message)
|
||||||
|
end
|
||||||
|
if logger.file != nothing && level >= logger.io_log_level
|
||||||
|
write(logger.file, time_string)
|
||||||
|
write(logger.file, message)
|
||||||
|
write(logger.file, "\n")
|
||||||
|
flush(logger.file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function setup_logger()
|
||||||
|
initial_time = time()
|
||||||
|
global_logger(TimeLogger(initial_time=initial_time))
|
||||||
|
miplearn = pyimport("miplearn")
|
||||||
|
miplearn.setup_logger(initial_time)
|
||||||
|
end
|
||||||
|
|
||||||
|
export TimeLogger
|
@ -0,0 +1,22 @@
|
|||||||
|
using PackageCompiler
|
||||||
|
|
||||||
|
using CPLEX
|
||||||
|
using CPLEXW
|
||||||
|
using Gurobi
|
||||||
|
using JuMP
|
||||||
|
using MathOptInterface
|
||||||
|
using PyCall
|
||||||
|
using TimerOutputs
|
||||||
|
using TinyBnB
|
||||||
|
|
||||||
|
pkg = [:CPLEX
|
||||||
|
:CPLEXW
|
||||||
|
:Gurobi
|
||||||
|
:JuMP
|
||||||
|
:MathOptInterface
|
||||||
|
:PyCall
|
||||||
|
:TimerOutputs
|
||||||
|
:TinyBnB]
|
||||||
|
|
||||||
|
@info "Building system image..."
|
||||||
|
create_sysimage(pkg, sysimage_path="build/sysimage.so")
|
@ -0,0 +1,65 @@
|
|||||||
|
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||||
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
using Test
|
||||||
|
using MIPLearn
|
||||||
|
using CPLEX
|
||||||
|
using Gurobi
|
||||||
|
|
||||||
|
@testset "varname_split" begin
|
||||||
|
@test MIPLearn.varname_split("x[1]") == ("x", "1")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@testset "JuMPSolver" begin
|
||||||
|
for optimizer in [CPLEX.Optimizer, Gurobi.Optimizer]
|
||||||
|
instance = KnapsackInstance([23., 26., 20., 18.],
|
||||||
|
[505., 352., 458., 220.],
|
||||||
|
67.0)
|
||||||
|
model = instance.to_model()
|
||||||
|
|
||||||
|
solver = JuMPSolver(optimizer=optimizer)
|
||||||
|
solver.set_instance(instance, model)
|
||||||
|
solver.set_time_limit(30)
|
||||||
|
solver.set_warm_start(Dict("x" => Dict(
|
||||||
|
"1" => 1.0,
|
||||||
|
"2" => 0.0,
|
||||||
|
"3" => 0.0,
|
||||||
|
"4" => 1.0,
|
||||||
|
)))
|
||||||
|
stats = solver.solve()
|
||||||
|
|
||||||
|
@test stats["Lower bound"] == 1183.0
|
||||||
|
@test stats["Upper bound"] == 1183.0
|
||||||
|
@test stats["Sense"] == "max"
|
||||||
|
@test stats["Wallclock time"] > 0
|
||||||
|
@test length(stats["Log"]) > 100
|
||||||
|
|
||||||
|
solution = solver.get_solution()
|
||||||
|
@test solution["x"]["1"] == 1.0
|
||||||
|
@test solution["x"]["2"] == 0.0
|
||||||
|
@test solution["x"]["3"] == 1.0
|
||||||
|
@test solution["x"]["4"] == 1.0
|
||||||
|
|
||||||
|
stats = solver.solve_lp()
|
||||||
|
@test round(stats["Optimal value"], digits=3) == 1287.923
|
||||||
|
@test length(stats["Log"]) > 100
|
||||||
|
|
||||||
|
solution = solver.get_solution()
|
||||||
|
@test round(solution["x"]["1"], digits=3) == 1.000
|
||||||
|
@test round(solution["x"]["2"], digits=3) == 0.923
|
||||||
|
@test round(solution["x"]["3"], digits=3) == 1.000
|
||||||
|
@test round(solution["x"]["4"], digits=3) == 0.000
|
||||||
|
|
||||||
|
solver.fix(Dict("x" => Dict(
|
||||||
|
"1" => 1.0,
|
||||||
|
"2" => 0.0,
|
||||||
|
"3" => 0.0,
|
||||||
|
"4" => 1.0,
|
||||||
|
)))
|
||||||
|
stats = solver.solve()
|
||||||
|
@test stats["Lower bound"] == 725.0
|
||||||
|
@test stats["Upper bound"] == 725.0
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,34 @@
|
|||||||
|
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||||
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
import MIPLearn: get_instance_features,
|
||||||
|
get_variable_features
|
||||||
|
find_violated_lazy_constraints
|
||||||
|
using JuMP
|
||||||
|
|
||||||
|
struct KnapsackData
|
||||||
|
weights
|
||||||
|
prices
|
||||||
|
capacity
|
||||||
|
end
|
||||||
|
|
||||||
|
function to_model(data::KnapsackData)
|
||||||
|
model = Model()
|
||||||
|
n = length(data.weights)
|
||||||
|
@variable(model, x[1:n], Bin)
|
||||||
|
@objective(model, Max, sum(x[i] * data.prices[i] for i in 1:n))
|
||||||
|
@constraint(model, sum(x[i] * data.weights[i] for i in 1:n) <= data.capacity)
|
||||||
|
return model
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_instance_features(data::KnapsackData)
|
||||||
|
return [0.]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function get_variable_features(data::KnapsackData, var, index)
|
||||||
|
return [0.]
|
||||||
|
end
|
||||||
|
|
||||||
|
KnapsackInstance = @Instance(KnapsackData)
|
@ -0,0 +1,50 @@
|
|||||||
|
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||||
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
using Test
|
||||||
|
using MIPLearn
|
||||||
|
using CPLEX
|
||||||
|
using Gurobi
|
||||||
|
|
||||||
|
|
||||||
|
@testset "Instance" begin
|
||||||
|
weights = [23., 26., 20., 18.]
|
||||||
|
prices = [505., 352., 458., 220.]
|
||||||
|
capacity = 67.0
|
||||||
|
|
||||||
|
instance = KnapsackInstance(weights, prices, capacity)
|
||||||
|
dump(instance, "tmp/instance.json.gz")
|
||||||
|
|
||||||
|
instance = KnapsackInstance([0.0], [0.0], 0.0)
|
||||||
|
load!(instance, "tmp/instance.json.gz")
|
||||||
|
@test instance.data.weights == weights
|
||||||
|
@test instance.data.prices == prices
|
||||||
|
@test instance.data.capacity == capacity
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@testset "LearningSolver" begin
|
||||||
|
for optimizer in [CPLEX.Optimizer, Gurobi.Optimizer]
|
||||||
|
instance = KnapsackInstance([23., 26., 20., 18.],
|
||||||
|
[505., 352., 458., 220.],
|
||||||
|
67.0)
|
||||||
|
solver = LearningSolver(optimizer=optimizer,
|
||||||
|
mode="heuristic",
|
||||||
|
time_limit=90)
|
||||||
|
stats = solve!(solver, instance)
|
||||||
|
@test instance.solution["x"]["1"] == 1.0
|
||||||
|
@test instance.solution["x"]["2"] == 0.0
|
||||||
|
@test instance.solution["x"]["3"] == 1.0
|
||||||
|
@test instance.solution["x"]["4"] == 1.0
|
||||||
|
@test instance.lower_bound == 1183.0
|
||||||
|
@test instance.upper_bound == 1183.0
|
||||||
|
@test round(instance.lp_solution["x"]["1"], digits=3) == 1.000
|
||||||
|
@test round(instance.lp_solution["x"]["2"], digits=3) == 0.923
|
||||||
|
@test round(instance.lp_solution["x"]["3"], digits=3) == 1.000
|
||||||
|
@test round(instance.lp_solution["x"]["4"], digits=3) == 0.000
|
||||||
|
@test round(instance.lp_value, digits=3) == 1287.923
|
||||||
|
fit!(solver, [instance])
|
||||||
|
solve!(solver, instance)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,14 @@
|
|||||||
|
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||||
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
using Test
|
||||||
|
using MIPLearn
|
||||||
|
|
||||||
|
MIPLearn.setup_logger()
|
||||||
|
|
||||||
|
@testset "MIPLearn" begin
|
||||||
|
include("knapsack.jl")
|
||||||
|
include("jump_solver_test.jl")
|
||||||
|
include("learning_solver_test.jl")
|
||||||
|
end
|
Loading…
Reference in new issue