Make lazy constr component compatible with Pyomo+Gurobi

dev
Alinson S. Xavier 2 years ago
parent c9eef36c4e
commit 25bbe20748

@ -38,9 +38,13 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 1,
"id": "f906fe9c", "id": "f906fe9c",
"metadata": { "metadata": {
"ExecuteTime": {
"end_time": "2024-01-30T22:19:30.826123021Z",
"start_time": "2024-01-30T22:19:30.766066926Z"
},
"collapsed": false, "collapsed": false,
"jupyter": { "jupyter": {
"outputs_hidden": false "outputs_hidden": false
@ -57,18 +61,18 @@
"x4 = [[0.37454012 0.9507143 0.7319939 ]\n", "x4 = [[0.37454012 0.9507143 0.7319939 ]\n",
" [0.5986585 0.15601864 0.15599452]\n", " [0.5986585 0.15601864 0.15599452]\n",
" [0.05808361 0.8661761 0.601115 ]]\n", " [0.05808361 0.8661761 0.601115 ]]\n",
"x5 = (2, 3)\t0.68030757\n", "x5 = (3, 2)\t0.6803075671195984\n",
" (3, 2)\t0.45049927\n", " (2, 3)\t0.4504992663860321\n",
" (4, 0)\t0.013264962\n", " (0, 4)\t0.013264961540699005\n",
" (0, 2)\t0.94220173\n", " (2, 0)\t0.9422017335891724\n",
" (4, 2)\t0.5632882\n", " (2, 4)\t0.5632882118225098\n",
" (2, 1)\t0.3854165\n", " (1, 2)\t0.38541650772094727\n",
" (1, 1)\t0.015966251\n", " (1, 1)\t0.015966251492500305\n",
" (3, 0)\t0.23089382\n", " (0, 3)\t0.2308938205242157\n",
" (4, 4)\t0.24102546\n", " (4, 4)\t0.24102546274662018\n",
" (1, 3)\t0.68326354\n", " (3, 1)\t0.6832635402679443\n",
" (3, 1)\t0.6099967\n", " (1, 3)\t0.6099966764450073\n",
" (0, 3)\t0.8331949\n" " (3, 0)\t0.83319491147995\n"
] ]
} }
], ],
@ -182,6 +186,10 @@
"execution_count": 4, "execution_count": 4,
"id": "ac6f8c6f", "id": "ac6f8c6f",
"metadata": { "metadata": {
"ExecuteTime": {
"end_time": "2024-01-30T22:19:30.826707866Z",
"start_time": "2024-01-30T22:19:30.825940503Z"
},
"collapsed": false, "collapsed": false,
"jupyter": { "jupyter": {
"outputs_hidden": false "outputs_hidden": false
@ -205,7 +213,7 @@
"\n", "\n",
"from miplearn.problems.tsp import (\n", "from miplearn.problems.tsp import (\n",
" TravelingSalesmanGenerator,\n", " TravelingSalesmanGenerator,\n",
" build_tsp_model,\n", " build_tsp_model_gurobipy,\n",
")\n", ")\n",
"from miplearn.io import write_pkl_gz\n", "from miplearn.io import write_pkl_gz\n",
"from miplearn.h5 import H5File\n", "from miplearn.h5 import H5File\n",
@ -231,7 +239,7 @@
"# Solve all instances and collect basic solution information.\n", "# Solve all instances and collect basic solution information.\n",
"# Process at most four instances in parallel.\n", "# Process at most four instances in parallel.\n",
"bc = BasicCollector()\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", "\n",
"# Read and print some training data for the first instance.\n", "# Read and print some training data for the first instance.\n",
"with H5File(\"data/tsp/00000.h5\", \"r\") as h5:\n", "with H5File(\"data/tsp/00000.h5\", \"r\") as h5:\n",
@ -244,6 +252,9 @@
"execution_count": null, "execution_count": null,
"id": "78f0b07a", "id": "78f0b07a",
"metadata": { "metadata": {
"ExecuteTime": {
"start_time": "2024-01-30T22:19:30.826179789Z"
},
"collapsed": false, "collapsed": false,
"jupyter": { "jupyter": {
"outputs_hidden": false "outputs_hidden": false
@ -269,7 +280,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.9.16" "version": "3.11.7"
} }
}, },
"nbformat": 4, "nbformat": 4,

@ -51,7 +51,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 1,
"id": "ed9a18c8", "id": "ed9a18c8",
"metadata": { "metadata": {
"collapsed": false, "collapsed": false,
@ -204,7 +204,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 2,
"id": "a1bc38fe", "id": "a1bc38fe",
"metadata": { "metadata": {
"collapsed": false, "collapsed": false,
@ -326,7 +326,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.9.16" "version": "3.11.7"
} }
}, },
"nbformat": 4, "nbformat": 4,

@ -283,7 +283,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.9.16" "version": "3.11.7"
} }
}, },
"nbformat": 4, "nbformat": 4,

