mirror of
https://github.com/ANL-CEEESA/MIPLearn.git
synced 2025-12-08 18:38:51 -06:00
stab: Implement MaxWeightStableSetPerturber; update tests and docs
This commit is contained in:
@@ -129,14 +129,15 @@
|
|||||||
"8 [ 8.47 21.9 16.58 15.37 3.76 3.91 1.57 20.57 14.76 18.61] 94.58\n",
|
"8 [ 8.47 21.9 16.58 15.37 3.76 3.91 1.57 20.57 14.76 18.61] 94.58\n",
|
||||||
"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 2026-11-23\n",
|
"Set parameter LicenseID to value 389975\n",
|
||||||
"Gurobi Optimizer version 12.0.3 build v12.0.3rc0 (linux64 - \"Ubuntu 24.04.3 LTS\")\n",
|
"Gurobi Optimizer version 13.0.0 build v13.0.0rc1 (linux64 - \"Ubuntu 22.04.5 LTS\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"CPU model: AMD Ryzen 9 3950X 16-Core Processor, instruction set [SSE2|AVX|AVX2]\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",
|
"Thread count: 16 physical cores, 16 logical processors, using up to 16 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 (Min)\n",
|
||||||
"Model fingerprint: 0x1ff9913f\n",
|
"Model fingerprint: 0x1ff9913f\n",
|
||||||
|
"Model has 10 linear objective coefficients\n",
|
||||||
"Variable types: 0 continuous, 110 integer (110 binary)\n",
|
"Variable types: 0 continuous, 110 integer (110 binary)\n",
|
||||||
"Coefficient statistics:\n",
|
"Coefficient statistics:\n",
|
||||||
" Matrix range [1e+00, 1e+02]\n",
|
" Matrix range [1e+00, 1e+02]\n",
|
||||||
@@ -159,15 +160,23 @@
|
|||||||
"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.01 seconds (0.00 work units)\n",
|
"Explored 1 nodes (38 simplex iterations) in 0.00 seconds (0.00 work units)\n",
|
||||||
"Thread count was 32 (of 32 available processors)\n",
|
"Thread count was 16 (of 16 available processors)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Solution count 4: 2 3 4 5 \n",
|
"Solution count 4: 2 3 4 5 \n",
|
||||||
"\n",
|
"\n",
|
||||||
"Optimal solution found (tolerance 1.00e-04)\n",
|
"Optimal solution found (tolerance 1.00e-04)\n",
|
||||||
"Best objective 2.000000000000e+00, best bound 2.000000000000e+00, gap 0.0000%\n",
|
"Best objective 2.000000000000e+00, best bound 2.000000000000e+00, gap 0.0000%\n",
|
||||||
"\n",
|
"\n",
|
||||||
"User-callback calls 148, time in user-callback 0.00 sec\n"
|
"User-callback calls 149, time in user-callback 0.00 sec\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "stderr",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"/home/axavier/Notebooks/[2025-12] Parallel BB Datasets/venv/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
|
||||||
|
" from .autonotebook import tqdm as notebook_tqdm\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -325,13 +334,14 @@
|
|||||||
"capacities\n",
|
"capacities\n",
|
||||||
" [1310. 988. 1004. 1269. 1007.]\n",
|
" [1310. 988. 1004. 1269. 1007.]\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Gurobi Optimizer version 12.0.3 build v12.0.3rc0 (linux64 - \"Ubuntu 24.04.3 LTS\")\n",
|
"Gurobi Optimizer version 13.0.0 build v13.0.0rc1 (linux64 - \"Ubuntu 22.04.5 LTS\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"CPU model: AMD Ryzen 9 3950X 16-Core Processor, instruction set [SSE2|AVX|AVX2]\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",
|
"Thread count: 16 physical cores, 16 logical processors, using up to 16 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 (Min)\n",
|
||||||
"Model fingerprint: 0xaf3ac15e\n",
|
"Model fingerprint: 0xaf3ac15e\n",
|
||||||
|
"Model has 10 linear objective coefficients\n",
|
||||||
"Variable types: 0 continuous, 10 integer (10 binary)\n",
|
"Variable types: 0 continuous, 10 integer (10 binary)\n",
|
||||||
"Coefficient statistics:\n",
|
"Coefficient statistics:\n",
|
||||||
" Matrix range [2e+01, 1e+03]\n",
|
" Matrix range [2e+01, 1e+03]\n",
|
||||||
@@ -355,7 +365,7 @@
|
|||||||
" 0 0 -1428.7265 0 4 -1279.0000 -1428.7265 11.7% - 0s\n",
|
" 0 0 -1428.7265 0 4 -1279.0000 -1428.7265 11.7% - 0s\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 32 (of 32 available processors)\n",
|
"Thread count was 16 (of 16 available processors)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Solution count 3: -1279 -995 -804 \n",
|
"Solution count 3: -1279 -995 -804 \n",
|
||||||
"No other solutions better than -1279\n",
|
"No other solutions better than -1279\n",
|
||||||
@@ -363,7 +373,7 @@
|
|||||||
"Optimal solution found (tolerance 1.00e-04)\n",
|
"Optimal solution found (tolerance 1.00e-04)\n",
|
||||||
"Best objective -1.279000000000e+03, best bound -1.279000000000e+03, gap 0.0000%\n",
|
"Best objective -1.279000000000e+03, best bound -1.279000000000e+03, gap 0.0000%\n",
|
||||||
"\n",
|
"\n",
|
||||||
"User-callback calls 416, time in user-callback 0.00 sec\n"
|
"User-callback calls 418, time in user-callback 0.00 sec\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -501,13 +511,14 @@
|
|||||||
"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 12.0.3 build v12.0.3rc0 (linux64 - \"Ubuntu 24.04.3 LTS\")\n",
|
"Gurobi Optimizer version 13.0.0 build v13.0.0rc1 (linux64 - \"Ubuntu 22.04.5 LTS\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"CPU model: AMD Ryzen 9 3950X 16-Core Processor, instruction set [SSE2|AVX|AVX2]\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",
|
"Thread count: 16 physical cores, 16 logical processors, using up to 16 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 (Min)\n",
|
||||||
"Model fingerprint: 0x8d8d9346\n",
|
"Model fingerprint: 0x8d8d9346\n",
|
||||||
|
"Model has 90 linear objective coefficients\n",
|
||||||
"Variable types: 0 continuous, 110 integer (110 binary)\n",
|
"Variable types: 0 continuous, 110 integer (110 binary)\n",
|
||||||
"Coefficient statistics:\n",
|
"Coefficient statistics:\n",
|
||||||
" Matrix range [5e-01, 2e+02]\n",
|
" Matrix range [5e-01, 2e+02]\n",
|
||||||
@@ -530,21 +541,21 @@
|
|||||||
"H 0 0 153.5000000 0.00000 100% - 0s\n",
|
"H 0 0 153.5000000 0.00000 100% - 0s\n",
|
||||||
"H 0 0 131.7700000 0.00000 100% - 0s\n",
|
"H 0 0 131.7700000 0.00000 100% - 0s\n",
|
||||||
" 0 0 17.14595 0 10 131.77000 17.14595 87.0% - 0s\n",
|
" 0 0 17.14595 0 10 131.77000 17.14595 87.0% - 0s\n",
|
||||||
"H 0 0 115.6500000 17.14595 85.2% - 0s\n",
|
"H 0 0 122.8100000 17.14595 86.0% - 0s\n",
|
||||||
"H 0 0 114.5300000 64.28872 43.9% - 0s\n",
|
"H 0 0 98.3900000 17.14595 82.6% - 0s\n",
|
||||||
"H 0 0 98.3900000 64.28872 34.7% - 0s\n",
|
"H 0 0 92.2900000 64.28872 30.3% - 0s\n",
|
||||||
" 0 0 74.01104 0 15 98.39000 74.01104 24.8% - 0s\n",
|
"H 0 0 91.6700000 64.28872 29.9% - 0s\n",
|
||||||
"H 0 0 91.2300000 74.01104 18.9% - 0s\n",
|
" 0 0 64.28872 0 15 91.67000 64.28872 29.9% - 0s\n",
|
||||||
|
"H 0 0 91.2300000 64.28872 29.5% - 0s\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Cutting planes:\n",
|
"Cutting planes:\n",
|
||||||
" Cover: 16\n",
|
" Cover: 16\n",
|
||||||
" MIR: 1\n",
|
|
||||||
" StrongCG: 1\n",
|
" StrongCG: 1\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Explored 1 nodes (42 simplex iterations) in 0.02 seconds (0.00 work units)\n",
|
"Explored 1 nodes (42 simplex iterations) in 0.01 seconds (0.00 work units)\n",
|
||||||
"Thread count was 32 (of 32 available processors)\n",
|
"Thread count was 16 (of 16 available processors)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Solution count 9: 91.23 98.39 114.53 ... 368.79\n",
|
"Solution count 10: 91.23 91.67 92.29 ... 368.79\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Optimal solution found (tolerance 1.00e-04)\n",
|
"Optimal solution found (tolerance 1.00e-04)\n",
|
||||||
"Best objective 9.123000000000e+01, best bound 9.123000000000e+01, gap 0.0000%\n",
|
"Best objective 9.123000000000e+01, best bound 9.123000000000e+01, gap 0.0000%\n",
|
||||||
@@ -678,13 +689,14 @@
|
|||||||
"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 12.0.3 build v12.0.3rc0 (linux64 - \"Ubuntu 24.04.3 LTS\")\n",
|
"Gurobi Optimizer version 13.0.0 build v13.0.0rc1 (linux64 - \"Ubuntu 22.04.5 LTS\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"CPU model: AMD Ryzen 9 3950X 16-Core Processor, instruction set [SSE2|AVX|AVX2]\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",
|
"Thread count: 16 physical cores, 16 logical processors, using up to 16 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 (Min)\n",
|
||||||
"Model fingerprint: 0xe5c2d4fa\n",
|
"Model fingerprint: 0xe5c2d4fa\n",
|
||||||
|
"Model has 10 linear objective coefficients\n",
|
||||||
"Variable types: 0 continuous, 10 integer (10 binary)\n",
|
"Variable types: 0 continuous, 10 integer (10 binary)\n",
|
||||||
"Coefficient statistics:\n",
|
"Coefficient statistics:\n",
|
||||||
" Matrix range [1e+00, 1e+00]\n",
|
" Matrix range [1e+00, 1e+00]\n",
|
||||||
@@ -696,15 +708,15 @@
|
|||||||
"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 32 available processors)\n",
|
"Thread count was 1 (of 16 available processors)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Solution count 1: 213.49 \n",
|
"Solution count 1: 213.49 \n",
|
||||||
"\n",
|
"\n",
|
||||||
"Optimal solution found (tolerance 1.00e-04)\n",
|
"Optimal solution found (tolerance 1.00e-04)\n",
|
||||||
"Best objective 2.134900000000e+02, best bound 2.134900000000e+02, gap 0.0000%\n",
|
"Best objective 2.134900000000e+02, best bound 2.134900000000e+02, gap 0.0000%\n",
|
||||||
"\n",
|
"\n",
|
||||||
"User-callback calls 183, time in user-callback 0.00 sec\n"
|
"User-callback calls 181, time in user-callback 0.00 sec\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -819,13 +831,14 @@
|
|||||||
"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 12.0.3 build v12.0.3rc0 (linux64 - \"Ubuntu 24.04.3 LTS\")\n",
|
"Gurobi Optimizer version 13.0.0 build v13.0.0rc1 (linux64 - \"Ubuntu 22.04.5 LTS\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"CPU model: AMD Ryzen 9 3950X 16-Core Processor, instruction set [SSE2|AVX|AVX2]\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",
|
"Thread count: 16 physical cores, 16 logical processors, using up to 16 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 (Min)\n",
|
||||||
"Model fingerprint: 0x4ee91388\n",
|
"Model fingerprint: 0x4ee91388\n",
|
||||||
|
"Model has 10 linear objective coefficients\n",
|
||||||
"Variable types: 0 continuous, 10 integer (10 binary)\n",
|
"Variable types: 0 continuous, 10 integer (10 binary)\n",
|
||||||
"Coefficient statistics:\n",
|
"Coefficient statistics:\n",
|
||||||
" Matrix range [1e+00, 1e+00]\n",
|
" Matrix range [1e+00, 1e+00]\n",
|
||||||
@@ -837,8 +850,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 32 available processors)\n",
|
"Thread count was 1 (of 16 available processors)\n",
|
||||||
"\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",
|
||||||
@@ -846,7 +859,7 @@
|
|||||||
"Optimal solution found (tolerance 1.00e-04)\n",
|
"Optimal solution found (tolerance 1.00e-04)\n",
|
||||||
"Best objective -1.986370000000e+03, best bound -1.986370000000e+03, gap 0.0000%\n",
|
"Best objective -1.986370000000e+03, best bound -1.986370000000e+03, gap 0.0000%\n",
|
||||||
"\n",
|
"\n",
|
||||||
"User-callback calls 244, time in user-callback 0.00 sec\n"
|
"User-callback calls 242, time in user-callback 0.00 sec\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -914,14 +927,12 @@
|
|||||||
"id": "ef030168",
|
"id": "ef030168",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"\n",
|
|
||||||
"### Random instance generator\n",
|
"### Random instance generator\n",
|
||||||
"\n",
|
"\n",
|
||||||
"The class [MaxWeightStableSetGenerator][MaxWeightStableSetGenerator] can be used to generate random instances of this problem. The class first samples the user-provided probability distributions `n` and `p` to decide the number of vertices and the density of the graph. Then, it generates a random Erdős-Rényi graph $G_{n,p}$. We recall that, in such a graph, each potential edge is included with probabilty $p$, independently for each other. The class then samples the provided probability distribution `w` to decide the vertex weights.\n",
|
"The class [MaxWeightStableSetGenerator][MaxWeightStableSetGenerator] can be used to generate random instances of this problem. For each instance, the generator creates a new random Erdős-Rényi graph $G_{n,p}$, where $n$ and $p$ are sampled from user-provided probability distributions `n` and `p`. For each vertex, the generator independently samples the weight $w_v$ from the user-provided probability distribution `w`. To create multiple instances with the same graph structure but different vertex weights, you can use [MaxWeightStableSetPerturber][MaxWeightStableSetPerturber]. This class takes an existing instance and generates new instances by applying random scaling factors to the vertex weights while keeping the graph fixed.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"[MaxWeightStableSetGenerator]: ../../api/problems/#miplearn.problems.stab.MaxWeightStableSetGenerator\n",
|
"[MaxWeightStableSetGenerator]: ../../api/problems/#miplearn.problems.stab.MaxWeightStableSetGenerator\n",
|
||||||
"\n",
|
"[MaxWeightStableSetPerturber]: ../../api/problems/#miplearn.problems.stab.MaxWeightStableSetPerturber\n",
|
||||||
"If `fix_graph=True`, then all generated instances have the same random graph. For each instance, the weights are decided by sampling `w`, as described above.\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"### Example"
|
"### Example"
|
||||||
]
|
]
|
||||||
@@ -942,49 +953,50 @@
|
|||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"graph [(0, 2), (0, 4), (0, 8), (1, 2), (1, 3), (1, 5), (1, 6), (1, 9), (2, 5), (2, 9), (3, 6), (3, 7), (6, 9), (7, 8), (8, 9)]\n",
|
"graph [(0, 2), (0, 4), (0, 8), (1, 2), (1, 3), (1, 5), (1, 6), (1, 9), (2, 5), (2, 9), (3, 6), (3, 7), (6, 9), (7, 8), (8, 9)]\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[0] [33.78 94.78 71.97 55.15 14.32 14.33 5.41 82.5 56.7 65.79]\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] [36. 86.89 68.02 56.08 14.75 15.26 5.35 82.41 57.66 64.06]\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Set parameter PreCrush to value 1\n",
|
"Set parameter PreCrush to value 1\n",
|
||||||
"Gurobi Optimizer version 12.0.3 build v12.0.3rc0 (linux64 - \"Ubuntu 24.04.3 LTS\")\n",
|
"Gurobi Optimizer version 13.0.0 build v13.0.0rc1 (linux64 - \"Ubuntu 22.04.5 LTS\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"CPU model: AMD Ryzen 9 3950X 16-Core Processor, instruction set [SSE2|AVX|AVX2]\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",
|
"Thread count: 16 physical cores, 16 logical processors, using up to 16 threads\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Non-default parameters:\n",
|
"Non-default parameters:\n",
|
||||||
"PreCrush 1\n",
|
"PreCrush 1\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 (Min)\n",
|
||||||
"Model fingerprint: 0x3240ea4a\n",
|
"Model fingerprint: 0xc7a32e6d\n",
|
||||||
|
"Model has 10 linear objective coefficients\n",
|
||||||
"Variable types: 0 continuous, 10 integer (10 binary)\n",
|
"Variable types: 0 continuous, 10 integer (10 binary)\n",
|
||||||
"Coefficient statistics:\n",
|
"Coefficient statistics:\n",
|
||||||
" Matrix range [1e+00, 1e+00]\n",
|
" Matrix range [1e+00, 1e+00]\n",
|
||||||
" Objective range [6e+00, 1e+02]\n",
|
" Objective range [5e+00, 9e+01]\n",
|
||||||
" Bounds range [1e+00, 1e+00]\n",
|
" Bounds range [1e+00, 1e+00]\n",
|
||||||
" RHS range [1e+00, 1e+00]\n",
|
" RHS range [1e+00, 1e+00]\n",
|
||||||
"Found heuristic solution: objective -219.1400000\n",
|
"Found heuristic solution: objective -211.0600000\n",
|
||||||
"Presolve removed 7 rows and 2 columns\n",
|
"Presolve removed 7 rows and 2 columns\n",
|
||||||
"Presolve time: 0.00s\n",
|
"Presolve time: 0.00s\n",
|
||||||
"Presolved: 8 rows, 8 columns, 19 nonzeros\n",
|
"Presolved: 8 rows, 8 columns, 19 nonzeros\n",
|
||||||
"Variable types: 0 continuous, 8 integer (8 binary)\n",
|
"Variable types: 0 continuous, 8 integer (8 binary)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Root relaxation: objective -2.205650e+02, 5 iterations, 0.00 seconds (0.00 work units)\n",
|
"Root relaxation: cutoff, 5 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 infeasible 0 -219.14000 -219.14000 0.00% - 0s\n",
|
" 0 0 cutoff 0 -211.06000 -211.06000 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.00 seconds (0.00 work units)\n",
|
||||||
"Thread count was 32 (of 32 available processors)\n",
|
"Thread count was 16 (of 16 available processors)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Solution count 1: -219.14 \n",
|
"Solution count 1: -211.06 \n",
|
||||||
"No other solutions better than -219.14\n",
|
"No other solutions better than -211.06\n",
|
||||||
"\n",
|
"\n",
|
||||||
"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.110600000000e+02, best bound -2.110600000000e+02, gap 0.0000%\n",
|
||||||
"\n",
|
"\n",
|
||||||
"User-callback calls 303, time in user-callback 0.00 sec\n"
|
"User-callback calls 304, time in user-callback 0.00 sec\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -994,6 +1006,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",
|
||||||
|
" MaxWeightStableSetPerturber,\n",
|
||||||
" build_stab_model_gurobipy,\n",
|
" build_stab_model_gurobipy,\n",
|
||||||
")\n",
|
")\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -1001,14 +1014,20 @@
|
|||||||
"random.seed(42)\n",
|
"random.seed(42)\n",
|
||||||
"np.random.seed(42)\n",
|
"np.random.seed(42)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Generate random instances with a fixed 10-node graph,\n",
|
"# Generate a base instance with a 10-node graph,\n",
|
||||||
"# 25% density and random weights in the [0, 100] interval.\n",
|
"# 25% density and random weights in the [0, 100] interval.\n",
|
||||||
"data = MaxWeightStableSetGenerator(\n",
|
"generator = MaxWeightStableSetGenerator(\n",
|
||||||
" w=uniform(loc=0.0, scale=100.0),\n",
|
" w=uniform(loc=0.0, scale=100.0),\n",
|
||||||
" n=randint(low=10, high=11),\n",
|
" n=randint(low=10, high=11),\n",
|
||||||
" p=uniform(loc=0.25, scale=0.0),\n",
|
" p=uniform(loc=0.25, scale=0.0),\n",
|
||||||
" fix_graph=True,\n",
|
")\n",
|
||||||
").generate(10)\n",
|
"base_instance = generator.generate(1)[0]\n",
|
||||||
|
"\n",
|
||||||
|
"# Create multiple instances with the same graph but perturbed weights\n",
|
||||||
|
"perturber = MaxWeightStableSetPerturber(\n",
|
||||||
|
" w_jitter=uniform(loc=0.9, scale=0.1),\n",
|
||||||
|
")\n",
|
||||||
|
"data = perturber.perturb(base_instance, 10)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Print the graph and weights for two instances\n",
|
"# Print the graph and weights for two instances\n",
|
||||||
"print(\"graph\", data[0].graph.edges)\n",
|
"print(\"graph\", data[0].graph.edges)\n",
|
||||||
@@ -1129,17 +1148,18 @@
|
|||||||
"\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 12.0.3 build v12.0.3rc0 (linux64 - \"Ubuntu 24.04.3 LTS\")\n",
|
"Gurobi Optimizer version 13.0.0 build v13.0.0rc1 (linux64 - \"Ubuntu 22.04.5 LTS\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"CPU model: AMD Ryzen 9 3950X 16-Core Processor, instruction set [SSE2|AVX|AVX2]\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",
|
"Thread count: 16 physical cores, 16 logical processors, using up to 16 threads\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Non-default parameters:\n",
|
"Non-default parameters:\n",
|
||||||
"PreCrush 1\n",
|
"PreCrush 1\n",
|
||||||
"LazyConstraints 1\n",
|
"LazyConstraints 1\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 (Min)\n",
|
||||||
"Model fingerprint: 0x719675e5\n",
|
"Model fingerprint: 0x719675e5\n",
|
||||||
|
"Model has 45 linear objective coefficients\n",
|
||||||
"Variable types: 0 continuous, 45 integer (45 binary)\n",
|
"Variable types: 0 continuous, 45 integer (45 binary)\n",
|
||||||
"Coefficient statistics:\n",
|
"Coefficient statistics:\n",
|
||||||
" Matrix range [1e+00, 1e+00]\n",
|
" Matrix range [1e+00, 1e+00]\n",
|
||||||
@@ -1160,15 +1180,15 @@
|
|||||||
"Cutting planes:\n",
|
"Cutting planes:\n",
|
||||||
" 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.00 seconds (0.00 work units)\n",
|
||||||
"Thread count was 32 (of 32 available processors)\n",
|
"Thread count was 16 (of 16 available processors)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Solution count 1: 2921 \n",
|
"Solution count 1: 2921 \n",
|
||||||
"\n",
|
"\n",
|
||||||
"Optimal solution found (tolerance 1.00e-04)\n",
|
"Optimal solution found (tolerance 1.00e-04)\n",
|
||||||
"Best objective 2.921000000000e+03, best bound 2.921000000000e+03, gap 0.0000%\n",
|
"Best objective 2.921000000000e+03, best bound 2.921000000000e+03, gap 0.0000%\n",
|
||||||
"\n",
|
"\n",
|
||||||
"User-callback calls 111, time in user-callback 0.00 sec\n"
|
"User-callback calls 113, time in user-callback 0.00 sec\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -1297,6 +1317,14 @@
|
|||||||
"If `fix_units=True`, then the list of generators (with their respective parameters) is kept the same for all generated instances. If `cost_jitter` and `demand_jitter` are provided, the instances will still have slightly different costs and demands."
|
"If `fix_units=True`, then the list of generators (with their respective parameters) is kept the same for all generated instances. If `cost_jitter` and `demand_jitter` are provided, the instances will still have slightly different costs and demands."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "cf0b884a",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "855b87b4",
|
"id": "855b87b4",
|
||||||
@@ -1307,7 +1335,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 12,
|
"execution_count": 8,
|
||||||
"id": "6217da7c",
|
"id": "6217da7c",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"ExecuteTime": {
|
"ExecuteTime": {
|
||||||
@@ -1348,13 +1376,14 @@
|
|||||||
"demand[1]\n",
|
"demand[1]\n",
|
||||||
" [ 827.37 926.76 1166.64 1128.59 939.17 948.8 950.95 639.5 ]\n",
|
" [ 827.37 926.76 1166.64 1128.59 939.17 948.8 950.95 639.5 ]\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Gurobi Optimizer version 12.0.3 build v12.0.3rc0 (linux64 - \"Ubuntu 24.04.3 LTS\")\n",
|
"Gurobi Optimizer version 13.0.0 build v13.0.0rc1 (linux64 - \"Ubuntu 22.04.5 LTS\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"CPU model: AMD Ryzen 9 3950X 16-Core Processor, instruction set [SSE2|AVX|AVX2]\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",
|
"Thread count: 16 physical cores, 16 logical processors, using up to 16 threads\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Optimize a model with 162 rows, 120 columns and 512 nonzeros\n",
|
"Optimize a model with 162 rows, 120 columns and 512 nonzeros (Min)\n",
|
||||||
"Model fingerprint: 0x1e3651da\n",
|
"Model fingerprint: 0x1e3651da\n",
|
||||||
|
"Model has 120 linear objective coefficients\n",
|
||||||
"Model has 40 quadratic objective terms\n",
|
"Model has 40 quadratic objective terms\n",
|
||||||
"Variable types: 40 continuous, 80 integer (80 binary)\n",
|
"Variable types: 40 continuous, 80 integer (80 binary)\n",
|
||||||
"Coefficient statistics:\n",
|
"Coefficient statistics:\n",
|
||||||
@@ -1382,43 +1411,31 @@
|
|||||||
" 0 0 203097.772 0 4 208079.699 203097.772 2.39% - 0s\n",
|
" 0 0 203097.772 0 4 208079.699 203097.772 2.39% - 0s\n",
|
||||||
" 0 0 203097.772 0 4 208079.699 203097.772 2.39% - 0s\n",
|
" 0 0 203097.772 0 4 208079.699 203097.772 2.39% - 0s\n",
|
||||||
" 0 0 203097.772 0 3 208079.699 203097.772 2.39% - 0s\n",
|
" 0 0 203097.772 0 3 208079.699 203097.772 2.39% - 0s\n",
|
||||||
" 0 0 203097.772 0 3 208079.699 203097.772 2.39% - 0s\n",
|
" 0 0 203097.772 0 2 208079.699 203097.772 2.39% - 0s\n",
|
||||||
" 0 0 203097.772 0 3 208079.699 203097.772 2.39% - 0s\n",
|
" 0 0 204065.874 0 2 208079.699 204065.874 1.93% - 0s\n",
|
||||||
" 0 0 205275.299 0 - 208079.699 205275.299 1.35% - 0s\n",
|
" 0 0 205410.033 0 2 208079.699 205410.033 1.28% - 0s\n",
|
||||||
" 0 0 205777.846 0 2 208079.699 205777.846 1.11% - 0s\n",
|
" 0 0 205413.331 0 2 208079.699 205413.331 1.28% - 0s\n",
|
||||||
" 0 0 205789.407 0 - 208079.699 205789.407 1.10% - 0s\n",
|
"H 0 0 205789.40802 205458.260 0.16% - 0s\n",
|
||||||
" 0 0 postponed 0 208079.699 205789.407 1.10% - 0s\n",
|
"* 0 0 0 205789.40802 205458.260 0.16% - 0s\n",
|
||||||
" 0 0 postponed 0 208079.699 205789.408 1.10% - 0s\n",
|
" 0 0 - 0 205789.408 205787.978 0.00% - 0s\n",
|
||||||
" 0 0 205789.408 0 4 208079.699 205789.408 1.10% - 0s\n",
|
|
||||||
" 0 0 205789.408 0 4 208079.699 205789.408 1.10% - 0s\n",
|
|
||||||
" 0 0 205789.408 0 1 208079.699 205789.408 1.10% - 0s\n",
|
|
||||||
" 0 0 205789.408 0 - 208079.699 205789.408 1.10% - 0s\n",
|
|
||||||
" 0 0 205789.408 0 - 208079.699 205789.408 1.10% - 0s\n",
|
|
||||||
" 0 0 205789.408 0 - 208079.699 205789.408 1.10% - 0s\n",
|
|
||||||
" 0 0 205789.408 0 - 208079.699 205789.408 1.10% - 0s\n",
|
|
||||||
" 0 0 205789.408 0 2 208079.699 205789.408 1.10% - 0s\n",
|
|
||||||
"H 0 0 207525.63560 205789.408 0.84% - 0s\n",
|
|
||||||
" 0 0 205789.408 0 2 207525.636 205789.408 0.84% - 0s\n",
|
|
||||||
" 0 2 205789.408 0 2 207525.636 205789.408 0.84% - 0s\n",
|
|
||||||
"* 9 0 5 205789.40812 205789.408 0.00% 0.0 0s\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"Cutting planes:\n",
|
"Cutting planes:\n",
|
||||||
|
" Gomory: 1\n",
|
||||||
" Cover: 1\n",
|
" Cover: 1\n",
|
||||||
" Implied bound: 6\n",
|
" Implied bound: 1\n",
|
||||||
" MIR: 2\n",
|
" MIR: 7\n",
|
||||||
" Flow cover: 2\n",
|
" Flow cover: 3\n",
|
||||||
" RLT: 2\n",
|
" Relax-and-lift: 1\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Explored 11 nodes (621 simplex iterations) in 0.32 seconds (0.19 work units)\n",
|
"Explored 1 nodes (431 simplex iterations) in 0.02 seconds (0.01 work units)\n",
|
||||||
"Thread count was 32 (of 32 available processors)\n",
|
"Thread count was 16 (of 16 available processors)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Solution count 5: 205789 207526 208080 ... 282371\n",
|
"Solution count 4: 205789 208080 212979 282371 \n",
|
||||||
"No other solutions better than 205789\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"Optimal solution found (tolerance 1.00e-04)\n",
|
"Optimal solution found (tolerance 1.00e-04)\n",
|
||||||
"Best objective 2.057894080889e+05, best bound 2.057894081187e+05, gap 0.0000%\n",
|
"Best objective 2.057894080182e+05, best bound 2.057879779509e+05, gap 0.0007%\n",
|
||||||
"\n",
|
"\n",
|
||||||
"User-callback calls 650, time in user-callback 0.00 sec\n"
|
"User-callback calls 540, time in user-callback 0.00 sec\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -1513,7 +1530,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"### Random instance generator\n",
|
"### Random instance generator\n",
|
||||||
"\n",
|
"\n",
|
||||||
"The class [MinWeightVertexCoverGenerator][MinWeightVertexCoverGenerator] can be used to generate random instances of this problem. The class accepts exactly the same parameters and behaves exactly in the same way as [MaxWeightStableSetGenerator][MaxWeightStableSetGenerator]. See the [stable set section](#Stable-Set) for more details.\n",
|
"The class [MinWeightVertexCoverGenerator][MinWeightVertexCoverGenerator] can be used to generate random instances of this problem. The class accepts the same parameters and behaves in the same way as [MaxWeightStableSetGenerator][MaxWeightStableSetGenerator]. See the [stable set section](#Stable-Set) for more details on the generation process.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"[MinWeightVertexCoverGenerator]: ../../api/problems/#module-miplearn.problems.vertexcover\n",
|
"[MinWeightVertexCoverGenerator]: ../../api/problems/#module-miplearn.problems.vertexcover\n",
|
||||||
"[MaxWeightStableSetGenerator]: ../../api/problems/#miplearn.problems.stab.MaxWeightStableSetGenerator\n",
|
"[MaxWeightStableSetGenerator]: ../../api/problems/#miplearn.problems.stab.MaxWeightStableSetGenerator\n",
|
||||||
@@ -1540,13 +1557,14 @@
|
|||||||
"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 12.0.3 build v12.0.3rc0 (linux64 - \"Ubuntu 24.04.3 LTS\")\n",
|
"Gurobi Optimizer version 13.0.0 build v13.0.0rc1 (linux64 - \"Ubuntu 22.04.5 LTS\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"CPU model: AMD Ryzen 9 3950X 16-Core Processor, instruction set [SSE2|AVX|AVX2]\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",
|
"Thread count: 16 physical cores, 16 logical processors, using up to 16 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 (Min)\n",
|
||||||
"Model fingerprint: 0x2d2d1390\n",
|
"Model fingerprint: 0x2d2d1390\n",
|
||||||
|
"Model has 10 linear objective coefficients\n",
|
||||||
"Variable types: 0 continuous, 10 integer (10 binary)\n",
|
"Variable types: 0 continuous, 10 integer (10 binary)\n",
|
||||||
"Coefficient statistics:\n",
|
"Coefficient statistics:\n",
|
||||||
" Matrix range [1e+00, 1e+00]\n",
|
" Matrix range [1e+00, 1e+00]\n",
|
||||||
@@ -1566,15 +1584,15 @@
|
|||||||
"\n",
|
"\n",
|
||||||
" 0 0 cutoff 0 301.00000 301.00000 0.00% - 0s\n",
|
" 0 0 cutoff 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.00 seconds (0.00 work units)\n",
|
||||||
"Thread count was 32 (of 32 available processors)\n",
|
"Thread count was 16 (of 16 available processors)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Solution count 1: 301 \n",
|
"Solution count 1: 301 \n",
|
||||||
"\n",
|
"\n",
|
||||||
"Optimal solution found (tolerance 1.00e-04)\n",
|
"Optimal solution found (tolerance 1.00e-04)\n",
|
||||||
"Best objective 3.010000000000e+02, best bound 3.010000000000e+02, gap 0.0000%\n",
|
"Best objective 3.010000000000e+02, best bound 3.010000000000e+02, gap 0.0000%\n",
|
||||||
"\n",
|
"\n",
|
||||||
"User-callback calls 333, time in user-callback 0.00 sec\n"
|
"User-callback calls 335, time in user-callback 0.00 sec\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -1591,13 +1609,12 @@
|
|||||||
"random.seed(42)\n",
|
"random.seed(42)\n",
|
||||||
"np.random.seed(42)\n",
|
"np.random.seed(42)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Generate random instances with a fixed 10-node graph,\n",
|
"# Generate random instances with a 10-node graph,\n",
|
||||||
"# 25% density and random weights in the [0, 100] interval.\n",
|
"# 25% density and random weights in the [0, 100] interval.\n",
|
||||||
"data = MinWeightVertexCoverGenerator(\n",
|
"data = MinWeightVertexCoverGenerator(\n",
|
||||||
" w=uniform(loc=0.0, scale=100.0),\n",
|
" w=uniform(loc=0.0, scale=100.0),\n",
|
||||||
" n=randint(low=10, high=11),\n",
|
" n=randint(low=10, high=11),\n",
|
||||||
" p=uniform(loc=0.25, scale=0.0),\n",
|
" p=uniform(loc=0.25, scale=0.0),\n",
|
||||||
" fix_graph=True,\n",
|
|
||||||
").generate(10)\n",
|
").generate(10)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Print the graph and weights for two instances\n",
|
"# Print the graph and weights for two instances\n",
|
||||||
@@ -1686,13 +1703,14 @@
|
|||||||
"weights[0]: [ 1 1 1 -1 -1 -1 -1 -1 -1 -1 1 -1 -1 1 1 -1 -1]\n",
|
"weights[0]: [ 1 1 1 -1 -1 -1 -1 -1 -1 -1 1 -1 -1 1 1 -1 -1]\n",
|
||||||
"weights[1]: [-1 1 -1 -1 -1 1 -1 1 -1 1 -1 1 -1 -1 1 -1 1]\n",
|
"weights[1]: [-1 1 -1 -1 -1 1 -1 1 -1 1 -1 1 -1 -1 1 -1 1]\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Gurobi Optimizer version 12.0.3 build v12.0.3rc0 (linux64 - \"Ubuntu 24.04.3 LTS\")\n",
|
"Gurobi Optimizer version 13.0.0 build v13.0.0rc1 (linux64 - \"Ubuntu 22.04.5 LTS\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"CPU model: AMD Ryzen 9 3950X 16-Core Processor, instruction set [SSE2|AVX|AVX2]\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",
|
"Thread count: 16 physical cores, 16 logical processors, using up to 16 threads\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Optimize a model with 0 rows, 10 columns and 0 nonzeros\n",
|
"Optimize a model with 0 rows, 10 columns and 0 nonzeros (Min)\n",
|
||||||
"Model fingerprint: 0x005f9eac\n",
|
"Model fingerprint: 0x005f9eac\n",
|
||||||
|
"Model has 5 linear objective coefficients\n",
|
||||||
"Model has 17 quadratic objective terms\n",
|
"Model has 17 quadratic objective terms\n",
|
||||||
"Variable types: 0 continuous, 10 integer (10 binary)\n",
|
"Variable types: 0 continuous, 10 integer (10 binary)\n",
|
||||||
"Coefficient statistics:\n",
|
"Coefficient statistics:\n",
|
||||||
@@ -1707,8 +1725,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 32 available processors)\n",
|
"Thread count was 1 (of 16 available processors)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Solution count 2: -3 0 \n",
|
"Solution count 2: -3 0 \n",
|
||||||
"No other solutions better than -3\n",
|
"No other solutions better than -3\n",
|
||||||
@@ -1716,7 +1734,7 @@
|
|||||||
"Optimal solution found (tolerance 1.00e-04)\n",
|
"Optimal solution found (tolerance 1.00e-04)\n",
|
||||||
"Best objective -3.000000000000e+00, best bound -3.000000000000e+00, gap 0.0000%\n",
|
"Best objective -3.000000000000e+00, best bound -3.000000000000e+00, gap 0.0000%\n",
|
||||||
"\n",
|
"\n",
|
||||||
"User-callback calls 86, time in user-callback 0.00 sec\n"
|
"User-callback calls 100, time in user-callback 0.00 sec\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -1770,7 +1788,7 @@
|
|||||||
"name": "python",
|
"name": "python",
|
||||||
"nbconvert_exporter": "python",
|
"nbconvert_exporter": "python",
|
||||||
"pygments_lexer": "ipython3",
|
"pygments_lexer": "ipython3",
|
||||||
"version": "3.12.3"
|
"version": "3.11.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nbformat": 4,
|
"nbformat": 4,
|
||||||
|
|||||||
@@ -32,14 +32,10 @@ class MaxWeightStableSetData:
|
|||||||
class MaxWeightStableSetGenerator:
|
class MaxWeightStableSetGenerator:
|
||||||
"""Random instance generator for the Maximum-Weight Stable Set Problem.
|
"""Random instance generator for the Maximum-Weight Stable Set Problem.
|
||||||
|
|
||||||
The generator has two modes of operation. When `fix_graph=True` is provided,
|
Generates instances by creating a new random Erdős-Rényi graph $G_{n,p}$ for each
|
||||||
one random Erdős-Rényi graph $G_{n,p}$ is generated in the constructor, where $n$
|
instance, where $n$ and $p$ are sampled from user-provided probability distributions
|
||||||
and $p$ are sampled from user-provided probability distributions `n` and `p`. To
|
`n` and `p`. For each instance, the generator independently samples each $w_v$ from
|
||||||
generate each instance, the generator independently samples each $w_v$ from the
|
the user-provided probability distribution `w`.
|
||||||
user-provided probability distribution `w`.
|
|
||||||
|
|
||||||
When `fix_graph=False`, a new random graph is generated for each instance; the
|
|
||||||
remaining parameters are sampled in the same way.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -47,7 +43,6 @@ class MaxWeightStableSetGenerator:
|
|||||||
w: rv_frozen = uniform(loc=10.0, scale=1.0),
|
w: rv_frozen = uniform(loc=10.0, scale=1.0),
|
||||||
n: rv_frozen = randint(low=250, high=251),
|
n: rv_frozen = randint(low=250, high=251),
|
||||||
p: rv_frozen = uniform(loc=0.05, scale=0.0),
|
p: rv_frozen = uniform(loc=0.05, scale=0.0),
|
||||||
fix_graph: bool = True,
|
|
||||||
):
|
):
|
||||||
"""Initialize the problem generator.
|
"""Initialize the problem generator.
|
||||||
|
|
||||||
@@ -66,17 +61,10 @@ class MaxWeightStableSetGenerator:
|
|||||||
self.w = w
|
self.w = w
|
||||||
self.n = n
|
self.n = n
|
||||||
self.p = p
|
self.p = p
|
||||||
self.fix_graph = fix_graph
|
|
||||||
self.graph = None
|
|
||||||
if fix_graph:
|
|
||||||
self.graph = self._generate_graph()
|
|
||||||
|
|
||||||
def generate(self, n_samples: int) -> List[MaxWeightStableSetData]:
|
def generate(self, n_samples: int) -> List[MaxWeightStableSetData]:
|
||||||
def _sample() -> MaxWeightStableSetData:
|
def _sample() -> MaxWeightStableSetData:
|
||||||
if self.graph is not None:
|
graph = self._generate_graph()
|
||||||
graph = self.graph
|
|
||||||
else:
|
|
||||||
graph = self._generate_graph()
|
|
||||||
weights = np.round(self.w.rvs(graph.number_of_nodes()), 2)
|
weights = np.round(self.w.rvs(graph.number_of_nodes()), 2)
|
||||||
return MaxWeightStableSetData(graph, weights)
|
return MaxWeightStableSetData(graph, weights)
|
||||||
|
|
||||||
@@ -86,6 +74,42 @@ class MaxWeightStableSetGenerator:
|
|||||||
return nx.generators.random_graphs.binomial_graph(self.n.rvs(), self.p.rvs())
|
return nx.generators.random_graphs.binomial_graph(self.n.rvs(), self.p.rvs())
|
||||||
|
|
||||||
|
|
||||||
|
class MaxWeightStableSetPerturber:
|
||||||
|
"""Perturbation generator for existing Maximum-Weight Stable Set instances.
|
||||||
|
|
||||||
|
Takes an existing MaxWeightStableSetData instance and generates new instances
|
||||||
|
by applying randomization factors to the existing weights while keeping the graph fixed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
w_jitter: rv_frozen = uniform(loc=0.9, scale=0.2),
|
||||||
|
):
|
||||||
|
"""Initialize the perturbation generator.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
w_jitter: rv_continuous
|
||||||
|
Probability distribution for randomization factors applied to vertex weights.
|
||||||
|
"""
|
||||||
|
assert isinstance(
|
||||||
|
w_jitter, rv_frozen
|
||||||
|
), "w_jitter should be a SciPy probability distribution"
|
||||||
|
self.w_jitter = w_jitter
|
||||||
|
|
||||||
|
def perturb(
|
||||||
|
self,
|
||||||
|
instance: MaxWeightStableSetData,
|
||||||
|
n_samples: int,
|
||||||
|
) -> List[MaxWeightStableSetData]:
|
||||||
|
def _sample() -> MaxWeightStableSetData:
|
||||||
|
jitter_factors = self.w_jitter.rvs(instance.graph.number_of_nodes())
|
||||||
|
weights = np.round(instance.weights * jitter_factors, 2)
|
||||||
|
return MaxWeightStableSetData(instance.graph, weights)
|
||||||
|
|
||||||
|
return [_sample() for _ in range(n_samples)]
|
||||||
|
|
||||||
|
|
||||||
def build_stab_model_gurobipy(
|
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,
|
||||||
|
|||||||
@@ -29,9 +29,8 @@ class MinWeightVertexCoverGenerator:
|
|||||||
w: rv_frozen = uniform(loc=10.0, scale=1.0),
|
w: rv_frozen = uniform(loc=10.0, scale=1.0),
|
||||||
n: rv_frozen = randint(low=250, high=251),
|
n: rv_frozen = randint(low=250, high=251),
|
||||||
p: rv_frozen = uniform(loc=0.05, scale=0.0),
|
p: rv_frozen = uniform(loc=0.05, scale=0.0),
|
||||||
fix_graph: bool = True,
|
|
||||||
):
|
):
|
||||||
self._generator = MaxWeightStableSetGenerator(w, n, p, fix_graph)
|
self._generator = MaxWeightStableSetGenerator(w, n, p)
|
||||||
|
|
||||||
def generate(self, n_samples: int) -> List[MinWeightVertexCoverData]:
|
def generate(self, n_samples: int) -> List[MinWeightVertexCoverData]:
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -28,17 +28,17 @@ def test_mem_component_gp(
|
|||||||
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, 50)
|
assert x.shape == (3, 50)
|
||||||
assert y.shape == (3, 412)
|
assert y.shape == (3, 382)
|
||||||
y = y.tolist()
|
y = y.tolist()
|
||||||
assert y[0][40:50] == [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
assert y[0][40:50] == [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
||||||
assert y[1][40:50] == [1, 1, 0, 1, 1, 1, 1, 1, 1, 1]
|
assert y[1][40:50] == [1, 1, 1, 0, 1, 1, 1, 1, 1, 1]
|
||||||
assert y[2][40:50] == [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
assert y[2][40:50] == [1, 1, 1, 1, 0, 0, 1, 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_ == 50
|
assert comp.n_features_ == 50
|
||||||
assert comp.n_targets_ == 412
|
assert comp.n_targets_ == 382
|
||||||
assert len(comp.constrs_) == 412
|
assert len(comp.constrs_) == 382
|
||||||
|
|
||||||
# Call before-mip
|
# Call before-mip
|
||||||
stats: Dict[str, Any] = {}
|
stats: Dict[str, Any] = {}
|
||||||
@@ -54,7 +54,7 @@ def test_mem_component_gp(
|
|||||||
model.set_cuts.assert_called()
|
model.set_cuts.assert_called()
|
||||||
(cuts_aot_,) = model.set_cuts.call_args.args
|
(cuts_aot_,) = model.set_cuts.call_args.args
|
||||||
assert cuts_aot_ is not None
|
assert cuts_aot_ is not None
|
||||||
assert len(cuts_aot_) == 256
|
assert len(cuts_aot_) == 247
|
||||||
|
|
||||||
|
|
||||||
def test_usage_stab(
|
def test_usage_stab(
|
||||||
|
|||||||
8
tests/fixtures/gen_stab.py
vendored
8
tests/fixtures/gen_stab.py
vendored
@@ -7,6 +7,7 @@ from miplearn.collectors.basic import BasicCollector
|
|||||||
from miplearn.io import write_pkl_gz
|
from miplearn.io import write_pkl_gz
|
||||||
from miplearn.problems.stab import (
|
from miplearn.problems.stab import (
|
||||||
MaxWeightStableSetGenerator,
|
MaxWeightStableSetGenerator,
|
||||||
|
MaxWeightStableSetPerturber,
|
||||||
build_stab_model_gurobipy,
|
build_stab_model_gurobipy,
|
||||||
build_stab_model_pyomo,
|
build_stab_model_pyomo,
|
||||||
)
|
)
|
||||||
@@ -17,9 +18,12 @@ gen = MaxWeightStableSetGenerator(
|
|||||||
w=uniform(10.0, scale=1.0),
|
w=uniform(10.0, scale=1.0),
|
||||||
n=randint(low=50, high=51),
|
n=randint(low=50, high=51),
|
||||||
p=uniform(loc=0.5, scale=0.0),
|
p=uniform(loc=0.5, scale=0.0),
|
||||||
fix_graph=True,
|
|
||||||
)
|
)
|
||||||
data = gen.generate(3)
|
pr = MaxWeightStableSetPerturber(
|
||||||
|
w_jitter=uniform(0.9, scale=0.2),
|
||||||
|
)
|
||||||
|
base_instance = gen.generate(1)[0]
|
||||||
|
data = pr.perturb(base_instance, 3)
|
||||||
|
|
||||||
params = {"seed": 42, "threads": 1}
|
params = {"seed": 42, "threads": 1}
|
||||||
|
|
||||||
|
|||||||
BIN
tests/fixtures/stab-gp-n50-00000.h5
vendored
BIN
tests/fixtures/stab-gp-n50-00000.h5
vendored
Binary file not shown.
BIN
tests/fixtures/stab-gp-n50-00000.mps.gz
vendored
BIN
tests/fixtures/stab-gp-n50-00000.mps.gz
vendored
Binary file not shown.
BIN
tests/fixtures/stab-gp-n50-00000.pkl.gz
vendored
BIN
tests/fixtures/stab-gp-n50-00000.pkl.gz
vendored
Binary file not shown.
BIN
tests/fixtures/stab-gp-n50-00001.h5
vendored
BIN
tests/fixtures/stab-gp-n50-00001.h5
vendored
Binary file not shown.
BIN
tests/fixtures/stab-gp-n50-00001.mps.gz
vendored
BIN
tests/fixtures/stab-gp-n50-00001.mps.gz
vendored
Binary file not shown.
BIN
tests/fixtures/stab-gp-n50-00001.pkl.gz
vendored
BIN
tests/fixtures/stab-gp-n50-00001.pkl.gz
vendored
Binary file not shown.
BIN
tests/fixtures/stab-gp-n50-00002.h5
vendored
BIN
tests/fixtures/stab-gp-n50-00002.h5
vendored
Binary file not shown.
BIN
tests/fixtures/stab-gp-n50-00002.mps.gz
vendored
BIN
tests/fixtures/stab-gp-n50-00002.mps.gz
vendored
Binary file not shown.
BIN
tests/fixtures/stab-gp-n50-00002.pkl.gz
vendored
BIN
tests/fixtures/stab-gp-n50-00002.pkl.gz
vendored
Binary file not shown.
BIN
tests/fixtures/stab-pyo-n50-00000.h5
vendored
BIN
tests/fixtures/stab-pyo-n50-00000.h5
vendored
Binary file not shown.
BIN
tests/fixtures/stab-pyo-n50-00000.mps.gz
vendored
BIN
tests/fixtures/stab-pyo-n50-00000.mps.gz
vendored
Binary file not shown.
BIN
tests/fixtures/stab-pyo-n50-00000.pkl.gz
vendored
BIN
tests/fixtures/stab-pyo-n50-00000.pkl.gz
vendored
Binary file not shown.
BIN
tests/fixtures/stab-pyo-n50-00001.h5
vendored
BIN
tests/fixtures/stab-pyo-n50-00001.h5
vendored
Binary file not shown.
BIN
tests/fixtures/stab-pyo-n50-00001.mps.gz
vendored
BIN
tests/fixtures/stab-pyo-n50-00001.mps.gz
vendored
Binary file not shown.
BIN
tests/fixtures/stab-pyo-n50-00001.pkl.gz
vendored
BIN
tests/fixtures/stab-pyo-n50-00001.pkl.gz
vendored
Binary file not shown.
BIN
tests/fixtures/stab-pyo-n50-00002.h5
vendored
BIN
tests/fixtures/stab-pyo-n50-00002.h5
vendored
Binary file not shown.
BIN
tests/fixtures/stab-pyo-n50-00002.mps.gz
vendored
BIN
tests/fixtures/stab-pyo-n50-00002.mps.gz
vendored
Binary file not shown.
BIN
tests/fixtures/stab-pyo-n50-00002.pkl.gz
vendored
BIN
tests/fixtures/stab-pyo-n50-00002.pkl.gz
vendored
Binary file not shown.
Reference in New Issue
Block a user