diff --git a/docs/guide/collectors.ipynb b/docs/guide/collectors.ipynb index 42ec697..a9b4bb6 100644 --- a/docs/guide/collectors.ipynb +++ b/docs/guide/collectors.ipynb @@ -38,9 +38,13 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "id": "f906fe9c", "metadata": { + "ExecuteTime": { + "end_time": "2024-01-30T22:19:30.826123021Z", + "start_time": "2024-01-30T22:19:30.766066926Z" + }, "collapsed": false, "jupyter": { "outputs_hidden": false @@ -57,18 +61,18 @@ "x4 = [[0.37454012 0.9507143 0.7319939 ]\n", " [0.5986585 0.15601864 0.15599452]\n", " [0.05808361 0.8661761 0.601115 ]]\n", - "x5 = (2, 3)\t0.68030757\n", - " (3, 2)\t0.45049927\n", - " (4, 0)\t0.013264962\n", - " (0, 2)\t0.94220173\n", - " (4, 2)\t0.5632882\n", - " (2, 1)\t0.3854165\n", - " (1, 1)\t0.015966251\n", - " (3, 0)\t0.23089382\n", - " (4, 4)\t0.24102546\n", - " (1, 3)\t0.68326354\n", - " (3, 1)\t0.6099967\n", - " (0, 3)\t0.8331949\n" + "x5 = (3, 2)\t0.6803075671195984\n", + " (2, 3)\t0.4504992663860321\n", + " (0, 4)\t0.013264961540699005\n", + " (2, 0)\t0.9422017335891724\n", + " (2, 4)\t0.5632882118225098\n", + " (1, 2)\t0.38541650772094727\n", + " (1, 1)\t0.015966251492500305\n", + " (0, 3)\t0.2308938205242157\n", + " (4, 4)\t0.24102546274662018\n", + " (3, 1)\t0.6832635402679443\n", + " (1, 3)\t0.6099966764450073\n", + " (3, 0)\t0.83319491147995\n" ] } ], @@ -182,6 +186,10 @@ "execution_count": 4, "id": "ac6f8c6f", "metadata": { + "ExecuteTime": { + "end_time": "2024-01-30T22:19:30.826707866Z", + "start_time": "2024-01-30T22:19:30.825940503Z" + }, "collapsed": false, "jupyter": { "outputs_hidden": false @@ -205,7 +213,7 @@ "\n", "from miplearn.problems.tsp import (\n", " TravelingSalesmanGenerator,\n", - " build_tsp_model,\n", + " build_tsp_model_gurobipy,\n", ")\n", "from miplearn.io import write_pkl_gz\n", "from miplearn.h5 import H5File\n", @@ -231,7 +239,7 @@ "# Solve all instances and collect basic solution information.\n", "# Process at most four instances in parallel.\n", "bc = BasicCollector()\n", - "bc.collect(glob(\"data/tsp/*.pkl.gz\"), build_tsp_model, n_jobs=4)\n", + "bc.collect(glob(\"data/tsp/*.pkl.gz\"), build_tsp_model_gurobipy, n_jobs=4)\n", "\n", "# Read and print some training data for the first instance.\n", "with H5File(\"data/tsp/00000.h5\", \"r\") as h5:\n", @@ -244,6 +252,9 @@ "execution_count": null, "id": "78f0b07a", "metadata": { + "ExecuteTime": { + "start_time": "2024-01-30T22:19:30.826179789Z" + }, "collapsed": false, "jupyter": { "outputs_hidden": false @@ -269,7 +280,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.16" + "version": "3.11.7" } }, "nbformat": 4, diff --git a/docs/guide/features.ipynb b/docs/guide/features.ipynb index d2ae648..81c2629 100644 --- a/docs/guide/features.ipynb +++ b/docs/guide/features.ipynb @@ -51,7 +51,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 1, "id": "ed9a18c8", "metadata": { "collapsed": false, @@ -204,7 +204,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 2, "id": "a1bc38fe", "metadata": { "collapsed": false, @@ -326,7 +326,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.16" + "version": "3.11.7" } }, "nbformat": 4, diff --git a/docs/guide/primal.ipynb b/docs/guide/primal.ipynb index 056992d..26464ce 100644 --- a/docs/guide/primal.ipynb +++ b/docs/guide/primal.ipynb @@ -283,7 +283,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.16" + "version": "3.11.7" } }, "nbformat": 4, diff --git a/docs/guide/problems.ipynb b/docs/guide/problems.ipynb index 24a551e..bf7d9fb 100644 --- a/docs/guide/problems.ipynb +++ b/docs/guide/problems.ipynb @@ -108,11 +108,11 @@ "execution_count": 1, "id": "f14e560c-ef9f-4c48-8467-72d6acce5f9f", "metadata": { - "tags": [], "ExecuteTime": { "end_time": "2023-11-07T16:29:48.409419720Z", "start_time": "2023-11-07T16:29:47.824353556Z" - } + }, + "tags": [] }, "outputs": [ { @@ -131,10 +131,10 @@ "9 [ 8.57 22.77 17.06 16.25 4.14 4. 1.56 22.97 14.09 19.09] 100.79\n", "\n", "Restricted license - for non-production use only - expires 2024-10-28\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 20 rows, 110 columns and 210 nonzeros\n", "Model fingerprint: 0x1ff9913f\n", @@ -159,8 +159,8 @@ "H 0 0 2.0000000 1.27484 36.3% - 0s\n", " 0 0 1.27484 0 4 2.00000 1.27484 36.3% - 0s\n", "\n", - "Explored 1 nodes (38 simplex iterations) in 0.02 seconds (0.00 work units)\n", - "Thread count was 12 (of 12 available processors)\n", + "Explored 1 nodes (38 simplex iterations) in 0.01 seconds (0.00 work units)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", "Solution count 3: 2 4 5 \n", "\n", @@ -323,10 +323,10 @@ "capacities\n", " [1310. 988. 1004. 1269. 1007.]\n", "\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 5 rows, 10 columns and 50 nonzeros\n", "Model fingerprint: 0xaf3ac15e\n", @@ -354,7 +354,7 @@ " Cover: 1\n", "\n", "Explored 1 nodes (4 simplex iterations) in 0.01 seconds (0.00 work units)\n", - "Thread count was 12 (of 12 available processors)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", "Solution count 2: -1279 -804 \n", "No other solutions better than -1279\n", @@ -498,10 +498,10 @@ "demands = [6.12 1.39 2.92 3.66 4.56 7.85 2. 5.14 5.92 0.46]\n", "capacities = [151.89 42.63 16.26 237.22 241.41 202.1 76.15 24.42 171.06 110.04]\n", "\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 21 rows, 110 columns and 220 nonzeros\n", "Model fingerprint: 0x8d8d9346\n", @@ -535,8 +535,8 @@ " 0 0 86.06884 0 15 93.92000 86.06884 8.36% - 0s\n", "* 0 0 0 91.2300000 91.23000 0.00% - 0s\n", "\n", - "Explored 1 nodes (70 simplex iterations) in 0.02 seconds (0.00 work units)\n", - "Thread count was 12 (of 12 available processors)\n", + "Explored 1 nodes (70 simplex iterations) in 0.07 seconds (0.00 work units)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", "Solution count 10: 91.23 93.92 93.98 ... 368.79\n", "\n", @@ -670,10 +670,10 @@ "costs [1044.58 850.13 1014.5 944.83 697.9 971.87 213.49 220.98 70.23\n", " 425.33]\n", "\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 5 rows, 10 columns and 28 nonzeros\n", "Model fingerprint: 0xe5c2d4fa\n", @@ -688,8 +688,8 @@ "Presolve time: 0.00s\n", "Presolve: All rows and columns removed\n", "\n", - "Explored 0 nodes (0 simplex iterations) in 0.01 seconds (0.00 work units)\n", - "Thread count was 1 (of 12 available processors)\n", + "Explored 0 nodes (0 simplex iterations) in 0.00 seconds (0.00 work units)\n", + "Thread count was 1 (of 20 available processors)\n", "\n", "Solution count 1: 213.49 \n", "\n", @@ -786,10 +786,13 @@ "execution_count": 5, "id": "cc797da7", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-07T16:29:48.806917868Z", "start_time": "2023-11-07T16:29:48.781619530Z" + }, + "collapsed": false, + "jupyter": { + "outputs_hidden": false } }, "outputs": [ @@ -806,10 +809,10 @@ "costs [1044.58 850.13 1014.5 944.83 697.9 971.87 213.49 220.98 70.23\n", " 425.33]\n", "\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 5 rows, 10 columns and 28 nonzeros\n", "Model fingerprint: 0x4ee91388\n", @@ -824,8 +827,9 @@ "Presolve time: 0.00s\n", "Presolve: All rows and columns removed\n", "\n", - "Explored 0 nodes (0 simplex iterations) in 0.01 seconds (0.00 work units)\n", - "Thread count was 1 (of 12 available processors)\n", + "Explored 0 nodes (0 simplex iterations) in 0.00 seconds (0.00 work units)\n", + "Thread count was 1 (of 20 available processors)\n", + "\n", "Solution count 2: -1986.37 -1265.56 \n", "No other solutions better than -1986.37\n", "\n", @@ -930,10 +934,10 @@ "weights[1] [ 2.06 96.99 83.24 21.23 18.18 18.34 30.42 52.48 43.19 29.12]\n", "\n", "Set parameter PreCrush to value 1\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 15 rows, 10 columns and 30 nonzeros\n", "Model fingerprint: 0x3240ea4a\n", @@ -957,7 +961,7 @@ " 0 0 infeasible 0 -219.14000 -219.14000 0.00% - 0s\n", "\n", "Explored 1 nodes (5 simplex iterations) in 0.01 seconds (0.00 work units)\n", - "Thread count was 12 (of 12 available processors)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", "Solution count 1: -219.14 \n", "No other solutions better than -219.14\n", @@ -965,7 +969,7 @@ "Optimal solution found (tolerance 1.00e-04)\n", "Best objective -2.191400000000e+02, best bound -2.191400000000e+02, gap 0.0000%\n", "\n", - "User-callback calls 300, time in user-callback 0.00 sec\n" + "User-callback calls 299, time in user-callback 0.00 sec\n" ] } ], @@ -975,7 +979,7 @@ "from scipy.stats import uniform, randint\n", "from miplearn.problems.stab import (\n", " MaxWeightStableSetGenerator,\n", - " build_stab_model,\n", + " build_stab_model_gurobipy,\n", ")\n", "\n", "# Set random seed to make example reproducible\n", @@ -998,7 +1002,7 @@ "print()\n", "\n", "# Load and optimize the first instance\n", - "model = build_stab_model(data[0])\n", + "model = build_stab_model_gurobipy(data[0])\n", "model.optimize()" ] }, @@ -1071,10 +1075,13 @@ "execution_count": 7, "id": "9d0c56c6", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-07T16:29:48.958833448Z", "start_time": "2023-11-07T16:29:48.898121017Z" + }, + "collapsed": false, + "jupyter": { + "outputs_hidden": false } }, "outputs": [ @@ -1107,10 +1114,10 @@ "\n", "Set parameter PreCrush to value 1\n", "Set parameter LazyConstraints to value 1\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 10 rows, 45 columns and 90 nonzeros\n", "Model fingerprint: 0x719675e5\n", @@ -1135,7 +1142,7 @@ " Lazy constraints: 3\n", "\n", "Explored 1 nodes (17 simplex iterations) in 0.01 seconds (0.00 work units)\n", - "Thread count was 12 (of 12 available processors)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", "Solution count 1: 2921 \n", "\n", @@ -1150,7 +1157,10 @@ "import random\n", "import numpy as np\n", "from scipy.stats import uniform, randint\n", - "from miplearn.problems.tsp import TravelingSalesmanGenerator, build_tsp_model\n", + "from miplearn.problems.tsp import (\n", + " TravelingSalesmanGenerator,\n", + " build_tsp_model_gurobipy,\n", + ")\n", "\n", "# Set random seed to make example reproducible\n", "random.seed(42)\n", @@ -1173,7 +1183,7 @@ "print()\n", "\n", "# Load and optimize the first instance\n", - "model = build_tsp_model(data[0])\n", + "model = build_tsp_model_gurobipy(data[0])\n", "model.optimize()" ] }, @@ -1283,10 +1293,13 @@ "execution_count": 8, "id": "6217da7c", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-07T16:29:49.061613905Z", "start_time": "2023-11-07T16:29:48.941857719Z" + }, + "collapsed": false, + "jupyter": { + "outputs_hidden": false } }, "outputs": [ @@ -1320,10 +1333,10 @@ " 828.28 775.18 834.99 959.76 865.72 1193.52 1058.92 985.19 893.92\n", " 962.16 781.88 723.15 639.04 602.4 787.02]\n", "\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 578 rows, 360 columns and 2128 nonzeros\n", "Model fingerprint: 0x4dc1c661\n", @@ -1361,8 +1374,8 @@ " RLT: 1\n", " Relax-and-lift: 7\n", "\n", - "Explored 1 nodes (234 simplex iterations) in 0.04 seconds (0.02 work units)\n", - "Thread count was 12 (of 12 available processors)\n", + "Explored 1 nodes (234 simplex iterations) in 0.03 seconds (0.02 work units)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", "Solution count 5: 364722 368600 374044 ... 440662\n", "\n", @@ -1487,10 +1500,10 @@ "weights[0] [37.45 95.07 73.2 59.87 15.6 15.6 5.81 86.62 60.11 70.81]\n", "weights[1] [ 2.06 96.99 83.24 21.23 18.18 18.34 30.42 52.48 43.19 29.12]\n", "\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 15 rows, 10 columns and 30 nonzeros\n", "Model fingerprint: 0x2d2d1390\n", @@ -1514,7 +1527,7 @@ " 0 0 infeasible 0 301.00000 301.00000 0.00% - 0s\n", "\n", "Explored 1 nodes (8 simplex iterations) in 0.01 seconds (0.00 work units)\n", - "Thread count was 12 (of 12 available processors)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", "Solution count 1: 301 \n", "\n", @@ -1558,13 +1571,16 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "9f12e91f", "metadata": { - "collapsed": false, "ExecuteTime": { "end_time": "2023-11-07T16:29:49.075852252Z", "start_time": "2023-11-07T16:29:49.050243601Z" + }, + "collapsed": false, + "jupyter": { + "outputs_hidden": false } }, "outputs": [], @@ -1587,7 +1603,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.16" + "version": "3.11.7" } }, "nbformat": 4, diff --git a/docs/guide/solvers.ipynb b/docs/guide/solvers.ipynb index e19682d..d89824a 100644 --- a/docs/guide/solvers.ipynb +++ b/docs/guide/solvers.ipynb @@ -57,7 +57,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "id": "92b09b98", "metadata": { "collapsed": false, @@ -70,10 +70,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Restricted license - for non-production use only - expires 2024-10-28\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: AMD Ryzen 9 7950X 16-Core Processor, instruction set [SSE2|AVX|AVX2|AVX512]\n", - "Thread count: 16 physical cores, 32 logical processors, using up to 32 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 10 rows, 45 columns and 90 nonzeros\n", "Model fingerprint: 0x6ddcd141\n", @@ -91,11 +92,12 @@ "\n", "Solved in 15 iterations and 0.00 seconds (0.00 work units)\n", "Optimal objective 2.761000000e+03\n", + "Set parameter PreCrush to value 1\n", "Set parameter LazyConstraints to value 1\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: AMD Ryzen 9 7950X 16-Core Processor, instruction set [SSE2|AVX|AVX2|AVX512]\n", - "Thread count: 16 physical cores, 32 logical processors, using up to 32 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 10 rows, 45 columns and 90 nonzeros\n", "Model fingerprint: 0x74ca3d0a\n", @@ -125,7 +127,7 @@ " Lazy constraints: 3\n", "\n", "Explored 1 nodes (16 simplex iterations) in 0.01 seconds (0.00 work units)\n", - "Thread count was 32 (of 32 available processors)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", "Solution count 1: 2796 \n", "\n", @@ -141,7 +143,7 @@ "{'WS: Count': 1, 'WS: Number of variables set': 41.0}" ] }, - "execution_count": 3, + "execution_count": 1, "metadata": {}, "output_type": "execute_result" } @@ -162,7 +164,7 @@ "from miplearn.io import write_pkl_gz\n", "from miplearn.problems.tsp import (\n", " TravelingSalesmanGenerator,\n", - " build_tsp_model,\n", + " build_tsp_model_gurobipy,\n", ")\n", "from miplearn.solvers.learning import LearningSolver\n", "\n", @@ -189,7 +191,7 @@ "\n", "# Collect training data\n", "bc = BasicCollector()\n", - "bc.collect(train_data, build_tsp_model, n_jobs=4)\n", + "bc.collect(train_data, build_tsp_model_gurobipy, n_jobs=4)\n", "\n", "# Build learning solver\n", "solver = LearningSolver(\n", @@ -211,7 +213,7 @@ "solver.fit(train_data)\n", "\n", "# Solve a test instance\n", - "solver.optimize(test_data[0], build_tsp_model)" + "solver.optimize(test_data[0], build_tsp_model_gurobipy)" ] }, { @@ -239,7 +241,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.12" + "version": "3.11.7" } }, "nbformat": 4, diff --git a/docs/tutorials/getting-started-gurobipy.ipynb b/docs/tutorials/getting-started-gurobipy.ipynb index 36f0d9d..39f757b 100644 --- a/docs/tutorials/getting-started-gurobipy.ipynb +++ b/docs/tutorials/getting-started-gurobipy.ipynb @@ -127,7 +127,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "id": "22a67170-10b4-43d3-8708-014d91141e73", "metadata": { "ExecuteTime": { @@ -163,7 +163,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "id": "2f67032f-0d74-4317-b45c-19da0ec859e9", "metadata": { "ExecuteTime": { @@ -207,7 +207,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "id": "2a896f47", "metadata": { "ExecuteTime": { @@ -221,10 +221,10 @@ "output_type": "stream", "text": [ "Restricted license - for non-production use only - expires 2024-10-28\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 7 rows, 6 columns and 15 nonzeros\n", "Model fingerprint: 0x58dfdd53\n", @@ -250,7 +250,7 @@ "* 0 0 0 1320.0000000 1320.00000 0.00% - 0s\n", "\n", "Explored 1 nodes (5 simplex iterations) in 0.01 seconds (0.00 work units)\n", - "Thread count was 12 (of 12 available processors)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", "Solution count 2: 1320 1400 \n", "\n", @@ -315,7 +315,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "id": "5eb09fab", "metadata": { "ExecuteTime": { @@ -361,7 +361,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "id": "6156752c", "metadata": { "ExecuteTime": { @@ -388,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "id": "7623f002", "metadata": { "ExecuteTime": { @@ -429,7 +429,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "id": "435f7bf8-4b09-4889-b1ec-b7b56e7d8ed2", "metadata": { "ExecuteTime": { @@ -467,7 +467,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "id": "9d13dd50-3dcf-4673-a757-6f44dcc0dedf", "metadata": { "ExecuteTime": { @@ -480,10 +480,10 @@ "name": "stdout", "output_type": "stream", "text": [ - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Model fingerprint: 0xa8b70287\n", @@ -493,7 +493,7 @@ " Bounds range [1e+00, 1e+00]\n", " RHS range [3e+08, 3e+08]\n", "Presolve removed 1000 rows and 500 columns\n", - "Presolve time: 0.00s\n", + "Presolve time: 0.01s\n", "Presolved: 1 rows, 500 columns, 500 nonzeros\n", "\n", "Iteration Objective Primal Inf. Dual Inf. Time\n", @@ -502,13 +502,13 @@ "\n", "Solved in 1 iterations and 0.01 seconds (0.00 work units)\n", "Optimal objective 8.290621916e+09\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", - "Model fingerprint: 0x4ccd7ae3\n", + "Model fingerprint: 0xcf27855a\n", "Variable types: 500 continuous, 500 integer (500 binary)\n", "Coefficient statistics:\n", " Matrix range [1e+00, 2e+06]\n", @@ -516,11 +516,9 @@ " Bounds range [1e+00, 1e+00]\n", " RHS range [3e+08, 3e+08]\n", "\n", - "User MIP start produced solution with objective 8.30129e+09 (0.01s)\n", - "User MIP start produced solution with objective 8.29184e+09 (0.01s)\n", - "User MIP start produced solution with objective 8.29146e+09 (0.01s)\n", - "User MIP start produced solution with objective 8.29146e+09 (0.01s)\n", - "Loaded user MIP start with objective 8.29146e+09\n", + "User MIP start produced solution with objective 8.29153e+09 (0.01s)\n", + "User MIP start produced solution with objective 8.29153e+09 (0.01s)\n", + "Loaded user MIP start with objective 8.29153e+09\n", "\n", "Presolve time: 0.00s\n", "Presolved: 1001 rows, 1000 columns, 2500 nonzeros\n", @@ -532,19 +530,32 @@ " Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time\n", "\n", " 0 0 8.2906e+09 0 1 8.2915e+09 8.2906e+09 0.01% - 0s\n", + " 0 0 8.2907e+09 0 3 8.2915e+09 8.2907e+09 0.01% - 0s\n", + " 0 0 8.2907e+09 0 1 8.2915e+09 8.2907e+09 0.01% - 0s\n", + " 0 0 8.2907e+09 0 2 8.2915e+09 8.2907e+09 0.01% - 0s\n", "\n", "Cutting planes:\n", - " Cover: 1\n", + " Gomory: 1\n", " Flow cover: 2\n", "\n", - "Explored 1 nodes (512 simplex iterations) in 0.07 seconds (0.01 work units)\n", - "Thread count was 12 (of 12 available processors)\n", + "Explored 1 nodes (565 simplex iterations) in 0.03 seconds (0.01 work units)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", - "Solution count 3: 8.29146e+09 8.29184e+09 8.30129e+09 \n", + "Solution count 1: 8.29153e+09 \n", "\n", "Optimal solution found (tolerance 1.00e-04)\n", - "Best objective 8.291459497797e+09, best bound 8.290645029670e+09, gap 0.0098%\n" + "Best objective 8.291528276179e+09, best bound 8.290733258025e+09, gap 0.0096%\n" ] + }, + { + "data": { + "text/plain": [ + "{'WS: Count': 1, 'WS: Number of variables set': 482.0}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -565,7 +576,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "id": "2ff391ed-e855-4228-aa09-a7641d8c2893", "metadata": { "ExecuteTime": { @@ -578,10 +589,10 @@ "name": "stdout", "output_type": "stream", "text": [ - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Model fingerprint: 0xa8b70287\n", @@ -600,10 +611,10 @@ "\n", "Solved in 1 iterations and 0.01 seconds (0.00 work units)\n", "Optimal objective 8.290621916e+09\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Model fingerprint: 0x4cbbf7c7\n", @@ -641,14 +652,24 @@ " Gomory: 2\n", " MIR: 1\n", "\n", - "Explored 1 nodes (1031 simplex iterations) in 0.07 seconds (0.03 work units)\n", - "Thread count was 12 (of 12 available processors)\n", + "Explored 1 nodes (1031 simplex iterations) in 0.15 seconds (0.03 work units)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", "Solution count 4: 8.29147e+09 8.29398e+09 8.29827e+09 9.75713e+09 \n", "\n", "Optimal solution found (tolerance 1.00e-04)\n", "Best objective 8.291465302389e+09, best bound 8.290781665333e+09, gap 0.0082%\n" ] + }, + { + "data": { + "text/plain": [ + "{}" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -679,7 +700,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 10, "id": "67a6cd18", "metadata": { "ExecuteTime": { @@ -692,10 +713,10 @@ "name": "stdout", "output_type": "stream", "text": [ - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Model fingerprint: 0x19042f12\n", @@ -714,13 +735,13 @@ "\n", "Solved in 1 iterations and 0.01 seconds (0.00 work units)\n", "Optimal objective 8.253596777e+09\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", - "Model fingerprint: 0x8ee64638\n", + "Model fingerprint: 0xf97cde91\n", "Variable types: 500 continuous, 500 integer (500 binary)\n", "Coefficient statistics:\n", " Matrix range [1e+00, 2e+06]\n", @@ -728,13 +749,16 @@ " Bounds range [1e+00, 1e+00]\n", " RHS range [3e+08, 3e+08]\n", "\n", - "User MIP start produced solution with objective 8.25814e+09 (0.01s)\n", + "User MIP start produced solution with objective 8.25814e+09 (0.00s)\n", "User MIP start produced solution with objective 8.25512e+09 (0.01s)\n", - "User MIP start produced solution with objective 8.25459e+09 (0.04s)\n", - "User MIP start produced solution with objective 8.25459e+09 (0.04s)\n", + "User MIP start produced solution with objective 8.25483e+09 (0.01s)\n", + "User MIP start produced solution with objective 8.25483e+09 (0.01s)\n", + "User MIP start produced solution with objective 8.25483e+09 (0.01s)\n", + "User MIP start produced solution with objective 8.25459e+09 (0.01s)\n", + "User MIP start produced solution with objective 8.25459e+09 (0.01s)\n", "Loaded user MIP start with objective 8.25459e+09\n", "\n", - "Presolve time: 0.01s\n", + "Presolve time: 0.00s\n", "Presolved: 1001 rows, 1000 columns, 2500 nonzeros\n", "Variable types: 500 continuous, 500 integer (500 binary)\n", "\n", @@ -758,16 +782,16 @@ " StrongCG: 1\n", " Flow cover: 1\n", "\n", - "Explored 1 nodes (575 simplex iterations) in 0.12 seconds (0.01 work units)\n", - "Thread count was 12 (of 12 available processors)\n", + "Explored 1 nodes (575 simplex iterations) in 0.05 seconds (0.01 work units)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", - "Solution count 3: 8.25459e+09 8.25512e+09 8.25814e+09 \n", + "Solution count 4: 8.25459e+09 8.25483e+09 8.25512e+09 8.25814e+09 \n", "\n", "Optimal solution found (tolerance 1.00e-04)\n", "Best objective 8.254590409970e+09, best bound 8.253768093811e+09, gap 0.0100%\n", "obj = 8254590409.969726\n", "x = [1.0, 1.0, 0.0]\n", - "y = [935662.0949263407, 1604270.0218116897, 0.0]\n" + "y = [935662.0949262811, 1604270.0218116897, 0.0]\n" ] } ], @@ -805,7 +829,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.16" + "version": "3.11.7" } }, "nbformat": 4, diff --git a/docs/tutorials/getting-started-pyomo.ipynb b/docs/tutorials/getting-started-pyomo.ipynb index 77e2c28..2618f74 100644 --- a/docs/tutorials/getting-started-pyomo.ipynb +++ b/docs/tutorials/getting-started-pyomo.ipynb @@ -127,7 +127,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "id": "22a67170-10b4-43d3-8708-014d91141e73", "metadata": { "ExecuteTime": { @@ -163,7 +163,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "id": "2f67032f-0d74-4317-b45c-19da0ec859e9", "metadata": { "ExecuteTime": { @@ -213,7 +213,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "id": "2a896f47", "metadata": { "ExecuteTime": { @@ -228,10 +228,10 @@ "text": [ "Restricted license - for non-production use only - expires 2024-10-28\n", "Set parameter QCPDual to value 1\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 7 rows, 6 columns and 15 nonzeros\n", "Model fingerprint: 0x15c7a953\n", @@ -257,7 +257,7 @@ "* 0 0 0 1320.0000000 1320.00000 0.00% - 0s\n", "\n", "Explored 1 nodes (5 simplex iterations) in 0.01 seconds (0.00 work units)\n", - "Thread count was 12 (of 12 available processors)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", "Solution count 2: 1320 1400 \n", "\n", @@ -324,7 +324,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "id": "5eb09fab", "metadata": { "ExecuteTime": { @@ -370,7 +370,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "id": "6156752c", "metadata": { "ExecuteTime": { @@ -397,7 +397,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "id": "7623f002", "metadata": { "ExecuteTime": { @@ -438,7 +438,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "id": "435f7bf8-4b09-4889-b1ec-b7b56e7d8ed2", "metadata": { "ExecuteTime": { @@ -476,7 +476,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "id": "9d13dd50-3dcf-4673-a757-6f44dcc0dedf", "metadata": { "ExecuteTime": { @@ -490,10 +490,10 @@ "output_type": "stream", "text": [ "Set parameter QCPDual to value 1\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Model fingerprint: 0x5e67c6ee\n", @@ -513,13 +513,13 @@ "Solved in 1 iterations and 0.01 seconds (0.00 work units)\n", "Optimal objective 8.290621916e+09\n", "Set parameter QCPDual to value 1\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", - "Model fingerprint: 0xa4a7961e\n", + "Model fingerprint: 0x4a7cfe2b\n", "Variable types: 500 continuous, 500 integer (500 binary)\n", "Coefficient statistics:\n", " Matrix range [1e+00, 2e+06]\n", @@ -527,37 +527,48 @@ " Bounds range [1e+00, 1e+00]\n", " RHS range [3e+08, 3e+08]\n", "\n", - "User MIP start produced solution with objective 8.30129e+09 (0.01s)\n", - "User MIP start produced solution with objective 8.29184e+09 (0.01s)\n", - "User MIP start produced solution with objective 8.29146e+09 (0.01s)\n", - "User MIP start produced solution with objective 8.29146e+09 (0.02s)\n", - "Loaded user MIP start with objective 8.29146e+09\n", + "User MIP start produced solution with objective 8.29153e+09 (0.01s)\n", + "User MIP start produced solution with objective 8.29153e+09 (0.01s)\n", + "Loaded user MIP start with objective 8.29153e+09\n", "\n", - "Presolve time: 0.01s\n", + "Presolve time: 0.00s\n", "Presolved: 1001 rows, 1000 columns, 2500 nonzeros\n", "Variable types: 500 continuous, 500 integer (500 binary)\n", "\n", - "Root relaxation: objective 8.290622e+09, 512 iterations, 0.01 seconds (0.00 work units)\n", + "Root relaxation: objective 8.290622e+09, 512 iterations, 0.00 seconds (0.00 work units)\n", "\n", " Nodes | Current Node | Objective Bounds | Work\n", " Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time\n", "\n", " 0 0 8.2906e+09 0 1 8.2915e+09 8.2906e+09 0.01% - 0s\n", + " 0 0 8.2907e+09 0 3 8.2915e+09 8.2907e+09 0.01% - 0s\n", + " 0 0 8.2907e+09 0 1 8.2915e+09 8.2907e+09 0.01% - 0s\n", + " 0 0 8.2907e+09 0 2 8.2915e+09 8.2907e+09 0.01% - 0s\n", "\n", "Cutting planes:\n", - " Cover: 1\n", + " Gomory: 1\n", " Flow cover: 2\n", "\n", - "Explored 1 nodes (512 simplex iterations) in 0.09 seconds (0.01 work units)\n", - "Thread count was 12 (of 12 available processors)\n", + "Explored 1 nodes (565 simplex iterations) in 0.04 seconds (0.01 work units)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", - "Solution count 3: 8.29146e+09 8.29184e+09 8.30129e+09 \n", + "Solution count 1: 8.29153e+09 \n", "\n", "Optimal solution found (tolerance 1.00e-04)\n", - "Best objective 8.291459497797e+09, best bound 8.290645029670e+09, gap 0.0098%\n", + "Best objective 8.291528276179e+09, best bound 8.290733258025e+09, gap 0.0096%\n", "WARNING: Cannot get reduced costs for MIP.\n", "WARNING: Cannot get duals for MIP.\n" ] + }, + { + "data": { + "text/plain": [ + "{}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -578,7 +589,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "id": "2ff391ed-e855-4228-aa09-a7641d8c2893", "metadata": { "ExecuteTime": { @@ -592,10 +603,10 @@ "output_type": "stream", "text": [ "Set parameter QCPDual to value 1\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Model fingerprint: 0x5e67c6ee\n", @@ -605,7 +616,7 @@ " Bounds range [1e+00, 1e+00]\n", " RHS range [3e+08, 3e+08]\n", "Presolve removed 1000 rows and 500 columns\n", - "Presolve time: 0.01s\n", + "Presolve time: 0.00s\n", "Presolved: 1 rows, 500 columns, 500 nonzeros\n", "\n", "Iteration Objective Primal Inf. Dual Inf. Time\n", @@ -615,10 +626,10 @@ "Solved in 1 iterations and 0.01 seconds (0.00 work units)\n", "Optimal objective 8.290621916e+09\n", "Set parameter QCPDual to value 1\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Model fingerprint: 0x8a0f9587\n", @@ -656,8 +667,8 @@ " Gomory: 2\n", " MIR: 1\n", "\n", - "Explored 1 nodes (1025 simplex iterations) in 0.08 seconds (0.03 work units)\n", - "Thread count was 12 (of 12 available processors)\n", + "Explored 1 nodes (1025 simplex iterations) in 0.12 seconds (0.03 work units)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", "Solution count 4: 8.29147e+09 8.29398e+09 8.29827e+09 9.75713e+09 \n", "\n", @@ -666,6 +677,16 @@ "WARNING: Cannot get reduced costs for MIP.\n", "WARNING: Cannot get duals for MIP.\n" ] + }, + { + "data": { + "text/plain": [ + "{}" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -696,7 +717,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 10, "id": "67a6cd18", "metadata": { "ExecuteTime": { @@ -710,10 +731,10 @@ "output_type": "stream", "text": [ "Set parameter QCPDual to value 1\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Model fingerprint: 0x2dfe4e1c\n", @@ -723,7 +744,7 @@ " Bounds range [1e+00, 1e+00]\n", " RHS range [3e+08, 3e+08]\n", "Presolve removed 1000 rows and 500 columns\n", - "Presolve time: 0.01s\n", + "Presolve time: 0.00s\n", "Presolved: 1 rows, 500 columns, 500 nonzeros\n", "\n", "Iteration Objective Primal Inf. Dual Inf. Time\n", @@ -733,13 +754,13 @@ "Solved in 1 iterations and 0.01 seconds (0.00 work units)\n", "Optimal objective 8.253596777e+09\n", "Set parameter QCPDual to value 1\n", - "Gurobi Optimizer version 10.0.1 build v10.0.1rc0 (linux64)\n", + "Gurobi Optimizer version 10.0.3 build v10.0.3rc0 (linux64)\n", "\n", - "CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", - "Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", + "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n", + "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n", "\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", - "Model fingerprint: 0x20637200\n", + "Model fingerprint: 0x0f0924a1\n", "Variable types: 500 continuous, 500 integer (500 binary)\n", "Coefficient statistics:\n", " Matrix range [1e+00, 2e+06]\n", @@ -747,13 +768,16 @@ " Bounds range [1e+00, 1e+00]\n", " RHS range [3e+08, 3e+08]\n", "\n", - "User MIP start produced solution with objective 8.25814e+09 (0.01s)\n", + "User MIP start produced solution with objective 8.25814e+09 (0.00s)\n", "User MIP start produced solution with objective 8.25512e+09 (0.01s)\n", - "User MIP start produced solution with objective 8.25459e+09 (0.04s)\n", - "User MIP start produced solution with objective 8.25459e+09 (0.04s)\n", + "User MIP start produced solution with objective 8.25483e+09 (0.01s)\n", + "User MIP start produced solution with objective 8.25483e+09 (0.01s)\n", + "User MIP start produced solution with objective 8.25483e+09 (0.01s)\n", + "User MIP start produced solution with objective 8.25459e+09 (0.01s)\n", + "User MIP start produced solution with objective 8.25459e+09 (0.01s)\n", "Loaded user MIP start with objective 8.25459e+09\n", "\n", - "Presolve time: 0.01s\n", + "Presolve time: 0.00s\n", "Presolved: 1001 rows, 1000 columns, 2500 nonzeros\n", "Variable types: 500 continuous, 500 integer (500 binary)\n", "\n", @@ -777,10 +801,10 @@ " StrongCG: 1\n", " Flow cover: 1\n", "\n", - "Explored 1 nodes (575 simplex iterations) in 0.11 seconds (0.01 work units)\n", - "Thread count was 12 (of 12 available processors)\n", + "Explored 1 nodes (575 simplex iterations) in 0.09 seconds (0.01 work units)\n", + "Thread count was 20 (of 20 available processors)\n", "\n", - "Solution count 3: 8.25459e+09 8.25512e+09 8.25814e+09 \n", + "Solution count 4: 8.25459e+09 8.25483e+09 8.25512e+09 8.25814e+09 \n", "\n", "Optimal solution found (tolerance 1.00e-04)\n", "Best objective 8.254590409970e+09, best bound 8.253768093811e+09, gap 0.0100%\n", @@ -788,7 +812,7 @@ "WARNING: Cannot get duals for MIP.\n", "obj = 8254590409.96973\n", " x = [1.0, 1.0, 0.0, 1.0, 1.0]\n", - " y = [935662.0949263407, 1604270.0218116897, 0.0, 1369560.835229226, 602828.5321028307]\n" + " y = [935662.0949262811, 1604270.0218116897, 0.0, 1369560.835229226, 602828.5321028307]\n" ] } ], @@ -826,7 +850,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.13" + "version": "3.11.7" } }, "nbformat": 4, diff --git a/miplearn/problems/__init__.py b/miplearn/problems/__init__.py index 4932a43..bdf9921 100644 --- a/miplearn/problems/__init__.py +++ b/miplearn/problems/__init__.py @@ -1,3 +1,28 @@ # MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization # Copyright (C) 2020-2022, UChicago Argonne, LLC. All rights reserved. # Released under the modified BSD license. See COPYING.md for more details. + +from typing import Any, Optional + +import gurobipy as gp +from pyomo import environ as pe + + +def _gurobipy_set_params(model: gp.Model, params: Optional[dict[str, Any]]) -> None: + assert isinstance(model, gp.Model) + if params is not None: + for (param_name, param_value) in params.items(): + setattr(model.params, param_name, param_value) + + +def _pyomo_set_params( + model: pe.ConcreteModel, + params: Optional[dict[str, Any]], + solver: str, +) -> None: + assert ( + solver == "gurobi_persistent" + ), "setting parameters is only supported with gurobi_persistent" + if solver == "gurobi_persistent" and params is not None: + for (param_name, param_value) in params.items(): + model.solver.set_gurobi_param(param_name, param_value) diff --git a/miplearn/problems/stab.py b/miplearn/problems/stab.py index f21a572..9a5e502 100644 --- a/miplearn/problems/stab.py +++ b/miplearn/problems/stab.py @@ -18,6 +18,8 @@ from networkx import Graph from scipy.stats import uniform, randint from scipy.stats.distributions import rv_frozen +from . import _gurobipy_set_params, _pyomo_set_params + logger = logging.getLogger(__name__) @@ -88,11 +90,10 @@ def build_stab_model_gurobipy( data: Union[str, MaxWeightStableSetData], params: Optional[dict[str, Any]] = None, ) -> GurobiModel: - data = _stab_read(data) model = gp.Model() - if params is not None: - for (param_name, param_value) in params.items(): - setattr(model.params, param_name, param_value) + _gurobipy_set_params(model, params) + + data = _stab_read(data) nodes = list(data.graph.nodes) # Variables and objective function @@ -152,18 +153,14 @@ def build_stab_model_pyomo( for clique in violations: m.add_constr(model.clique_eqs.add(sum(model.x[i] for i in clique) <= 1)) - m = PyomoModel( + pm = PyomoModel( model, solver, cuts_separate=cuts_separate, cuts_enforce=cuts_enforce, ) - - if solver == "gurobi_persistent" and params is not None: - for (param_name, param_value) in params.items(): - m.solver.set_gurobi_param(param_name, param_value) - - return m + _pyomo_set_params(pm, params, solver) + return pm def _stab_read(data: Union[str, MaxWeightStableSetData]) -> MaxWeightStableSetData: diff --git a/miplearn/problems/tsp.py b/miplearn/problems/tsp.py index dd910f4..209d24c 100644 --- a/miplearn/problems/tsp.py +++ b/miplearn/problems/tsp.py @@ -2,20 +2,23 @@ # Copyright (C) 2020-2022, UChicago Argonne, LLC. All rights reserved. # Released under the modified BSD license. See COPYING.md for more details. +import logging from dataclasses import dataclass from typing import List, Tuple, Optional, Any, Union import gurobipy as gp import networkx as nx import numpy as np +import pyomo.environ as pe from gurobipy import quicksum, GRB, tuplelist +from miplearn.io import read_pkl_gz +from miplearn.problems import _gurobipy_set_params, _pyomo_set_params +from miplearn.solvers.gurobi import GurobiModel from scipy.spatial.distance import pdist, squareform from scipy.stats import uniform, randint from scipy.stats.distributions import rv_frozen -import logging -from miplearn.io import read_pkl_gz -from miplearn.solvers.gurobi import GurobiModel +from miplearn.solvers.pyomo import PyomoModel logger = logging.getLogger(__name__) @@ -112,15 +115,18 @@ class TravelingSalesmanGenerator: return n, cities -def build_tsp_model(data: Union[str, TravelingSalesmanData]) -> GurobiModel: - if isinstance(data, str): - data = read_pkl_gz(data) - assert isinstance(data, TravelingSalesmanData) +def build_tsp_model_gurobipy( + data: Union[str, TravelingSalesmanData], + params: Optional[dict[str, Any]] = None, +) -> GurobiModel: + + model = gp.Model() + _gurobipy_set_params(model, params) + data = _tsp_read(data) edges = tuplelist( (i, j) for i in range(data.n_cities) for j in range(i + 1, data.n_cities) ) - model = gp.Model() # Decision variables x = model.addVars(edges, vtype=GRB.BINARY, name="x") @@ -173,3 +179,75 @@ def build_tsp_model(data: Union[str, TravelingSalesmanData]) -> GurobiModel: lazy_separate=lazy_separate, lazy_enforce=lazy_enforce, ) + + +def build_tsp_model_pyomo( + data: Union[str, TravelingSalesmanData], + solver: str = "gurobi_persistent", + params: Optional[dict[str, Any]] = None, +) -> PyomoModel: + + model = pe.ConcreteModel() + data = _tsp_read(data) + + edges = tuplelist( + (i, j) for i in range(data.n_cities) for j in range(i + 1, data.n_cities) + ) + + # Decision variables + model.x = pe.Var(edges, domain=pe.Boolean, name="x") + model.obj = pe.Objective( + expr=sum(model.x[i, j] * data.distances[i, j] for (i, j) in edges) + ) + + # Eq: Must choose two edges adjacent to each node + model.degree_eqs = pe.ConstraintList() + for i in range(data.n_cities): + model.degree_eqs.add( + sum(model.x[min(i, j), max(i, j)] for j in range(data.n_cities) if i != j) + == 2 + ) + + # Eq: Subtour elimination + model.subtour_eqs = pe.ConstraintList() + + def lazy_separate(m: PyomoModel) -> List[Any]: + violations = [] + m.solver.cbGetSolution([model.x[e] for e in edges]) + x_val = {e: model.x[e].value for e in edges} + selected_edges = [e for e in edges if x_val[e] > 0.5] + graph = nx.Graph() + graph.add_edges_from(selected_edges) + for component in list(nx.connected_components(graph)): + if len(component) < data.n_cities: + cut_edges = tuple( + (e[0], e[1]) + for e in edges + if (e[0] in component and e[1] not in component) + or (e[0] not in component and e[1] in component) + ) + violations.append(cut_edges) + return violations + + def lazy_enforce(m: PyomoModel, violations: List[Any]) -> None: + logger.warning(f"Adding {len(violations)} subtour elimination constraints...") + for violation in violations: + m.add_constr( + model.subtour_eqs.add(sum(model.x[e[0], e[1]] for e in violation) >= 2) + ) + + pm = PyomoModel( + model, + solver, + lazy_separate=lazy_separate, + lazy_enforce=lazy_enforce, + ) + _pyomo_set_params(pm, params, solver) + return pm + + +def _tsp_read(data: Union[str, TravelingSalesmanData]) -> TravelingSalesmanData: + if isinstance(data, str): + data = read_pkl_gz(data) + assert isinstance(data, TravelingSalesmanData) + return data diff --git a/miplearn/solvers/pyomo.py b/miplearn/solvers/pyomo.py index f4c83a9..3493f67 100644 --- a/miplearn/solvers/pyomo.py +++ b/miplearn/solvers/pyomo.py @@ -53,7 +53,12 @@ class PyomoModel(AbstractModel): assert ( self.solver_name == "gurobi_persistent" ), "Callbacks are currently only supported on gurobi_persistent" - _gurobi_add_constr(self.solver, self.where, constr) + if self.where in [AbstractModel.WHERE_CUTS, AbstractModel.WHERE_LAZY]: + _gurobi_add_constr(self.solver, self.where, constr) + else: + # outside callbacks, add_constr shouldn't do anything, as the constraint + # has already been added to the ConstraintList object + pass def add_constrs( self, diff --git a/tests/components/lazy/test_mem.py b/tests/components/lazy/test_mem.py index 39ab650..88b2a74 100644 --- a/tests/components/lazy/test_mem.py +++ b/tests/components/lazy/test_mem.py @@ -10,53 +10,60 @@ from sklearn.neighbors import KNeighborsClassifier from miplearn.components.lazy.mem import MemorizingLazyComponent from miplearn.extractors.abstract import FeaturesExtractor -from miplearn.problems.tsp import build_tsp_model +from miplearn.problems.tsp import build_tsp_model_gurobipy, build_tsp_model_pyomo from miplearn.solvers.learning import LearningSolver def test_mem_component( - tsp_h5: List[str], + tsp_gp_h5: List[str], + tsp_pyo_h5: List[str], default_extractor: FeaturesExtractor, ) -> None: - clf = Mock(wraps=DummyClassifier()) - comp = MemorizingLazyComponent(clf=clf, extractor=default_extractor) - comp.fit(tsp_h5) - - # Should call fit method with correct arguments - clf.fit.assert_called() - x, y = clf.fit.call_args.args - assert x.shape == (3, 190) - assert y.tolist() == [ - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0], - [1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0], - [1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1], - ] - - # Should store violations - assert comp.constrs_ is not None - assert comp.n_features_ == 190 - assert comp.n_targets_ == 22 - assert len(comp.constrs_) == 22 - - # Call before-mip - stats: Dict[str, Any] = {} - model = Mock() - comp.before_mip(tsp_h5[0], model, stats) - - # Should call predict with correct args - clf.predict.assert_called() - (x_test,) = clf.predict.call_args.args - assert x_test.shape == (1, 190) + for h5 in [tsp_gp_h5, tsp_pyo_h5]: + clf = Mock(wraps=DummyClassifier()) + comp = MemorizingLazyComponent(clf=clf, extractor=default_extractor) + comp.fit(tsp_gp_h5) + + # Should call fit method with correct arguments + clf.fit.assert_called() + x, y = clf.fit.call_args.args + assert x.shape == (3, 190) + assert y.tolist() == [ + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0], + [1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0], + [1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1], + ] + + # Should store violations + assert comp.constrs_ is not None + assert comp.n_features_ == 190 + assert comp.n_targets_ == 20 + assert len(comp.constrs_) == 20 + + # Call before-mip + stats: Dict[str, Any] = {} + model = Mock() + comp.before_mip(tsp_gp_h5[0], model, stats) + + # Should call predict with correct args + clf.predict.assert_called() + (x_test,) = clf.predict.call_args.args + assert x_test.shape == (1, 190) def test_usage_tsp( - tsp_h5: List[str], + tsp_gp_h5: List[str], + tsp_pyo_h5: List[str], default_extractor: FeaturesExtractor, ) -> None: - # Should not crash - data_filenames = [f.replace(".h5", ".pkl.gz") for f in tsp_h5] - clf = KNeighborsClassifier(n_neighbors=1) - comp = MemorizingLazyComponent(clf=clf, extractor=default_extractor) - solver = LearningSolver(components=[comp]) - solver.fit(data_filenames) - solver.optimize(data_filenames[0], build_tsp_model) + for (h5, build_model) in [ + (tsp_pyo_h5, build_tsp_model_pyomo), + (tsp_gp_h5, build_tsp_model_gurobipy), + ]: + data_filenames = [f.replace(".h5", ".pkl.gz") for f in h5] + clf = KNeighborsClassifier(n_neighbors=1) + comp = MemorizingLazyComponent(clf=clf, extractor=default_extractor) + solver = LearningSolver(components=[comp]) + solver.fit(data_filenames) + stats = solver.optimize(data_filenames[0], build_model) # type: ignore + assert stats["Lazy Constraints: AOT"] > 0 diff --git a/tests/conftest.py b/tests/conftest.py index a664101..9d4847d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -47,8 +47,13 @@ def multiknapsack_h5(request: Any) -> List[str]: @pytest.fixture() -def tsp_h5(request: Any) -> List[str]: - return _h5_fixture("tsp*.h5", request) +def tsp_gp_h5(request: Any) -> List[str]: + return _h5_fixture("tsp-gp*.h5", request) + + +@pytest.fixture() +def tsp_pyo_h5(request: Any) -> List[str]: + return _h5_fixture("tsp-pyo*.h5", request) @pytest.fixture() diff --git a/tests/fixtures/gen_tsp.py b/tests/fixtures/gen_tsp.py index a180caa..09cbf94 100644 --- a/tests/fixtures/gen_tsp.py +++ b/tests/fixtures/gen_tsp.py @@ -5,7 +5,11 @@ from scipy.stats import uniform, randint from miplearn.collectors.basic import BasicCollector from miplearn.io import write_pkl_gz -from miplearn.problems.tsp import TravelingSalesmanGenerator, build_tsp_model +from miplearn.problems.tsp import ( + TravelingSalesmanGenerator, + build_tsp_model_gurobipy, + build_tsp_model_pyomo, +) np.random.seed(42) gen = TravelingSalesmanGenerator( @@ -16,7 +20,27 @@ gen = TravelingSalesmanGenerator( fix_cities=True, round=True, ) + data = gen.generate(3) -data_filenames = write_pkl_gz(data, dirname(__file__), prefix="tsp-n20-") + +params = {"seed": 42, "threads": 1} + +# Gurobipy +data_filenames = write_pkl_gz(data, dirname(__file__), prefix="tsp-gp-n20-") collector = BasicCollector() -collector.collect(data_filenames, build_tsp_model) +collector.collect( + data_filenames, + lambda d: build_tsp_model_gurobipy(d, params=params), + progress=True, + verbose=True, +) + +# Pyomo +data_filenames = write_pkl_gz(data, dirname(__file__), prefix="tsp-pyo-n20-") +collector = BasicCollector() +collector.collect( + data_filenames, + lambda d: build_tsp_model_pyomo(d, params=params), + progress=True, + verbose=True, +) diff --git a/tests/fixtures/tsp-gp-n20-00000.h5 b/tests/fixtures/tsp-gp-n20-00000.h5 new file mode 100644 index 0000000..9313b70 Binary files /dev/null and b/tests/fixtures/tsp-gp-n20-00000.h5 differ diff --git a/tests/fixtures/tsp-gp-n20-00000.mps.gz b/tests/fixtures/tsp-gp-n20-00000.mps.gz new file mode 100644 index 0000000..a2d48c6 Binary files /dev/null and b/tests/fixtures/tsp-gp-n20-00000.mps.gz differ diff --git a/tests/fixtures/tsp-n20-00000.pkl.gz b/tests/fixtures/tsp-gp-n20-00000.pkl.gz similarity index 78% rename from tests/fixtures/tsp-n20-00000.pkl.gz rename to tests/fixtures/tsp-gp-n20-00000.pkl.gz index fcb3322..ef6c835 100644 Binary files a/tests/fixtures/tsp-n20-00000.pkl.gz and b/tests/fixtures/tsp-gp-n20-00000.pkl.gz differ diff --git a/tests/fixtures/tsp-gp-n20-00001.h5 b/tests/fixtures/tsp-gp-n20-00001.h5 new file mode 100644 index 0000000..6ab818d Binary files /dev/null and b/tests/fixtures/tsp-gp-n20-00001.h5 differ diff --git a/tests/fixtures/tsp-gp-n20-00001.mps.gz b/tests/fixtures/tsp-gp-n20-00001.mps.gz new file mode 100644 index 0000000..a12acd7 Binary files /dev/null and b/tests/fixtures/tsp-gp-n20-00001.mps.gz differ diff --git a/tests/fixtures/tsp-n20-00001.pkl.gz b/tests/fixtures/tsp-gp-n20-00001.pkl.gz similarity index 56% rename from tests/fixtures/tsp-n20-00001.pkl.gz rename to tests/fixtures/tsp-gp-n20-00001.pkl.gz index 46b3770..b95efd0 100644 Binary files a/tests/fixtures/tsp-n20-00001.pkl.gz and b/tests/fixtures/tsp-gp-n20-00001.pkl.gz differ diff --git a/tests/fixtures/tsp-gp-n20-00002.h5 b/tests/fixtures/tsp-gp-n20-00002.h5 new file mode 100644 index 0000000..7cafa84 Binary files /dev/null and b/tests/fixtures/tsp-gp-n20-00002.h5 differ diff --git a/tests/fixtures/tsp-gp-n20-00002.mps.gz b/tests/fixtures/tsp-gp-n20-00002.mps.gz new file mode 100644 index 0000000..4a99cce Binary files /dev/null and b/tests/fixtures/tsp-gp-n20-00002.mps.gz differ diff --git a/tests/fixtures/tsp-gp-n20-00002.pkl.gz b/tests/fixtures/tsp-gp-n20-00002.pkl.gz new file mode 100644 index 0000000..313606c Binary files /dev/null and b/tests/fixtures/tsp-gp-n20-00002.pkl.gz differ diff --git a/tests/fixtures/tsp-n20-00000.h5 b/tests/fixtures/tsp-n20-00000.h5 deleted file mode 100644 index 40929bd..0000000 Binary files a/tests/fixtures/tsp-n20-00000.h5 and /dev/null differ diff --git a/tests/fixtures/tsp-n20-00001.h5 b/tests/fixtures/tsp-n20-00001.h5 deleted file mode 100644 index ca98ae9..0000000 Binary files a/tests/fixtures/tsp-n20-00001.h5 and /dev/null differ diff --git a/tests/fixtures/tsp-n20-00001.mps.gz b/tests/fixtures/tsp-n20-00001.mps.gz deleted file mode 100644 index 7f8ad96..0000000 Binary files a/tests/fixtures/tsp-n20-00001.mps.gz and /dev/null differ diff --git a/tests/fixtures/tsp-n20-00002.h5 b/tests/fixtures/tsp-n20-00002.h5 deleted file mode 100644 index 84c534c..0000000 Binary files a/tests/fixtures/tsp-n20-00002.h5 and /dev/null differ diff --git a/tests/fixtures/tsp-n20-00002.mps.gz b/tests/fixtures/tsp-n20-00002.mps.gz deleted file mode 100644 index c82f639..0000000 Binary files a/tests/fixtures/tsp-n20-00002.mps.gz and /dev/null differ diff --git a/tests/fixtures/tsp-n20-00002.pkl.gz b/tests/fixtures/tsp-n20-00002.pkl.gz deleted file mode 100644 index 09992bb..0000000 Binary files a/tests/fixtures/tsp-n20-00002.pkl.gz and /dev/null differ diff --git a/tests/fixtures/tsp-pyo-n20-00000.h5 b/tests/fixtures/tsp-pyo-n20-00000.h5 new file mode 100644 index 0000000..02a0f98 Binary files /dev/null and b/tests/fixtures/tsp-pyo-n20-00000.h5 differ diff --git a/tests/fixtures/tsp-pyo-n20-00000.mps.gz b/tests/fixtures/tsp-pyo-n20-00000.mps.gz new file mode 100644 index 0000000..667cb01 Binary files /dev/null and b/tests/fixtures/tsp-pyo-n20-00000.mps.gz differ diff --git a/tests/fixtures/tsp-pyo-n20-00000.pkl.gz b/tests/fixtures/tsp-pyo-n20-00000.pkl.gz new file mode 100644 index 0000000..d927584 Binary files /dev/null and b/tests/fixtures/tsp-pyo-n20-00000.pkl.gz differ diff --git a/tests/fixtures/tsp-pyo-n20-00001.h5 b/tests/fixtures/tsp-pyo-n20-00001.h5 new file mode 100644 index 0000000..35e07dd Binary files /dev/null and b/tests/fixtures/tsp-pyo-n20-00001.h5 differ diff --git a/tests/fixtures/tsp-pyo-n20-00001.mps.gz b/tests/fixtures/tsp-pyo-n20-00001.mps.gz new file mode 100644 index 0000000..3855d9a Binary files /dev/null and b/tests/fixtures/tsp-pyo-n20-00001.mps.gz differ diff --git a/tests/fixtures/tsp-pyo-n20-00001.pkl.gz b/tests/fixtures/tsp-pyo-n20-00001.pkl.gz new file mode 100644 index 0000000..293e30c Binary files /dev/null and b/tests/fixtures/tsp-pyo-n20-00001.pkl.gz differ diff --git a/tests/fixtures/tsp-pyo-n20-00002.h5 b/tests/fixtures/tsp-pyo-n20-00002.h5 new file mode 100644 index 0000000..06cd880 Binary files /dev/null and b/tests/fixtures/tsp-pyo-n20-00002.h5 differ diff --git a/tests/fixtures/tsp-pyo-n20-00002.mps.gz b/tests/fixtures/tsp-pyo-n20-00002.mps.gz new file mode 100644 index 0000000..1de5170 Binary files /dev/null and b/tests/fixtures/tsp-pyo-n20-00002.mps.gz differ diff --git a/tests/fixtures/tsp-pyo-n20-00002.pkl.gz b/tests/fixtures/tsp-pyo-n20-00002.pkl.gz new file mode 100644 index 0000000..d24be47 Binary files /dev/null and b/tests/fixtures/tsp-pyo-n20-00002.pkl.gz differ diff --git a/tests/problems/test_tsp.py b/tests/problems/test_tsp.py index 46b3a3b..584c55e 100644 --- a/tests/problems/test_tsp.py +++ b/tests/problems/test_tsp.py @@ -6,7 +6,7 @@ import numpy as np from miplearn.problems.tsp import ( TravelingSalesmanData, TravelingSalesmanGenerator, - build_tsp_model, + build_tsp_model_gurobipy, ) from scipy.spatial.distance import pdist, squareform from scipy.stats import randint, uniform @@ -51,7 +51,7 @@ def test_tsp() -> None: ) ), ) - model = build_tsp_model(data) + model = build_tsp_model_gurobipy(data) model.optimize() assert model.inner.getAttr("x", model.inner.getVars()) == [ 1.0,