@ -108,11 +108,11 @@
"execution_count": 1, "execution_count": 1,
"id": "f14e560c-ef9f-4c48-8467-72d6acce5f9f", "id": "f14e560c-ef9f-4c48-8467-72d6acce5f9f",
"metadata": { "metadata": {
"tags": [],
"ExecuteTime": { "ExecuteTime": {
"end_time": "2023-11-07T16:29:48.409419720Z", "end_time": "2023-11-07T16:29:48.409419720Z",
"start_time": "2023-11-07T16:29:47.824353556Z" "start_time": "2023-11-07T16:29:47.824353556Z"
} },
"tags": []
}, },
"outputs": [ "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", "9 [ 8.57 22.77 17.06 16.25 4.14 4. 1.56 22.97 14.09 19.09] 100.79\n",
"\n", "\n",
"Restricted license - for non-production use only - expires 2024-10-28\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 20 rows, 110 columns and 210 nonzeros\n", "Optimize a model with 20 rows, 110 columns and 210 nonzeros\n",
"Model fingerprint: 0x1ff9913f\n", "Model fingerprint: 0x1ff9913f\n",
@ -159,8 +159,8 @@
"H 0 0 2.0000000 1.27484 36.3% - 0s\n", "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", " 0 0 1.27484 0 4 2.00000 1.27484 36.3% - 0s\n",
"\n", "\n",
"Explored 1 nodes (38 simplex iterations) in 0.02 seconds (0.00 work units)\n", "Explored 1 nodes (38 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", "\n",
"Solution count 3: 2 4 5 \n", "Solution count 3: 2 4 5 \n",
"\n", "\n",
@ -323,10 +323,10 @@
"capacities\n", "capacities\n",
" [1310. 988. 1004. 1269. 1007.]\n", " [1310. 988. 1004. 1269. 1007.]\n",
"\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 5 rows, 10 columns and 50 nonzeros\n", "Optimize a model with 5 rows, 10 columns and 50 nonzeros\n",
"Model fingerprint: 0xaf3ac15e\n", "Model fingerprint: 0xaf3ac15e\n",
@ -354,7 +354,7 @@
" Cover: 1\n", " Cover: 1\n",
"\n", "\n",
"Explored 1 nodes (4 simplex iterations) in 0.01 seconds (0.00 work units)\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", "\n",
"Solution count 2: -1279 -804 \n", "Solution count 2: -1279 -804 \n",
"No other solutions better than -1279\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", "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", "capacities = [151.89 42.63 16.26 237.22 241.41 202.1 76.15 24.42 171.06 110.04]\n",
"\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 21 rows, 110 columns and 220 nonzeros\n", "Optimize a model with 21 rows, 110 columns and 220 nonzeros\n",
"Model fingerprint: 0x8d8d9346\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 86.06884 0 15 93.92000 86.06884 8.36% - 0s\n",
"* 0 0 0 91.2300000 91.23000 0.00% - 0s\n", "* 0 0 0 91.2300000 91.23000 0.00% - 0s\n",
"\n", "\n",
"Explored 1 nodes (70 simplex iterations) in 0.02 seconds (0.00 work units)\n", "Explored 1 nodes (70 simplex iterations) in 0.07 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", "\n",
"Solution count 10: 91.23 93.92 93.98 ... 368.79\n", "Solution count 10: 91.23 93.92 93.98 ... 368.79\n",
"\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", "costs [1044.58 850.13 1014.5 944.83 697.9 971.87 213.49 220.98 70.23\n",
" 425.33]\n", " 425.33]\n",
"\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 5 rows, 10 columns and 28 nonzeros\n", "Optimize a model with 5 rows, 10 columns and 28 nonzeros\n",
"Model fingerprint: 0xe5c2d4fa\n", "Model fingerprint: 0xe5c2d4fa\n",
@ -688,8 +688,8 @@
"Presolve time: 0.00s\n", "Presolve time: 0.00s\n",
"Presolve: All rows and columns removed\n", "Presolve: All rows and columns removed\n",
"\n", "\n",
"Explored 0 nodes (0 simplex iterations) in 0.01 seconds (0.00 work units)\n", "Explored 0 nodes (0 simplex iterations) in 0.00 seconds (0.00 work units)\n",
"Thread count was 1 (of 12 available processors)\n", "Thread count was 1 (of 20 available processors)\n",
"\n", "\n",
"Solution count 1: 213.49 \n", "Solution count 1: 213.49 \n",
"\n", "\n",
@ -786,10 +786,13 @@
"execution_count": 5, "execution_count": 5,
"id": "cc797da7", "id": "cc797da7",
"metadata": { "metadata": {
"collapsed": false,
"ExecuteTime": { "ExecuteTime": {
"end_time": "2023-11-07T16:29:48.806917868Z", "end_time": "2023-11-07T16:29:48.806917868Z",
"start_time": "2023-11-07T16:29:48.781619530Z" "start_time": "2023-11-07T16:29:48.781619530Z"
},
"collapsed": false,
"jupyter": {
"outputs_hidden": false
} }
}, },
"outputs": [ "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", "costs [1044.58 850.13 1014.5 944.83 697.9 971.87 213.49 220.98 70.23\n",
" 425.33]\n", " 425.33]\n",
"\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 5 rows, 10 columns and 28 nonzeros\n", "Optimize a model with 5 rows, 10 columns and 28 nonzeros\n",
"Model fingerprint: 0x4ee91388\n", "Model fingerprint: 0x4ee91388\n",
@ -824,8 +827,9 @@
"Presolve time: 0.00s\n", "Presolve time: 0.00s\n",
"Presolve: All rows and columns removed\n", "Presolve: All rows and columns removed\n",
"\n", "\n",
"Explored 0 nodes (0 simplex iterations) in 0.01 seconds (0.00 work units)\n", "Explored 0 nodes (0 simplex iterations) in 0.00 seconds (0.00 work units)\n",
"Thread count was 1 (of 12 available processors)\n", "Thread count was 1 (of 20 available processors)\n",
"\n",
"Solution count 2: -1986.37 -1265.56 \n", "Solution count 2: -1986.37 -1265.56 \n",
"No other solutions better than -1986.37\n", "No other solutions better than -1986.37\n",
"\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", "weights[1] [ 2.06 96.99 83.24 21.23 18.18 18.34 30.42 52.48 43.19 29.12]\n",
"\n", "\n",
"Set parameter PreCrush to value 1\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 15 rows, 10 columns and 30 nonzeros\n", "Optimize a model with 15 rows, 10 columns and 30 nonzeros\n",
"Model fingerprint: 0x3240ea4a\n", "Model fingerprint: 0x3240ea4a\n",
@ -957,7 +961,7 @@
" 0 0 infeasible 0 -219.14000 -219.14000 0.00% - 0s\n", " 0 0 infeasible 0 -219.14000 -219.14000 0.00% - 0s\n",
"\n", "\n",
"Explored 1 nodes (5 simplex iterations) in 0.01 seconds (0.00 work units)\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", "\n",
"Solution count 1: -219.14 \n", "Solution count 1: -219.14 \n",
"No other solutions better than -219.14\n", "No other solutions better than -219.14\n",
@ -965,7 +969,7 @@
"Optimal solution found (tolerance 1.00e-04)\n", "Optimal solution found (tolerance 1.00e-04)\n",
"Best objective -2.191400000000e+02, best bound -2.191400000000e+02, gap 0.0000%\n", "Best objective -2.191400000000e+02, best bound -2.191400000000e+02, gap 0.0000%\n",
"\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 scipy.stats import uniform, randint\n",
"from miplearn.problems.stab import (\n", "from miplearn.problems.stab import (\n",
" MaxWeightStableSetGenerator,\n", " MaxWeightStableSetGenerator,\n",
" build_stab_model,\n", " build_stab_model_gurobipy,\n",
")\n", ")\n",
"\n", "\n",
"# Set random seed to make example reproducible\n", "# Set random seed to make example reproducible\n",
@ -998,7 +1002,7 @@
"print()\n", "print()\n",
"\n", "\n",
"# Load and optimize the first instance\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()" "model.optimize()"
] ]
}, },
@ -1071,10 +1075,13 @@
"execution_count": 7, "execution_count": 7,
"id": "9d0c56c6", "id": "9d0c56c6",
"metadata": { "metadata": {
"collapsed": false,
"ExecuteTime": { "ExecuteTime": {
"end_time": "2023-11-07T16:29:48.958833448Z", "end_time": "2023-11-07T16:29:48.958833448Z",
"start_time": "2023-11-07T16:29:48.898121017Z" "start_time": "2023-11-07T16:29:48.898121017Z"
},
"collapsed": false,
"jupyter": {
"outputs_hidden": false
} }
}, },
"outputs": [ "outputs": [
@ -1107,10 +1114,10 @@
"\n", "\n",
"Set parameter PreCrush to value 1\n", "Set parameter PreCrush to value 1\n",
"Set parameter LazyConstraints 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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 10 rows, 45 columns and 90 nonzeros\n", "Optimize a model with 10 rows, 45 columns and 90 nonzeros\n",
"Model fingerprint: 0x719675e5\n", "Model fingerprint: 0x719675e5\n",
@ -1135,7 +1142,7 @@
" Lazy constraints: 3\n", " Lazy constraints: 3\n",
"\n", "\n",
"Explored 1 nodes (17 simplex iterations) in 0.01 seconds (0.00 work units)\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", "\n",
"Solution count 1: 2921 \n", "Solution count 1: 2921 \n",
"\n", "\n",
@ -1150,7 +1157,10 @@
"import random\n", "import random\n",
"import numpy as np\n", "import numpy as np\n",
"from scipy.stats import uniform, randint\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", "\n",
"# Set random seed to make example reproducible\n", "# Set random seed to make example reproducible\n",
"random.seed(42)\n", "random.seed(42)\n",
@ -1173,7 +1183,7 @@
"print()\n", "print()\n",
"\n", "\n",
"# Load and optimize the first instance\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()" "model.optimize()"
] ]
}, },
@ -1283,10 +1293,13 @@
"execution_count": 8, "execution_count": 8,
"id": "6217da7c", "id": "6217da7c",
"metadata": { "metadata": {
"collapsed": false,
"ExecuteTime": { "ExecuteTime": {
"end_time": "2023-11-07T16:29:49.061613905Z", "end_time": "2023-11-07T16:29:49.061613905Z",
"start_time": "2023-11-07T16:29:48.941857719Z" "start_time": "2023-11-07T16:29:48.941857719Z"
},
"collapsed": false,
"jupyter": {
"outputs_hidden": false
} }
}, },
"outputs": [ "outputs": [
@ -1320,10 +1333,10 @@
" 828.28 775.18 834.99 959.76 865.72 1193.52 1058.92 985.19 893.92\n", " 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", " 962.16 781.88 723.15 639.04 602.4 787.02]\n",
"\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 578 rows, 360 columns and 2128 nonzeros\n", "Optimize a model with 578 rows, 360 columns and 2128 nonzeros\n",
"Model fingerprint: 0x4dc1c661\n", "Model fingerprint: 0x4dc1c661\n",
@ -1361,8 +1374,8 @@
" RLT: 1\n", " RLT: 1\n",
" Relax-and-lift: 7\n", " Relax-and-lift: 7\n",
"\n", "\n",
"Explored 1 nodes (234 simplex iterations) in 0.04 seconds (0.02 work units)\n", "Explored 1 nodes (234 simplex iterations) in 0.03 seconds (0.02 work units)\n",
"Thread count was 12 (of 12 available processors)\n", "Thread count was 20 (of 20 available processors)\n",
"\n", "\n",
"Solution count 5: 364722 368600 374044 ... 440662\n", "Solution count 5: 364722 368600 374044 ... 440662\n",
"\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[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", "weights[1] [ 2.06 96.99 83.24 21.23 18.18 18.34 30.42 52.48 43.19 29.12]\n",
"\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 15 rows, 10 columns and 30 nonzeros\n", "Optimize a model with 15 rows, 10 columns and 30 nonzeros\n",
"Model fingerprint: 0x2d2d1390\n", "Model fingerprint: 0x2d2d1390\n",
@ -1514,7 +1527,7 @@
" 0 0 infeasible 0 301.00000 301.00000 0.00% - 0s\n", " 0 0 infeasible 0 301.00000 301.00000 0.00% - 0s\n",
"\n", "\n",
"Explored 1 nodes (8 simplex iterations) in 0.01 seconds (0.00 work units)\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", "\n",
"Solution count 1: 301 \n", "Solution count 1: 301 \n",
"\n", "\n",
@ -1558,13 +1571,16 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": null,
"id": "9f12e91f", "id": "9f12e91f",
"metadata": { "metadata": {
"collapsed": false,
"ExecuteTime": { "ExecuteTime": {
"end_time": "2023-11-07T16:29:49.075852252Z", "end_time": "2023-11-07T16:29:49.075852252Z",
"start_time": "2023-11-07T16:29:49.050243601Z" "start_time": "2023-11-07T16:29:49.050243601Z"
},
"collapsed": false,
"jupyter": {
"outputs_hidden": false
} }
}, },
"outputs": [], "outputs": [],
@ -1587,7 +1603,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.9.16" "version": "3.11.7"
} }
}, },
"nbformat": 4, "nbformat": 4,

