diff --git a/docs/notebooks/neuralnet/graph_neural_network_formulation.ipynb b/docs/notebooks/neuralnet/graph_neural_network_formulation.ipynb index e30c94f7..a2e76575 100644 --- a/docs/notebooks/neuralnet/graph_neural_network_formulation.ipynb +++ b/docs/notebooks/neuralnet/graph_neural_network_formulation.ipynb @@ -39,31 +39,30 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pyomo.environ as pyo\n", "import torch\n", - "from torch.nn import Linear, ReLU, Sigmoid\n", - "from torch_geometric.nn import GCNConv, Sequential, global_mean_pool\n", - "\n", "from omlt import OmltBlock\n", "from omlt.io.torch_geometric import gnn_with_fixed_graph\n", + "from torch.nn import Linear, ReLU, Sigmoid\n", + "from torch_geometric.nn import GCNConv, Sequential, global_mean_pool\n", "\n", "\n", "def GCN_Sequential(activation, pooling):\n", " torch.manual_seed(123)\n", " return Sequential(\n", - " \"x, edge_index\",\n", + " \"x, edge_index, batch\",\n", " [\n", " (GCNConv(2, 4), \"x, edge_index -> x\"),\n", " activation(),\n", " (GCNConv(4, 4), \"x, edge_index -> x\"),\n", " activation(),\n", " Linear(4, 4),\n", - " (pooling, \"x, None -> x\"),\n", + " (pooling, \"x, batch -> x\"),\n", " Linear(4, 2),\n", " activation(),\n", " Linear(2, 1),\n", @@ -80,7 +79,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -125,7 +124,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -153,7 +152,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -161,20 +160,20 @@ "output_type": "stream", "text": [ "Welcome to the CBC MILP Solver \n", - "Version: 2.10.12 \n", - "Build Date: Sep 3 2024 \n", + "Version: 2.9.9 \n", + "Build Date: Oct 13 2018 \n", "\n", - "command line - /home/jalving/miniconda3/bin/cbc -printingOptions all -import /tmp/tmplnicse8d.pyomo.lp -stat=1 -solve -solu /tmp/tmplnicse8d.pyomo.soln (default strategy 1)\n", + "command line - /rds/general/user/sz421/home/anaconda3/envs/OMLT_test/bin/cbc -printingOptions all -import /var/tmp/pbs.377756.pbs/tmponfhl_r6.pyomo.lp -stat=1 -solve -solu /var/tmp/pbs.377756.pbs/tmponfhl_r6.pyomo.soln (default strategy 1)\n", "Option for printingOptions changed from normal to all\n", - "Presolve 171 (-223) rows, 109 (-77) columns and 655 (-220) elements\n", + "Presolve 172 (-222) rows, 111 (-75) columns and 608 (-267) elements\n", "Statistics for presolved model\n", "Original problem has 26 integers (26 of which binary)\n", "Presolved problem has 25 integers (25 of which binary)\n", - "==== 108 zero objective 2 different\n", + "==== 110 zero objective 2 different\n", "1 variables have objective of -0.0421598\n", - "108 variables have objective of 0\n", + "110 variables have objective of 0\n", "==== absolute objective values 2 different\n", - "108 variables have objective of 0\n", + "110 variables have objective of 0\n", "1 variables have objective of 0.0421598\n", "==== for integers 25 zero objective 1 different\n", "25 variables have objective of 0\n", @@ -183,95 +182,94 @@ "===== end objective counts\n", "\n", "\n", - "Problem has 171 rows, 109 columns (1 with objective) and 655 elements\n", + "Problem has 172 rows, 111 columns (1 with objective) and 608 elements\n", "Column breakdown:\n", - "0 of type 0.0->inf, 44 of type 0.0->up, 0 of type lo->inf, \n", - "40 of type lo->up, 0 of type free, 0 of type fixed, \n", + "0 of type 0.0->inf, 49 of type 0.0->up, 0 of type lo->inf, \n", + "37 of type lo->up, 0 of type free, 0 of type fixed, \n", "0 of type -inf->0.0, 0 of type -inf->up, 25 of type 0.0->1.0 \n", "Row breakdown:\n", - "3 of type E 0.0, 0 of type E 1.0, 0 of type E -1.0, \n", - "8 of type E other, 0 of type G 0.0, 0 of type G 1.0, \n", - "0 of type G other, 133 of type L 0.0, 0 of type L 1.0, \n", - "26 of type L other, 0 of type Range 0.0->1.0, 1 of type Range other, \n", + "8 of type E 0.0, 0 of type E 1.0, 0 of type E -1.0, \n", + "5 of type E other, 0 of type G 0.0, 0 of type G 1.0, \n", + "0 of type G other, 134 of type L 0.0, 0 of type L 1.0, \n", + "25 of type L other, 0 of type Range 0.0->1.0, 0 of type Range other, \n", "0 of type Free \n", - "Continuous objective value is 0.315152 - 0.01 seconds\n", + "Continuous objective value is 0.315152 - 0.00 seconds\n", "Cgl0003I 0 fixed, 0 tightened bounds, 2 strengthened rows, 0 substitutions\n", - "Cgl0004I processed model has 169 rows, 107 columns (25 integer (25 of which binary)) and 692 elements\n", - "Cbc0038I Initial state - 7 integers unsatisfied sum - 0.178371\n", - "Cbc0038I Pass 1: suminf. 0.00000 (0) obj. 0.317969 iterations 73\n", + "Cgl0004I processed model has 166 rows, 105 columns (25 integer (25 of which binary)) and 670 elements\n", + "Cbc0038I Initial state - 5 integers unsatisfied sum - 0.191951\n", + "Cbc0038I Pass 1: suminf. 0.00000 (0) obj. 0.317969 iterations 17\n", "Cbc0038I Solution found of 0.317969\n", "Cbc0038I Relaxing continuous gives 0.317969\n", - "Cbc0038I Before mini branch and bound, 18 integers at bound fixed and 59 continuous\n", - "Cbc0038I Full problem 169 rows 107 columns, reduced to 33 rows 17 columns\n", - "Cbc0038I Mini branch and bound did not improve solution (0.33 seconds)\n", - "Cbc0038I Round again with cutoff of 0.317678\n", - "Cbc0038I Pass 2: suminf. 0.01308 (1) obj. 0.317678 iterations 20\n", - "Cbc0038I Pass 3: suminf. 0.28789 (1) obj. 0.317678 iterations 7\n", - "Cbc0038I Pass 4: suminf. 0.01308 (1) obj. 0.317678 iterations 23\n", - "Cbc0038I Pass 5: suminf. 0.28789 (1) obj. 0.317678 iterations 10\n", - "Cbc0038I Pass 6: suminf. 0.01308 (1) obj. 0.317678 iterations 8\n", - "Cbc0038I Pass 7: suminf. 0.01308 (1) obj. 0.317678 iterations 30\n", - "Cbc0038I Pass 8: suminf. 0.28789 (1) obj. 0.317678 iterations 8\n", - "Cbc0038I Pass 9: suminf. 0.01308 (1) obj. 0.317678 iterations 6\n", - "Cbc0038I Pass 10: suminf. 0.01308 (1) obj. 0.317678 iterations 16\n", - "Cbc0038I Pass 11: suminf. 0.28789 (1) obj. 0.317678 iterations 3\n", - "Cbc0038I Pass 12: suminf. 0.01308 (1) obj. 0.317678 iterations 2\n", - "Cbc0038I Pass 13: suminf. 0.01308 (1) obj. 0.317678 iterations 21\n", - "Cbc0038I Pass 14: suminf. 0.28789 (1) obj. 0.317678 iterations 6\n", - "Cbc0038I Pass 15: suminf. 0.01308 (1) obj. 0.317678 iterations 4\n", - "Cbc0038I Pass 16: suminf. 0.01308 (1) obj. 0.317678 iterations 9\n", - "Cbc0038I Pass 17: suminf. 0.28789 (1) obj. 0.317678 iterations 6\n", - "Cbc0038I Pass 18: suminf. 0.01308 (1) obj. 0.317678 iterations 9\n", - "Cbc0038I Pass 19: suminf. 0.01308 (1) obj. 0.317678 iterations 7\n", - "Cbc0038I Pass 20: suminf. 0.28789 (1) obj. 0.317678 iterations 3\n", - "Cbc0038I Pass 21: suminf. 0.01308 (1) obj. 0.317678 iterations 2\n", - "Cbc0038I Pass 22: suminf. 0.01308 (1) obj. 0.317678 iterations 16\n", - "Cbc0038I Pass 23: suminf. 0.28789 (1) obj. 0.317678 iterations 2\n", - "Cbc0038I Pass 24: suminf. 0.01308 (1) obj. 0.317678 iterations 1\n", - "Cbc0038I Pass 25: suminf. 0.01308 (1) obj. 0.317678 iterations 29\n", - "Cbc0038I Pass 26: suminf. 0.28789 (1) obj. 0.317678 iterations 2\n", - "Cbc0038I Pass 27: suminf. 0.01308 (1) obj. 0.317678 iterations 1\n", - "Cbc0038I Pass 28: suminf. 0.01308 (1) obj. 0.317678 iterations 10\n", - "Cbc0038I Pass 29: suminf. 0.28789 (1) obj. 0.317678 iterations 4\n", - "Cbc0038I Pass 30: suminf. 0.01308 (1) obj. 0.317678 iterations 3\n", - "Cbc0038I Pass 31: suminf. 0.01308 (1) obj. 0.317678 iterations 3\n", + "Cbc0038I Before mini branch and bound, 19 integers at bound fixed and 48 continuous\n", + "Cbc0038I Full problem 166 rows 105 columns, reduced to 49 rows 27 columns\n", + "Cbc0038I Mini branch and bound did not improve solution (0.01 seconds)\n", + "Cbc0038I Round again with cutoff of 0.317791\n", + "Cbc0038I Pass 2: suminf. 0.00876 (1) obj. 0.317791 iterations 1\n", + "Cbc0038I Pass 3: suminf. 0.18897 (1) obj. 0.317791 iterations 25\n", + "Cbc0038I Pass 4: suminf. 0.00876 (1) obj. 0.317791 iterations 45\n", + "Cbc0038I Pass 5: suminf. 0.18897 (1) obj. 0.317791 iterations 10\n", + "Cbc0038I Pass 6: suminf. 0.00876 (1) obj. 0.317791 iterations 9\n", + "Cbc0038I Pass 7: suminf. 0.00876 (1) obj. 0.317791 iterations 20\n", + "Cbc0038I Pass 8: suminf. 0.18897 (1) obj. 0.317791 iterations 11\n", + "Cbc0038I Pass 9: suminf. 0.00876 (1) obj. 0.317791 iterations 11\n", + "Cbc0038I Pass 10: suminf. 0.00876 (1) obj. 0.317791 iterations 4\n", + "Cbc0038I Pass 11: suminf. 0.18897 (1) obj. 0.317791 iterations 10\n", + "Cbc0038I Pass 12: suminf. 0.00876 (1) obj. 0.317791 iterations 8\n", + "Cbc0038I Pass 13: suminf. 0.00876 (1) obj. 0.317791 iterations 6\n", + "Cbc0038I Pass 14: suminf. 0.18897 (1) obj. 0.317791 iterations 9\n", + "Cbc0038I Pass 15: suminf. 0.00876 (1) obj. 0.317791 iterations 9\n", + "Cbc0038I Pass 16: suminf. 0.00876 (1) obj. 0.317791 iterations 6\n", + "Cbc0038I Pass 17: suminf. 0.18897 (1) obj. 0.317791 iterations 17\n", + "Cbc0038I Pass 18: suminf. 0.00876 (1) obj. 0.317791 iterations 18\n", + "Cbc0038I Pass 19: suminf. 0.00876 (1) obj. 0.317791 iterations 8\n", + "Cbc0038I Pass 20: suminf. 0.18897 (1) obj. 0.317791 iterations 15\n", + "Cbc0038I Pass 21: suminf. 0.00876 (1) obj. 0.317791 iterations 19\n", + "Cbc0038I Pass 22: suminf. 0.00876 (1) obj. 0.317791 iterations 25\n", + "Cbc0038I Pass 23: suminf. 0.18897 (1) obj. 0.317791 iterations 6\n", + "Cbc0038I Pass 24: suminf. 0.00876 (1) obj. 0.317791 iterations 5\n", + "Cbc0038I Pass 25: suminf. 0.00876 (1) obj. 0.317791 iterations 12\n", + "Cbc0038I Pass 26: suminf. 0.18897 (1) obj. 0.317791 iterations 6\n", + "Cbc0038I Pass 27: suminf. 0.00876 (1) obj. 0.317791 iterations 5\n", + "Cbc0038I Pass 28: suminf. 0.00876 (1) obj. 0.317791 iterations 13\n", + "Cbc0038I Pass 29: suminf. 0.18897 (1) obj. 0.317791 iterations 6\n", + "Cbc0038I Pass 30: suminf. 0.00876 (1) obj. 0.317791 iterations 15\n", + "Cbc0038I Pass 31: suminf. 0.00876 (1) obj. 0.317791 iterations 6\n", "Cbc0038I No solution found this major pass\n", - "Cbc0038I Before mini branch and bound, 2 integers at bound fixed and 49 continuous\n", - "Cbc0038I Full problem 169 rows 107 columns, reduced to 56 rows 27 columns\n", - "Cbc0038I Mini branch and bound did not improve solution (0.65 seconds)\n", - "Cbc0038I After 0.65 seconds - Feasibility pump exiting with objective of 0.317969 - took 0.44 seconds\n", - "Cbc0012I Integer solution of 0.31796885 found by feasibility pump after 0 iterations and 0 nodes (0.66 seconds)\n", - "Cbc0038I Full problem 169 rows 107 columns, reduced to 56 rows 27 columns\n", - "Cbc0031I 4 added rows had average density of 8.5\n", - "Cbc0013I At root node, 24 cuts changed objective from 0.31515217 to 0.31796885 in 1 passes\n", - "Cbc0014I Cut generator 0 (Probing) - 14 row cuts average 3.0 elements, 1 column cuts (1 active) in 0.000 seconds - new frequency is 1\n", - "Cbc0014I Cut generator 1 (Gomory) - 3 row cuts average 10.3 elements, 0 column cuts (0 active) in 0.001 seconds - new frequency is 1\n", + "Cbc0038I Before mini branch and bound, 1 integers at bound fixed and 46 continuous\n", + "Cbc0038I Full problem 166 rows 105 columns, reduced to 48 rows 27 columns\n", + "Cbc0038I Mini branch and bound did not improve solution (0.02 seconds)\n", + "Cbc0038I After 0.02 seconds - Feasibility pump exiting with objective of 0.317969 - took 0.02 seconds\n", + "Cbc0012I Integer solution of 0.31796885 found by feasibility pump after 0 iterations and 0 nodes (0.02 seconds)\n", + "Cbc0038I Full problem 166 rows 105 columns, reduced to 49 rows 27 columns\n", + "Cbc0031I 6 added rows had average density of 5.5\n", + "Cbc0013I At root node, 25 cuts changed objective from 0.31628066 to 0.31796885 in 1 passes\n", + "Cbc0014I Cut generator 0 (Probing) - 11 row cuts average 3.0 elements, 1 column cuts (1 active) in 0.000 seconds - new frequency is 1\n", + "Cbc0014I Cut generator 1 (Gomory) - 2 row cuts average 13.0 elements, 0 column cuts (0 active) in 0.000 seconds - new frequency is 1\n", "Cbc0014I Cut generator 2 (Knapsack) - 0 row cuts average 0.0 elements, 0 column cuts (0 active) in 0.000 seconds - new frequency is -100\n", "Cbc0014I Cut generator 3 (Clique) - 0 row cuts average 0.0 elements, 0 column cuts (0 active) in 0.000 seconds - new frequency is -100\n", - "Cbc0014I Cut generator 4 (MixedIntegerRounding2) - 2 row cuts average 3.0 elements, 0 column cuts (0 active) in 0.000 seconds - new frequency is 1\n", + "Cbc0014I Cut generator 4 (MixedIntegerRounding2) - 4 row cuts average 3.2 elements, 0 column cuts (0 active) in 0.000 seconds - new frequency is 1\n", "Cbc0014I Cut generator 5 (FlowCover) - 0 row cuts average 0.0 elements, 0 column cuts (0 active) in 0.000 seconds - new frequency is -100\n", - "Cbc0014I Cut generator 6 (TwoMirCuts) - 5 row cuts average 7.8 elements, 0 column cuts (0 active) in 0.000 seconds - new frequency is 1\n", - "Cbc0001I Search completed - best objective 0.3179688462393472, took 20 iterations and 0 nodes (0.75 seconds)\n", + "Cbc0014I Cut generator 6 (TwoMirCuts) - 8 row cuts average 6.8 elements, 0 column cuts (0 active) in 0.000 seconds - new frequency is 1\n", + "Cbc0001I Search completed - best objective 0.3179688539269278, took 31 iterations and 0 nodes (0.03 seconds)\n", "Cbc0035I Maximum depth 0, 0 variables fixed on reduced cost\n", - "Cuts at root node changed objective from 0.315152 to 0.317969\n", - "Probing was tried 1 times and created 15 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", - "Gomory was tried 1 times and created 3 cuts of which 0 were active after adding rounds of cuts (0.001 seconds)\n", + "Cuts at root node changed objective from 0.316281 to 0.317969\n", + "Probing was tried 1 times and created 12 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", + "Gomory was tried 1 times and created 2 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", "Knapsack was tried 1 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", "Clique was tried 1 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", - "MixedIntegerRounding2 was tried 1 times and created 2 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", + "MixedIntegerRounding2 was tried 1 times and created 4 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", "FlowCover was tried 1 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", - "TwoMirCuts was tried 1 times and created 5 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", - "ZeroHalf was tried 1 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", + "TwoMirCuts was tried 1 times and created 8 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", "\n", "Result - Optimal solution found\n", "\n", "Objective value: 0.31796885\n", "Enumerated nodes: 0\n", - "Total iterations: 20\n", - "Time (CPU seconds): 0.84\n", - "Time (Wallclock seconds): 0.07\n", + "Total iterations: 31\n", + "Time (CPU seconds): 0.03\n", + "Time (Wallclock seconds): 0.03\n", "\n", - "Total time (CPU seconds): 0.93 (Wallclock seconds): 0.08\n", + "Total time (CPU seconds): 0.03 (Wallclock seconds): 0.03\n", "\n" ] } @@ -302,28 +300,15 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 5, "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "Sequential(\n", - " (0) - GCNConv(2, 4): x, edge_index -> x\n", - " (1) - ReLU(): x -> x\n", - " (2) - GCNConv(4, 4): x, edge_index -> x\n", - " (3) - ReLU(): x -> x\n", - " (4) - Linear(in_features=4, out_features=4, bias=True): x -> x\n", - " (5) - : x, None -> x\n", - " (6) - Linear(in_features=4, out_features=2, bias=True): x -> x\n", - " (7) - ReLU(): x -> x\n", - " (8) - Linear(in_features=2, out_features=1, bias=True): x -> x\n", - ")" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0.31796885]]\n" + ] } ], "source": [ @@ -337,10 +322,8 @@ " X.append(pyo.value(m1.nn.inputs[i]))\n", "X = np.array(X).reshape(3, 2)\n", "edges = np.transpose(np.array(edges)).reshape(2, -1)\n", - "nn.eval()\n", - "# TODO @zshiqiang: update for latest torch.geometric # noqa: FIX002\n", - "# https://github.com/cog-imperial/OMLT/issues/166\n", - "# print(nn1(torch.tensor(X).float(), torch.tensor(edges)).detach().numpy()) : noqa: ERA001" + "nn1.eval()\n", + "print(nn1(torch.tensor(X).float(), torch.tensor(edges).long(), None).detach().numpy())" ] }, { @@ -352,14 +335,14 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Ipopt 3.14.16: \n", + "Ipopt 3.14.12: \n", "\n", "******************************************************************************\n", "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", @@ -367,7 +350,7 @@ " For more information visit https://github.com/coin-or/Ipopt\n", "******************************************************************************\n", "\n", - "This is Ipopt version 3.14.16, running with linear solver MUMPS 5.7.3.\n", + "This is Ipopt version 3.14.12, running with linear solver MUMPS 5.2.1.\n", "\n", "Number of nonzeros in equality constraint Jacobian...: 395\n", "Number of nonzeros in inequality constraint Jacobian.: 276\n", @@ -385,61 +368,88 @@ "\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", " 0 0.0000000e+00 4.73e-01 1.32e-04 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 7.5562414e-02 3.99e-01 6.07e+01 -1.0 6.41e-01 - 4.88e-02 1.57e-01f 1\n", - " 2 1.6790546e-01 3.08e-01 4.25e+01 -1.0 4.05e-01 - 1.81e-01 2.28e-01f 1\n", - " 3 2.5794318e-01 2.19e-01 3.18e+01 -1.0 3.13e-01 - 5.10e-01 2.88e-01f 1\n", - " 4 3.9100052e-01 8.85e-02 1.45e+01 -1.0 2.23e-01 - 9.76e-01 5.97e-01h 1\n", - " 5 4.4307882e-01 3.72e-02 2.75e+01 -1.0 1.41e-01 - 1.00e+00 5.79e-01h 1\n", - " 6 4.6540207e-01 1.52e-02 6.33e+01 -1.0 8.16e-02 - 1.00e+00 5.91e-01h 1\n", + " 1 7.5562415e-02 3.99e-01 6.07e+01 -1.0 6.41e-01 - 4.88e-02 1.57e-01f 1\n", + " 2 1.6790548e-01 3.08e-01 4.25e+01 -1.0 4.05e-01 - 1.81e-01 2.28e-01f 1\n", + " 3 2.5794319e-01 2.19e-01 3.18e+01 -1.0 3.13e-01 - 5.10e-01 2.88e-01f 1\n", + " 4 3.9100053e-01 8.85e-02 1.45e+01 -1.0 2.23e-01 - 9.76e-01 5.97e-01h 1\n", + " 5 4.4307883e-01 3.72e-02 2.75e+01 -1.0 1.41e-01 - 1.00e+00 5.79e-01h 1\n", + " 6 4.6540208e-01 1.52e-02 6.33e+01 -1.0 8.16e-02 - 1.00e+00 5.91e-01h 1\n", " 7 4.7445376e-01 6.31e-03 1.55e+02 -1.0 3.67e-02 - 1.00e+00 5.85e-01h 1\n", " 8 4.7820844e-01 2.61e-03 3.74e+02 -1.0 1.47e-02 - 1.00e+00 5.86e-01h 1\n", - " 9 4.7976340e-01 1.08e-03 9.04e+02 -1.0 6.36e-03 - 1.00e+00 5.86e-01h 1\n", + " 9 4.7976341e-01 1.08e-03 9.04e+02 -1.0 6.36e-03 - 1.00e+00 5.86e-01h 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", " 10 4.8040743e-01 4.48e-04 2.18e+03 -1.0 2.53e-03 - 1.00e+00 5.86e-01h 1\n", - " 11 4.8067423e-01 1.86e-04 5.26e+03 -1.0 1.09e-03 - 1.00e+00 5.86e-01h 1\n", + " 11 4.8067424e-01 1.86e-04 5.26e+03 -1.0 1.09e-03 - 1.00e+00 5.86e-01h 1\n", " 12 4.8078473e-01 7.67e-05 1.27e+04 -1.0 4.34e-04 - 1.00e+00 5.87e-01h 1\n", " 13 4.8083051e-01 3.16e-05 3.04e+04 -1.0 1.87e-04 - 1.00e+00 5.88e-01h 1\n", - " 14 4.8084946e-01 1.29e-05 7.21e+04 -1.0 7.40e-05 - 1.00e+00 5.91e-01h 1\n", + " 14 4.8084947e-01 1.29e-05 7.21e+04 -1.0 7.40e-05 - 1.00e+00 5.91e-01h 1\n", " 15 4.8085732e-01 5.18e-06 1.67e+05 -1.0 3.15e-05 - 1.00e+00 5.99e-01h 1\n", " 16 4.8086057e-01 1.98e-06 3.65e+05 -1.0 1.21e-05 - 1.00e+00 6.18e-01h 1\n", - " 17 4.8086190e-01 6.64e-07 6.79e+05 -1.0 4.84e-06 - 1.00e+00 6.65e-01h 1\n", + " 17 4.8086191e-01 6.64e-07 6.79e+05 -1.0 4.84e-06 - 1.00e+00 6.65e-01h 1\n", " 18 4.8086192e-01 6.47e-07 3.49e+06 -1.0 1.54e-06 - 1.00e+00 2.47e-02f 6\n", - " 19 4.8086258e-01 1.92e-10 1.00e-06 -1.0 1.52e-06 - 1.00e+00 1.00e+00h 1\n", + " 19 4.8086258e-01 1.04e-10 1.00e-06 -1.0 1.52e-06 - 1.00e+00 1.00e+00h 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 4.8086252e-01 1.96e-09 4.52e+02 -8.6 7.22e-05 - 1.00e+00 1.00e+00h 1\n", - " 21 4.8001911e-01 2.86e-02 2.80e+02 -8.6 1.17e+00 - 5.23e-01 1.00e+00f 1\n", - " 22 4.8001743e-01 1.08e-02 2.14e+01 -8.6 2.15e-01 - 9.00e-01 6.57e-01h 1\n", + " 20 4.8086253e-01 1.78e-10 4.52e+02 -8.6 7.22e-05 - 1.00e+00 1.00e+00h 1\n", + " 21 4.8001913e-01 2.86e-02 2.80e+02 -8.6 1.17e+00 - 5.24e-01 1.00e+00f 1\n", + " 22 4.8001744e-01 1.08e-02 2.14e+01 -8.6 2.16e-01 - 9.00e-01 6.57e-01h 1\n", " 23 4.8001271e-01 1.79e-03 2.28e+01 -8.6 3.03e-01 - 8.31e-01 1.00e+00h 1\n", - " 24 4.8000768e-01 1.81e-04 4.22e+01 -8.6 9.74e-02 - 7.43e-01 1.00e+00h 1\n", - " 25 4.8000768e-01 1.81e-04 3.59e+01 -8.6 9.42e-03 -4.0 4.08e-01 4.08e-04h 1\n", - " 26 4.8000767e-01 1.80e-04 8.64e+01 -8.6 2.02e-02 - 4.83e-01 2.60e-03f 2\n", - " 27 4.8000767e-01 1.80e-04 1.41e+02 -8.6 1.89e-02 - 1.00e+00 5.52e-04h 1\n", - " 28 4.8000668e-01 5.07e-06 5.74e+00 -8.6 1.78e-02 - 2.96e-01 1.00e+00f 1\n", - " 29 4.8000668e-01 5.06e-06 1.41e+02 -8.6 3.89e-05 - 1.00e+00 9.95e-04h 1\n", + " 24 4.8000768e-01 1.81e-04 4.39e+01 -8.6 9.74e-02 - 7.32e-01 1.00e+00h 1\n", + " 25 4.8000768e-01 1.80e-04 5.02e+01 -8.6 1.67e-02 - 5.11e-01 4.80e-03h 1\n", + " 26 4.8000768e-01 1.80e-04 7.68e+01 -8.6 1.72e-02 - 2.92e-01 2.94e-04f 2\n", + " 27 4.8000768e-01 1.80e-04 1.18e+02 -8.6 1.73e-02 - 6.38e-01 2.96e-04h 1\n", + " 28 4.8000768e-01 1.80e-04 1.25e+02 -8.6 1.76e-02 - 3.09e-01 6.58e-05h 2\n", + " 29 4.8000768e-01 1.80e-04 1.41e+02 -8.6 1.76e-02 - 1.00e+00 2.94e-04h 1\n", "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 4.8000669e-01 9.53e-11 1.99e-10 -8.6 4.54e-05 - 1.00e+00 1.00e+00f 1\n", + " 30 4.8000669e-01 5.04e-06 2.97e+00 -8.6 1.77e-02 - 2.99e-01 1.00e+00f 1\n", + " 31 4.8000669e-01 5.04e-06 8.32e+01 -8.6 4.66e-05 - 5.89e-01 2.35e-04h 1\n", + " 32 4.8000669e-01 5.04e-06 1.14e+02 -8.6 5.90e-05 - 5.27e-01 3.92e-05h 1\n", + " 33 4.8000669e-01 5.04e-06 1.25e+02 -8.6 6.02e-05 - 3.88e-01 6.73e-06f 2\n", + " 34 4.8000669e-01 5.04e-06 1.25e+02 -8.6 6.06e-05 - 5.49e-02 2.21e-05h 1\n", + " 35 4.8000669e-01 5.04e-06 1.27e+02 -8.6 4.61e-04 - 8.33e-02 7.28e-08f 2\n", + " 36 4.8000669e-01 5.04e-06 1.34e+02 -8.6 6.09e-05 - 4.80e-01 7.71e-05f 2\n", + " 37 4.8000669e-01 5.04e-06 1.35e+02 -8.6 6.11e-05 - 1.75e-01 1.36e-05h 1\n", + " 38 4.8000669e-01 5.04e-06 1.36e+02 -8.6 1.27e-04 - 9.83e-02 1.38e-07f 2\n", + " 39 4.8000669e-01 5.04e-06 1.37e+02 -8.6 6.12e-05 - 2.54e-01 9.45e-04h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 4.8000669e-01 4.94e-06 1.35e+02 -8.6 6.12e-05 - 1.83e-01 1.89e-02f 1\n", + " 41 4.8000669e-01 4.94e-06 1.36e+02 -8.6 2.85e-04 - 9.97e-02 1.10e-07f 2\n", + " 42 4.8000669e-01 4.94e-06 1.37e+02 -8.6 6.00e-05 - 1.72e-01 4.40e-05h 1\n", + " 43 4.8000669e-01 4.94e-06 1.37e+02 -8.6 1.41e-04 - 9.04e-02 1.49e-06f 2\n", + " 44 4.8000669e-01 4.94e-06 1.38e+02 -8.6 6.01e-05 - 1.71e-01 5.97e-06f 2\n", + " 45 4.8000670e-01 2.65e-11 6.17e+01 -8.6 6.01e-05 - 1.56e-01 1.00e+00h 1\n", + " 46 4.8000670e-01 2.64e-11 5.65e+01 -8.6 3.45e-06 - 5.27e-02 4.42e-04h 1\n", + " 47 4.8000670e-01 2.26e-11 7.42e+01 -8.6 1.45e-07 - 6.61e-01 1.47e-01f 2\n", + " 48 4.8000670e-01 2.25e-11 8.82e+01 -8.6 7.27e-06 - 2.11e-01 1.18e-03h 1\n", + " 49 4.8000670e-01 2.25e-11 1.30e+02 -8.6 8.86e-06 - 7.86e-01 1.57e-04f 2\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 50 4.8000670e-01 2.25e-11 1.33e+02 -8.6 4.24e-05 - 2.54e-01 1.00e-04h 1\n", + " 51 4.8000670e-01 2.25e-11 1.41e+02 -8.6 6.81e-05 - 1.00e+00 2.59e-05f 2\n", + " 52 4.8000670e-01 3.10e-11 2.08e+00 -8.6 1.27e-07 - 2.54e-01 1.00e+00h 1\n", + " 53 4.8000670e-01 3.19e-09 1.41e+02 -8.6 3.37e-05 - 1.00e+00 4.73e-04h 1\n", + " 54 4.8000670e-01 9.74e-11 7.50e-11 -8.6 1.65e-08 - 1.00e+00 1.00e+00f 1\n", "\n", - "Number of Iterations....: 30\n", + "Number of Iterations....: 54\n", "\n", " (scaled) (unscaled)\n", - "Objective...............: 4.8000669067803564e-01 4.8000669067803564e-01\n", - "Dual infeasibility......: 1.9944890902928439e-10 1.9944890902928439e-10\n", - "Constraint violation....: 9.5274010902812734e-11 9.5274010902812734e-11\n", + "Objective...............: 4.8000669509937166e-01 4.8000669509937166e-01\n", + "Dual infeasibility......: 7.5043113584813605e-11 7.5043113584813605e-11\n", + "Constraint violation....: 9.7397756526618195e-11 9.7397756526618195e-11\n", "Variable bound violation: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Complementarity.........: 2.5481058108255804e-09 2.5481058108255804e-09\n", - "Overall NLP error.......: 9.5274010902812734e-11 2.5481058108255804e-09\n", + "Complementarity.........: 2.5636037643218892e-09 2.5636037643218892e-09\n", + "Overall NLP error.......: 9.7397756526618195e-11 2.5636037643218892e-09\n", "\n", "\n", - "Number of objective function evaluations = 37\n", - "Number of objective gradient evaluations = 31\n", - "Number of equality constraint evaluations = 37\n", - "Number of inequality constraint evaluations = 37\n", - "Number of equality constraint Jacobian evaluations = 31\n", - "Number of inequality constraint Jacobian evaluations = 31\n", - "Number of Lagrangian Hessian evaluations = 30\n", - "Total seconds in IPOPT = 0.059\n", + "Number of objective function evaluations = 72\n", + "Number of objective gradient evaluations = 55\n", + "Number of equality constraint evaluations = 72\n", + "Number of inequality constraint evaluations = 72\n", + "Number of equality constraint Jacobian evaluations = 55\n", + "Number of inequality constraint Jacobian evaluations = 55\n", + "Number of Lagrangian Hessian evaluations = 54\n", + "Total seconds in IPOPT = 0.134\n", "\n", - "EXIT: Optimal Solution Found.\n" + "EXIT: Optimal Solution Found.\n", + "\b" ] } ], @@ -474,31 +484,30 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pyomo.environ as pyo\n", "import torch\n", - "from torch.nn import ReLU\n", - "from torch_geometric.nn import SAGEConv, global_add_pool\n", - "\n", "from omlt import OmltBlock\n", "from omlt.io.torch_geometric import gnn_with_non_fixed_graph\n", + "from torch.nn import Linear, ReLU\n", + "from torch_geometric.nn import SAGEConv, Sequential, global_add_pool\n", "\n", "\n", "def SAGE_Sequential(activation, pooling):\n", " torch.manual_seed(123)\n", " return Sequential(\n", - " \"x, edge_index\",\n", + " \"x, edge_index, batch\",\n", " [\n", " (SAGEConv(2, 4, aggr=\"sum\"), \"x, edge_index -> x\"),\n", " activation(),\n", " (SAGEConv(4, 4, aggr=\"sum\"), \"x, edge_index -> x\"),\n", " activation(),\n", " Linear(4, 4),\n", - " (pooling, \"x, None -> x\"),\n", + " (pooling, \"x, batch -> x\"),\n", " Linear(4, 2),\n", " activation(),\n", " Linear(2, 1),\n", @@ -515,7 +524,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -523,21 +532,21 @@ "output_type": "stream", "text": [ "Welcome to the CBC MILP Solver \n", - "Version: 2.10.12 \n", - "Build Date: Sep 3 2024 \n", + "Version: 2.9.9 \n", + "Build Date: Oct 13 2018 \n", "\n", - "command line - /home/jalving/miniconda3/bin/cbc -printingOptions all -import /tmp/tmpe02s_bpw.pyomo.lp -stat=1 -solve -solu /tmp/tmpe02s_bpw.pyomo.soln (default strategy 1)\n", + "command line - /rds/general/user/sz421/home/anaconda3/envs/OMLT_test/bin/cbc -printingOptions all -import /var/tmp/pbs.377756.pbs/tmpfd6tc67i.pyomo.lp -stat=1 -solve -solu /var/tmp/pbs.377756.pbs/tmpfd6tc67i.pyomo.soln (default strategy 1)\n", "Option for printingOptions changed from normal to all\n", - "Presolve 266 (-131) rows, 147 (-45) columns and 875 (-150) elements\n", + "Presolve 260 (-137) rows, 141 (-51) columns and 852 (-173) elements\n", "Statistics for presolved model\n", "Original problem has 32 integers (32 of which binary)\n", "Presolved problem has 29 integers (29 of which binary)\n", - "==== 145 zero objective 3 different\n", - "145 variables have objective of 0\n", + "==== 139 zero objective 3 different\n", + "139 variables have objective of 0\n", "1 variables have objective of 0.203177\n", "1 variables have objective of 0.686721\n", "==== absolute objective values 3 different\n", - "145 variables have objective of 0\n", + "139 variables have objective of 0\n", "1 variables have objective of 0.203177\n", "1 variables have objective of 0.686721\n", "==== for integers 29 zero objective 1 different\n", @@ -547,29 +556,29 @@ "===== end objective counts\n", "\n", "\n", - "Problem has 266 rows, 147 columns (2 with objective) and 875 elements\n", + "Problem has 260 rows, 141 columns (2 with objective) and 852 elements\n", "Column breakdown:\n", - "0 of type 0.0->inf, 61 of type 0.0->up, 0 of type lo->inf, \n", - "57 of type lo->up, 0 of type free, 0 of type fixed, \n", + "0 of type 0.0->inf, 62 of type 0.0->up, 0 of type lo->inf, \n", + "50 of type lo->up, 0 of type free, 0 of type fixed, \n", "0 of type -inf->0.0, 0 of type -inf->up, 29 of type 0.0->1.0 \n", "Row breakdown:\n", - "2 of type E 0.0, 0 of type E 1.0, 0 of type E -1.0, \n", - "30 of type E other, 0 of type G 0.0, 0 of type G 1.0, \n", - "0 of type G other, 152 of type L 0.0, 24 of type L 1.0, \n", - "58 of type L other, 0 of type Range 0.0->1.0, 0 of type Range other, \n", + "0 of type E 0.0, 0 of type E 1.0, 0 of type E -1.0, \n", + "26 of type E other, 0 of type G 0.0, 0 of type G 1.0, \n", + "0 of type G other, 154 of type L 0.0, 24 of type L 1.0, \n", + "56 of type L other, 0 of type Range 0.0->1.0, 0 of type Range other, \n", "0 of type Free \n", - "Continuous objective value is 0.107106 - 0.03 seconds\n", - "Cgl0003I 0 fixed, 0 tightened bounds, 4 strengthened rows, 0 substitutions\n", - "Cgl0004I processed model has 250 rows, 131 columns (29 integer (29 of which binary)) and 985 elements\n", - "Cbc0038I Initial state - 19 integers unsatisfied sum - 2.07755\n", - "Cbc0038I Pass 1: suminf. 1.01765 (9) obj. 0.107106 iterations 53\n", + "Continuous objective value is 0.107106 - 0.00 seconds\n", + "Cgl0003I 0 fixed, 0 tightened bounds, 1 strengthened rows, 0 substitutions\n", + "Cgl0004I processed model has 237 rows, 118 columns (29 integer (29 of which binary)) and 969 elements\n", + "Cbc0038I Initial state - 17 integers unsatisfied sum - 1.66726\n", + "Cbc0038I Pass 1: suminf. 1.01765 (9) obj. 0.107106 iterations 47\n", "Cbc0038I Solution found of 0.107106\n", "Cbc0038I Relaxing continuous gives 0.107106\n", - "Cbc0038I Before mini branch and bound, 9 integers at bound fixed and 37 continuous\n", - "Cbc0038I Mini branch and bound did not improve solution (0.11 seconds)\n", - "Cbc0038I After 0.13 seconds - Feasibility pump exiting with objective of 0.107106 - took 0.05 seconds\n", - "Cbc0012I Integer solution of 0.10710584 found by feasibility pump after 0 iterations and 0 nodes (0.13 seconds)\n", - "Cbc0001I Search completed - best objective 0.10710584, took 0 iterations and 0 nodes (0.15 seconds)\n", + "Cbc0038I Before mini branch and bound, 12 integers at bound fixed and 40 continuous\n", + "Cbc0038I Mini branch and bound did not improve solution (0.01 seconds)\n", + "Cbc0038I After 0.01 seconds - Feasibility pump exiting with objective of 0.107106 - took 0.00 seconds\n", + "Cbc0012I Integer solution of 0.10710584 found by feasibility pump after 0 iterations and 0 nodes (0.01 seconds)\n", + "Cbc0001I Search completed - best objective 0.1071058437228203, took 0 iterations and 0 nodes (0.01 seconds)\n", "Cbc0035I Maximum depth 0, 0 variables fixed on reduced cost\n", "Cuts at root node changed objective from 0.107106 to 0.107106\n", "Probing was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", @@ -579,17 +588,16 @@ "MixedIntegerRounding2 was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", "FlowCover was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", "TwoMirCuts was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", - "ZeroHalf was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)\n", "\n", "Result - Optimal solution found\n", "\n", "Objective value: 0.10710584\n", "Enumerated nodes: 0\n", "Total iterations: 0\n", - "Time (CPU seconds): 0.20\n", - "Time (Wallclock seconds): 0.01\n", + "Time (CPU seconds): 0.01\n", + "Time (Wallclock seconds): 0.02\n", "\n", - "Total time (CPU seconds): 0.23 (Wallclock seconds): 0.02\n", + "Total time (CPU seconds): 0.02 (Wallclock seconds): 0.02\n", "\n" ] } @@ -622,13 +630,20 @@ "# solve the optimization problem\n", "status = pyo.SolverFactory(\"cbc\").solve(m3, tee=True)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "Python [conda env:OMLT_test]", "language": "python", - "name": "python3" + "name": "conda-env-OMLT_test-py" }, "language_info": { "codemirror_mode": { @@ -640,9 +655,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.3" + "version": "3.9.17" } }, "nbformat": 4, - "nbformat_minor": 4 + "nbformat_minor": 2 }