@ -57,7 +57,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 1,
"id": "92b09b98", "id": "92b09b98",
"metadata": { "metadata": {
"collapsed": false, "collapsed": false,
@ -70,10 +70,11 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "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", "\n",
"CPU model: AMD Ryzen 9 7950X 16-Core Processor, instruction set [SSE2|AVX|AVX2|AVX512]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 16 physical cores, 32 logical processors, using up to 32 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 10 rows, 45 columns and 90 nonzeros\n", "Optimize a model with 10 rows, 45 columns and 90 nonzeros\n",
"Model fingerprint: 0x6ddcd141\n", "Model fingerprint: 0x6ddcd141\n",
@ -91,11 +92,12 @@
"\n", "\n",
"Solved in 15 iterations and 0.00 seconds (0.00 work units)\n", "Solved in 15 iterations and 0.00 seconds (0.00 work units)\n",
"Optimal objective 2.761000000e+03\n", "Optimal objective 2.761000000e+03\n",
"Set parameter PreCrush to value 1\n",
"Set parameter LazyConstraints 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", "\n",
"CPU model: AMD Ryzen 9 7950X 16-Core Processor, instruction set [SSE2|AVX|AVX2|AVX512]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 16 physical cores, 32 logical processors, using up to 32 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 10 rows, 45 columns and 90 nonzeros\n", "Optimize a model with 10 rows, 45 columns and 90 nonzeros\n",
"Model fingerprint: 0x74ca3d0a\n", "Model fingerprint: 0x74ca3d0a\n",
@ -125,7 +127,7 @@
" Lazy constraints: 3\n", " Lazy constraints: 3\n",
"\n", "\n",
"Explored 1 nodes (16 simplex iterations) in 0.01 seconds (0.00 work units)\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", "\n",
"Solution count 1: 2796 \n", "Solution count 1: 2796 \n",
"\n", "\n",
@ -141,7 +143,7 @@
"{'WS: Count': 1, 'WS: Number of variables set': 41.0}" "{'WS: Count': 1, 'WS: Number of variables set': 41.0}"
] ]
}, },
"execution_count": 3, "execution_count": 1,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -162,7 +164,7 @@
"from miplearn.io import write_pkl_gz\n", "from miplearn.io import write_pkl_gz\n",
"from miplearn.problems.tsp import (\n", "from miplearn.problems.tsp import (\n",
" TravelingSalesmanGenerator,\n", " TravelingSalesmanGenerator,\n",
" build_tsp_model,\n", " build_tsp_model_gurobipy,\n",
")\n", ")\n",
"from miplearn.solvers.learning import LearningSolver\n", "from miplearn.solvers.learning import LearningSolver\n",
"\n", "\n",
@ -189,7 +191,7 @@
"\n", "\n",
"# Collect training data\n", "# Collect training data\n",
"bc = BasicCollector()\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", "\n",
"# Build learning solver\n", "# Build learning solver\n",
"solver = LearningSolver(\n", "solver = LearningSolver(\n",
@ -211,7 +213,7 @@
"solver.fit(train_data)\n", "solver.fit(train_data)\n",
"\n", "\n",
"# Solve a test instance\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", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.9.12" "version": "3.11.7"
} }
}, },
"nbformat": 4, "nbformat": 4,

@ -127,7 +127,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 1,
"id": "22a67170-10b4-43d3-8708-014d91141e73", "id": "22a67170-10b4-43d3-8708-014d91141e73",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -163,7 +163,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 2,
"id": "2f67032f-0d74-4317-b45c-19da0ec859e9", "id": "2f67032f-0d74-4317-b45c-19da0ec859e9",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -207,7 +207,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 3,
"id": "2a896f47", "id": "2a896f47",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -221,10 +221,10 @@
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Restricted license - for non-production use only - expires 2024-10-28\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 7 rows, 6 columns and 15 nonzeros\n", "Optimize a model with 7 rows, 6 columns and 15 nonzeros\n",
"Model fingerprint: 0x58dfdd53\n", "Model fingerprint: 0x58dfdd53\n",
@ -250,7 +250,7 @@
"* 0 0 0 1320.0000000 1320.00000 0.00% - 0s\n", "* 0 0 0 1320.0000000 1320.00000 0.00% - 0s\n",
"\n", "\n",
"Explored 1 nodes (5 simplex iterations) in 0.01 seconds (0.00 work units)\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", "\n",
"Solution count 2: 1320 1400 \n", "Solution count 2: 1320 1400 \n",
"\n", "\n",
@ -315,7 +315,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 4,
"id": "5eb09fab", "id": "5eb09fab",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -361,7 +361,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": 5,
"id": "6156752c", "id": "6156752c",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -388,7 +388,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 6,
"id": "7623f002", "id": "7623f002",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -429,7 +429,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 7,
"id": "435f7bf8-4b09-4889-b1ec-b7b56e7d8ed2", "id": "435f7bf8-4b09-4889-b1ec-b7b56e7d8ed2",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -467,7 +467,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 10, "execution_count": 8,
"id": "9d13dd50-3dcf-4673-a757-6f44dcc0dedf", "id": "9d13dd50-3dcf-4673-a757-6f44dcc0dedf",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -480,10 +480,10 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n",
"Model fingerprint: 0xa8b70287\n", "Model fingerprint: 0xa8b70287\n",
@ -493,7 +493,7 @@
" Bounds range [1e+00, 1e+00]\n", " Bounds range [1e+00, 1e+00]\n",
" RHS range [3e+08, 3e+08]\n", " RHS range [3e+08, 3e+08]\n",
"Presolve removed 1000 rows and 500 columns\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", "Presolved: 1 rows, 500 columns, 500 nonzeros\n",
"\n", "\n",
"Iteration Objective Primal Inf. Dual Inf. Time\n", "Iteration Objective Primal Inf. Dual Inf. Time\n",
@ -502,13 +502,13 @@
"\n", "\n",
"Solved in 1 iterations and 0.01 seconds (0.00 work units)\n", "Solved in 1 iterations and 0.01 seconds (0.00 work units)\n",
"Optimal objective 8.290621916e+09\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\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", "Variable types: 500 continuous, 500 integer (500 binary)\n",
"Coefficient statistics:\n", "Coefficient statistics:\n",
" Matrix range [1e+00, 2e+06]\n", " Matrix range [1e+00, 2e+06]\n",
@ -516,11 +516,9 @@
" Bounds range [1e+00, 1e+00]\n", " Bounds range [1e+00, 1e+00]\n",
" RHS range [3e+08, 3e+08]\n", " RHS range [3e+08, 3e+08]\n",
"\n", "\n",
"User MIP start produced solution with objective 8.30129e+09 (0.01s)\n", "User MIP start produced solution with objective 8.29153e+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.29153e+09 (0.01s)\n",
"User MIP start produced solution with objective 8.29146e+09 (0.01s)\n", "Loaded user MIP start with objective 8.29153e+09\n",
"User MIP start produced solution with objective 8.29146e+09 (0.01s)\n",
"Loaded user MIP start with objective 8.29146e+09\n",
"\n", "\n",
"Presolve time: 0.00s\n", "Presolve time: 0.00s\n",
"Presolved: 1001 rows, 1000 columns, 2500 nonzeros\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", " Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time\n",
"\n", "\n",
" 0 0 8.2906e+09 0 1 8.2915e+09 8.2906e+09 0.01% - 0s\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", "\n",
"Cutting planes:\n", "Cutting planes:\n",
" Cover: 1\n", " Gomory: 1\n",
" Flow cover: 2\n", " Flow cover: 2\n",
"\n", "\n",
"Explored 1 nodes (512 simplex iterations) in 0.07 seconds (0.01 work units)\n", "Explored 1 nodes (565 simplex iterations) in 0.03 seconds (0.01 work units)\n",
"Thread count was 12 (of 12 available processors)\n", "Thread count was 20 (of 20 available processors)\n",
"\n", "\n",
"Solution count 3: 8.29146e+09 8.29184e+09 8.30129e+09 \n", "Solution count 1: 8.29153e+09 \n",
"\n", "\n",
"Optimal solution found (tolerance 1.00e-04)\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": [ "source": [
@ -565,7 +576,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 11, "execution_count": 9,
"id": "2ff391ed-e855-4228-aa09-a7641d8c2893", "id": "2ff391ed-e855-4228-aa09-a7641d8c2893",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -578,10 +589,10 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n",
"Model fingerprint: 0xa8b70287\n", "Model fingerprint: 0xa8b70287\n",
@ -600,10 +611,10 @@
"\n", "\n",
"Solved in 1 iterations and 0.01 seconds (0.00 work units)\n", "Solved in 1 iterations and 0.01 seconds (0.00 work units)\n",
"Optimal objective 8.290621916e+09\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n",
"Model fingerprint: 0x4cbbf7c7\n", "Model fingerprint: 0x4cbbf7c7\n",
@ -641,14 +652,24 @@
" Gomory: 2\n", " Gomory: 2\n",
" MIR: 1\n", " MIR: 1\n",
"\n", "\n",
"Explored 1 nodes (1031 simplex iterations) in 0.07 seconds (0.03 work units)\n", "Explored 1 nodes (1031 simplex iterations) in 0.15 seconds (0.03 work units)\n",
"Thread count was 12 (of 12 available processors)\n", "Thread count was 20 (of 20 available processors)\n",
"\n", "\n",
"Solution count 4: 8.29147e+09 8.29398e+09 8.29827e+09 9.75713e+09 \n", "Solution count 4: 8.29147e+09 8.29398e+09 8.29827e+09 9.75713e+09 \n",
"\n", "\n",
"Optimal solution found (tolerance 1.00e-04)\n", "Optimal solution found (tolerance 1.00e-04)\n",
"Best objective 8.291465302389e+09, best bound 8.290781665333e+09, gap 0.0082%\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": [ "source": [
@ -679,7 +700,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 12, "execution_count": 10,
"id": "67a6cd18", "id": "67a6cd18",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -692,10 +713,10 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n",
"Model fingerprint: 0x19042f12\n", "Model fingerprint: 0x19042f12\n",
@ -714,13 +735,13 @@
"\n", "\n",
"Solved in 1 iterations and 0.01 seconds (0.00 work units)\n", "Solved in 1 iterations and 0.01 seconds (0.00 work units)\n",
"Optimal objective 8.253596777e+09\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\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", "Variable types: 500 continuous, 500 integer (500 binary)\n",
"Coefficient statistics:\n", "Coefficient statistics:\n",
" Matrix range [1e+00, 2e+06]\n", " Matrix range [1e+00, 2e+06]\n",
@ -728,13 +749,16 @@
" Bounds range [1e+00, 1e+00]\n", " Bounds range [1e+00, 1e+00]\n",
" RHS range [3e+08, 3e+08]\n", " RHS range [3e+08, 3e+08]\n",
"\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.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.25483e+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.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", "Loaded user MIP start with objective 8.25459e+09\n",
"\n", "\n",
"Presolve time: 0.01s\n", "Presolve time: 0.00s\n",
"Presolved: 1001 rows, 1000 columns, 2500 nonzeros\n", "Presolved: 1001 rows, 1000 columns, 2500 nonzeros\n",
"Variable types: 500 continuous, 500 integer (500 binary)\n", "Variable types: 500 continuous, 500 integer (500 binary)\n",
"\n", "\n",
@ -758,16 +782,16 @@
" StrongCG: 1\n", " StrongCG: 1\n",
" Flow cover: 1\n", " Flow cover: 1\n",
"\n", "\n",
"Explored 1 nodes (575 simplex iterations) in 0.12 seconds (0.01 work units)\n", "Explored 1 nodes (575 simplex iterations) in 0.05 seconds (0.01 work units)\n",
"Thread count was 12 (of 12 available processors)\n", "Thread count was 20 (of 20 available processors)\n",
"\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", "\n",
"Optimal solution found (tolerance 1.00e-04)\n", "Optimal solution found (tolerance 1.00e-04)\n",
"Best objective 8.254590409970e+09, best bound 8.253768093811e+09, gap 0.0100%\n", "Best objective 8.254590409970e+09, best bound 8.253768093811e+09, gap 0.0100%\n",
"obj = 8254590409.969726\n", "obj = 8254590409.969726\n",
"x = [1.0, 1.0, 0.0]\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", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.9.16" "version": "3.11.7"
} }
}, },
"nbformat": 4, "nbformat": 4,

@ -127,7 +127,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 1,
"id": "22a67170-10b4-43d3-8708-014d91141e73", "id": "22a67170-10b4-43d3-8708-014d91141e73",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -163,7 +163,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 2,
"id": "2f67032f-0d74-4317-b45c-19da0ec859e9", "id": "2f67032f-0d74-4317-b45c-19da0ec859e9",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -213,7 +213,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 3,
"id": "2a896f47", "id": "2a896f47",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -228,10 +228,10 @@
"text": [ "text": [
"Restricted license - for non-production use only - expires 2024-10-28\n", "Restricted license - for non-production use only - expires 2024-10-28\n",
"Set parameter QCPDual to value 1\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 7 rows, 6 columns and 15 nonzeros\n", "Optimize a model with 7 rows, 6 columns and 15 nonzeros\n",
"Model fingerprint: 0x15c7a953\n", "Model fingerprint: 0x15c7a953\n",
@ -257,7 +257,7 @@
"* 0 0 0 1320.0000000 1320.00000 0.00% - 0s\n", "* 0 0 0 1320.0000000 1320.00000 0.00% - 0s\n",
"\n", "\n",
"Explored 1 nodes (5 simplex iterations) in 0.01 seconds (0.00 work units)\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", "\n",
"Solution count 2: 1320 1400 \n", "Solution count 2: 1320 1400 \n",
"\n", "\n",
@ -324,7 +324,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 4,
"id": "5eb09fab", "id": "5eb09fab",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -370,7 +370,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": 5,
"id": "6156752c", "id": "6156752c",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -397,7 +397,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 6,
"id": "7623f002", "id": "7623f002",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -438,7 +438,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 7,
"id": "435f7bf8-4b09-4889-b1ec-b7b56e7d8ed2", "id": "435f7bf8-4b09-4889-b1ec-b7b56e7d8ed2",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -476,7 +476,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 10, "execution_count": 8,
"id": "9d13dd50-3dcf-4673-a757-6f44dcc0dedf", "id": "9d13dd50-3dcf-4673-a757-6f44dcc0dedf",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -490,10 +490,10 @@
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Set parameter QCPDual to value 1\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n",
"Model fingerprint: 0x5e67c6ee\n", "Model fingerprint: 0x5e67c6ee\n",
@ -513,13 +513,13 @@
"Solved in 1 iterations and 0.01 seconds (0.00 work units)\n", "Solved in 1 iterations and 0.01 seconds (0.00 work units)\n",
"Optimal objective 8.290621916e+09\n", "Optimal objective 8.290621916e+09\n",
"Set parameter QCPDual to value 1\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\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", "Variable types: 500 continuous, 500 integer (500 binary)\n",
"Coefficient statistics:\n", "Coefficient statistics:\n",
" Matrix range [1e+00, 2e+06]\n", " Matrix range [1e+00, 2e+06]\n",
@ -527,37 +527,48 @@
" Bounds range [1e+00, 1e+00]\n", " Bounds range [1e+00, 1e+00]\n",
" RHS range [3e+08, 3e+08]\n", " RHS range [3e+08, 3e+08]\n",
"\n", "\n",
"User MIP start produced solution with objective 8.30129e+09 (0.01s)\n", "User MIP start produced solution with objective 8.29153e+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.29153e+09 (0.01s)\n",
"User MIP start produced solution with objective 8.29146e+09 (0.01s)\n", "Loaded user MIP start with objective 8.29153e+09\n",
"User MIP start produced solution with objective 8.29146e+09 (0.02s)\n",
"Loaded user MIP start with objective 8.29146e+09\n",
"\n", "\n",
"Presolve time: 0.01s\n", "Presolve time: 0.00s\n",
"Presolved: 1001 rows, 1000 columns, 2500 nonzeros\n", "Presolved: 1001 rows, 1000 columns, 2500 nonzeros\n",
"Variable types: 500 continuous, 500 integer (500 binary)\n", "Variable types: 500 continuous, 500 integer (500 binary)\n",
"\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", "\n",
" Nodes | Current Node | Objective Bounds | Work\n", " Nodes | Current Node | Objective Bounds | Work\n",
" Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time\n", " Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time\n",
"\n", "\n",
" 0 0 8.2906e+09 0 1 8.2915e+09 8.2906e+09 0.01% - 0s\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", "\n",
"Cutting planes:\n", "Cutting planes:\n",
" Cover: 1\n", " Gomory: 1\n",
" Flow cover: 2\n", " Flow cover: 2\n",
"\n", "\n",
"Explored 1 nodes (512 simplex iterations) in 0.09 seconds (0.01 work units)\n", "Explored 1 nodes (565 simplex iterations) in 0.04 seconds (0.01 work units)\n",
"Thread count was 12 (of 12 available processors)\n", "Thread count was 20 (of 20 available processors)\n",
"\n", "\n",
"Solution count 3: 8.29146e+09 8.29184e+09 8.30129e+09 \n", "Solution count 1: 8.29153e+09 \n",
"\n", "\n",
"Optimal solution found (tolerance 1.00e-04)\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 reduced costs for MIP.\n",
"WARNING: Cannot get duals for MIP.\n" "WARNING: Cannot get duals for MIP.\n"
] ]
},
{
"data": {
"text/plain": [
"{}"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
} }
], ],
"source": [ "source": [
@ -578,7 +589,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 11, "execution_count": 9,
"id": "2ff391ed-e855-4228-aa09-a7641d8c2893", "id": "2ff391ed-e855-4228-aa09-a7641d8c2893",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -592,10 +603,10 @@
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Set parameter QCPDual to value 1\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n",
"Model fingerprint: 0x5e67c6ee\n", "Model fingerprint: 0x5e67c6ee\n",
@ -605,7 +616,7 @@
" Bounds range [1e+00, 1e+00]\n", " Bounds range [1e+00, 1e+00]\n",
" RHS range [3e+08, 3e+08]\n", " RHS range [3e+08, 3e+08]\n",
"Presolve removed 1000 rows and 500 columns\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", "Presolved: 1 rows, 500 columns, 500 nonzeros\n",
"\n", "\n",
"Iteration Objective Primal Inf. Dual Inf. Time\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", "Solved in 1 iterations and 0.01 seconds (0.00 work units)\n",
"Optimal objective 8.290621916e+09\n", "Optimal objective 8.290621916e+09\n",
"Set parameter QCPDual to value 1\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n",
"Model fingerprint: 0x8a0f9587\n", "Model fingerprint: 0x8a0f9587\n",
@ -656,8 +667,8 @@
" Gomory: 2\n", " Gomory: 2\n",
" MIR: 1\n", " MIR: 1\n",
"\n", "\n",
"Explored 1 nodes (1025 simplex iterations) in 0.08 seconds (0.03 work units)\n", "Explored 1 nodes (1025 simplex iterations) in 0.12 seconds (0.03 work units)\n",
"Thread count was 12 (of 12 available processors)\n", "Thread count was 20 (of 20 available processors)\n",
"\n", "\n",
"Solution count 4: 8.29147e+09 8.29398e+09 8.29827e+09 9.75713e+09 \n", "Solution count 4: 8.29147e+09 8.29398e+09 8.29827e+09 9.75713e+09 \n",
"\n", "\n",
@ -666,6 +677,16 @@
"WARNING: Cannot get reduced costs for MIP.\n", "WARNING: Cannot get reduced costs for MIP.\n",
"WARNING: Cannot get duals for MIP.\n" "WARNING: Cannot get duals for MIP.\n"
] ]
},
{
"data": {
"text/plain": [
"{}"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
} }
], ],
"source": [ "source": [
@ -696,7 +717,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 12, "execution_count": 10,
"id": "67a6cd18", "id": "67a6cd18",
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
@ -710,10 +731,10 @@
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Set parameter QCPDual to value 1\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n", "Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\n",
"Model fingerprint: 0x2dfe4e1c\n", "Model fingerprint: 0x2dfe4e1c\n",
@ -723,7 +744,7 @@
" Bounds range [1e+00, 1e+00]\n", " Bounds range [1e+00, 1e+00]\n",
" RHS range [3e+08, 3e+08]\n", " RHS range [3e+08, 3e+08]\n",
"Presolve removed 1000 rows and 500 columns\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", "Presolved: 1 rows, 500 columns, 500 nonzeros\n",
"\n", "\n",
"Iteration Objective Primal Inf. Dual Inf. Time\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", "Solved in 1 iterations and 0.01 seconds (0.00 work units)\n",
"Optimal objective 8.253596777e+09\n", "Optimal objective 8.253596777e+09\n",
"Set parameter QCPDual to value 1\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", "\n",
"CPU model: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, instruction set [SSE2|AVX|AVX2]\n", "CPU model: 13th Gen Intel(R) Core(TM) i7-13800H, instruction set [SSE2|AVX|AVX2]\n",
"Thread count: 6 physical cores, 12 logical processors, using up to 12 threads\n", "Thread count: 10 physical cores, 20 logical processors, using up to 20 threads\n",
"\n", "\n",
"Optimize a model with 1001 rows, 1000 columns and 2500 nonzeros\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", "Variable types: 500 continuous, 500 integer (500 binary)\n",
"Coefficient statistics:\n", "Coefficient statistics:\n",
" Matrix range [1e+00, 2e+06]\n", " Matrix range [1e+00, 2e+06]\n",
@ -747,13 +768,16 @@
" Bounds range [1e+00, 1e+00]\n", " Bounds range [1e+00, 1e+00]\n",
" RHS range [3e+08, 3e+08]\n", " RHS range [3e+08, 3e+08]\n",
"\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.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.25483e+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.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", "Loaded user MIP start with objective 8.25459e+09\n",
"\n", "\n",
"Presolve time: 0.01s\n", "Presolve time: 0.00s\n",
"Presolved: 1001 rows, 1000 columns, 2500 nonzeros\n", "Presolved: 1001 rows, 1000 columns, 2500 nonzeros\n",
"Variable types: 500 continuous, 500 integer (500 binary)\n", "Variable types: 500 continuous, 500 integer (500 binary)\n",
"\n", "\n",
@ -777,10 +801,10 @@
" StrongCG: 1\n", " StrongCG: 1\n",
" Flow cover: 1\n", " Flow cover: 1\n",
"\n", "\n",
"Explored 1 nodes (575 simplex iterations) in 0.11 seconds (0.01 work units)\n", "Explored 1 nodes (575 simplex iterations) in 0.09 seconds (0.01 work units)\n",
"Thread count was 12 (of 12 available processors)\n", "Thread count was 20 (of 20 available processors)\n",
"\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", "\n",
"Optimal solution found (tolerance 1.00e-04)\n", "Optimal solution found (tolerance 1.00e-04)\n",
"Best objective 8.254590409970e+09, best bound 8.253768093811e+09, gap 0.0100%\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", "WARNING: Cannot get duals for MIP.\n",
"obj = 8254590409.96973\n", "obj = 8254590409.96973\n",
" x = [1.0, 1.0, 0.0, 1.0, 1.0]\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", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.8.13" "version": "3.11.7"
} }
}, },
"nbformat": 4, "nbformat": 4,

@ -1,3 +1,28 @@
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization # MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
# Copyright (C) 2020-2022, UChicago Argonne, LLC. All rights reserved. # Copyright (C) 2020-2022, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details. # 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)

@ -18,6 +18,8 @@ from networkx import Graph
from scipy.stats import uniform, randint from scipy.stats import uniform, randint
from scipy.stats.distributions import rv_frozen from scipy.stats.distributions import rv_frozen
from . import _gurobipy_set_params, _pyomo_set_params
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -88,11 +90,10 @@ def build_stab_model_gurobipy(
data: Union[str, MaxWeightStableSetData], data: Union[str, MaxWeightStableSetData],
params: Optional[dict[str, Any]] = None, params: Optional[dict[str, Any]] = None,
) -> GurobiModel: ) -> GurobiModel:
data = _stab_read(data)
model = gp.Model() model = gp.Model()
if params is not None: _gurobipy_set_params(model, params)
for (param_name, param_value) in params.items():
setattr(model.params, param_name, param_value) data = _stab_read(data)
nodes = list(data.graph.nodes) nodes = list(data.graph.nodes)
# Variables and objective function # Variables and objective function
@ -152,18 +153,14 @@ def build_stab_model_pyomo(
for clique in violations: for clique in violations:
m.add_constr(model.clique_eqs.add(sum(model.x[i] for i in clique) <= 1)) m.add_constr(model.clique_eqs.add(sum(model.x[i] for i in clique) <= 1))
m = PyomoModel( pm = PyomoModel(
model, model,
solver, solver,
cuts_separate=cuts_separate, cuts_separate=cuts_separate,
cuts_enforce=cuts_enforce, cuts_enforce=cuts_enforce,
) )
_pyomo_set_params(pm, params, solver)
if solver == "gurobi_persistent" and params is not None: return pm
for (param_name, param_value) in params.items():
m.solver.set_gurobi_param(param_name, param_value)
return m
def _stab_read(data: Union[str, MaxWeightStableSetData]) -> MaxWeightStableSetData: def _stab_read(data: Union[str, MaxWeightStableSetData]) -> MaxWeightStableSetData:

@ -2,20 +2,23 @@
# Copyright (C) 2020-2022, UChicago Argonne, LLC. All rights reserved. # Copyright (C) 2020-2022, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details. # Released under the modified BSD license. See COPYING.md for more details.
import logging
from dataclasses import dataclass from dataclasses import dataclass
from typing import List, Tuple, Optional, Any, Union from typing import List, Tuple, Optional, Any, Union
import gurobipy as gp import gurobipy as gp
import networkx as nx import networkx as nx
import numpy as np import numpy as np
import pyomo.environ as pe
from gurobipy import quicksum, GRB, tuplelist 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.spatial.distance import pdist, squareform
from scipy.stats import uniform, randint from scipy.stats import uniform, randint
from scipy.stats.distributions import rv_frozen from scipy.stats.distributions import rv_frozen
import logging
from miplearn.io import read_pkl_gz from miplearn.solvers.pyomo import PyomoModel
from miplearn.solvers.gurobi import GurobiModel
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -112,15 +115,18 @@ class TravelingSalesmanGenerator:
return n, cities return n, cities
def build_tsp_model(data: Union[str, TravelingSalesmanData]) -> GurobiModel: def build_tsp_model_gurobipy(
if isinstance(data, str): data: Union[str, TravelingSalesmanData],
data = read_pkl_gz(data) params: Optional[dict[str, Any]] = None,
assert isinstance(data, TravelingSalesmanData) ) -> GurobiModel:
model = gp.Model()
_gurobipy_set_params(model, params)
data = _tsp_read(data)
edges = tuplelist( edges = tuplelist(
(i, j) for i in range(data.n_cities) for j in range(i + 1, data.n_cities) (i, j) for i in range(data.n_cities) for j in range(i + 1, data.n_cities)
) )
model = gp.Model()
# Decision variables # Decision variables
x = model.addVars(edges, vtype=GRB.BINARY, name="x") 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_separate=lazy_separate,
lazy_enforce=lazy_enforce, 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

@ -53,7 +53,12 @@ class PyomoModel(AbstractModel):
assert ( assert (
self.solver_name == "gurobi_persistent" self.solver_name == "gurobi_persistent"
), "Callbacks are currently only supported on gurobi_persistent" ), "Callbacks are currently only supported on gurobi_persistent"
if self.where in [AbstractModel.WHERE_CUTS, AbstractModel.WHERE_LAZY]:
_gurobi_add_constr(self.solver, self.where, constr) _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( def add_constrs(
self, self,

@ -10,38 +10,40 @@ from sklearn.neighbors import KNeighborsClassifier
from miplearn.components.lazy.mem import MemorizingLazyComponent from miplearn.components.lazy.mem import MemorizingLazyComponent
from miplearn.extractors.abstract import FeaturesExtractor 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 from miplearn.solvers.learning import LearningSolver
def test_mem_component( def test_mem_component(
tsp_h5: List[str], tsp_gp_h5: List[str],
tsp_pyo_h5: List[str],
default_extractor: FeaturesExtractor, default_extractor: FeaturesExtractor,
) -> None: ) -> None:
for h5 in [tsp_gp_h5, tsp_pyo_h5]:
clf = Mock(wraps=DummyClassifier()) clf = Mock(wraps=DummyClassifier())
comp = MemorizingLazyComponent(clf=clf, extractor=default_extractor) comp = MemorizingLazyComponent(clf=clf, extractor=default_extractor)
comp.fit(tsp_h5) comp.fit(tsp_gp_h5)
# Should call fit method with correct arguments # Should call fit method with correct arguments
clf.fit.assert_called() clf.fit.assert_called()
x, y = clf.fit.call_args.args x, y = clf.fit.call_args.args
assert x.shape == (3, 190) assert x.shape == (3, 190)
assert y.tolist() == [ 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, 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, 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], [1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1],
] ]
# Should store violations # Should store violations
assert comp.constrs_ is not None assert comp.constrs_ is not None
assert comp.n_features_ == 190 assert comp.n_features_ == 190
assert comp.n_targets_ == 22 assert comp.n_targets_ == 20
assert len(comp.constrs_) == 22 assert len(comp.constrs_) == 20
# Call before-mip # Call before-mip
stats: Dict[str, Any] = {} stats: Dict[str, Any] = {}
model = Mock() model = Mock()
comp.before_mip(tsp_h5[0], model, stats) comp.before_mip(tsp_gp_h5[0], model, stats)
# Should call predict with correct args # Should call predict with correct args
clf.predict.assert_called() clf.predict.assert_called()
@ -50,13 +52,18 @@ def test_mem_component(
def test_usage_tsp( def test_usage_tsp(
tsp_h5: List[str], tsp_gp_h5: List[str],
tsp_pyo_h5: List[str],
default_extractor: FeaturesExtractor, default_extractor: FeaturesExtractor,
) -> None: ) -> None:
# Should not crash for (h5, build_model) in [
data_filenames = [f.replace(".h5", ".pkl.gz") for f in tsp_h5] (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) clf = KNeighborsClassifier(n_neighbors=1)
comp = MemorizingLazyComponent(clf=clf, extractor=default_extractor) comp = MemorizingLazyComponent(clf=clf, extractor=default_extractor)
solver = LearningSolver(components=[comp]) solver = LearningSolver(components=[comp])
solver.fit(data_filenames) solver.fit(data_filenames)
solver.optimize(data_filenames[0], build_tsp_model) stats = solver.optimize(data_filenames[0], build_model) # type: ignore
assert stats["Lazy Constraints: AOT"] > 0

@ -47,8 +47,13 @@ def multiknapsack_h5(request: Any) -> List[str]:
@pytest.fixture() @pytest.fixture()
def tsp_h5(request: Any) -> List[str]: def tsp_gp_h5(request: Any) -> List[str]:
return _h5_fixture("tsp*.h5", request) 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() @pytest.fixture()

@ -5,7 +5,11 @@ from scipy.stats import uniform, randint
from miplearn.collectors.basic import BasicCollector from miplearn.collectors.basic import BasicCollector
from miplearn.io import write_pkl_gz 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) np.random.seed(42)
gen = TravelingSalesmanGenerator( gen = TravelingSalesmanGenerator(
@ -16,7 +20,27 @@ gen = TravelingSalesmanGenerator(
fix_cities=True, fix_cities=True,
round=True, round=True,
) )
data = gen.generate(3) 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 = 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,
)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -6,7 +6,7 @@ import numpy as np
from miplearn.problems.tsp import ( from miplearn.problems.tsp import (
TravelingSalesmanData, TravelingSalesmanData,
TravelingSalesmanGenerator, TravelingSalesmanGenerator,
build_tsp_model, build_tsp_model_gurobipy,
) )
from scipy.spatial.distance import pdist, squareform from scipy.spatial.distance import pdist, squareform
from scipy.stats import randint, uniform 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() model.optimize()
assert model.inner.getAttr("x", model.inner.getVars()) == [ assert model.inner.getAttr("x", model.inner.getVars()) == [
1.0, 1.0,

Loading…
Cancel
Save