Paper · 2019-06-04 · cs.LG, math.OC, stat.ML
Exact Combinatorial Optimization with Graph Convolutional Neural Networks
Learns branch-and-bound variable selection: a bipartite graph convolutional network imitates strong branching, trained by cross-entropy over candidate variables. On four NP-hard MILP families in SCIP 6.0.1 it is most accurate and, in 11 of 12 size settings, faster than SCIP's default reliability pseudocost rule, including on larger instances (author-reported).
Branch-and-boundImitation learningGraph neural networkbranch-and-boundmixed-integer-programmingimitation-learninggraph-neural-networkcombinatorial-optimization
arXivPDFCodeMarkdown18 min read
AI-compiled by claude-haiku-5-5 on 2026-10-19, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.
In plain words
Many hard optimisation problems are solved by splitting them into smaller pieces, again and again, and throwing away pieces that cannot contain the best answer. Each split asks one question: which quantity should we cut on next? A rule that makes this choice well can save a lot of time, but the best known rule is slow, because it tests every option before choosing.
The authors train a neural network to make that choice quickly. They describe the problem as a graph: one kind of node stands for the rules of the problem, another for its quantities, and a link shows which quantity appears in which rule. A network that passes messages along these links learns to copy the slow expert's choices. It is trained on examples that a solver produced while it worked through many problems.
The learned rule is tested on four classic problem families and compared with the solver's default rule and with earlier learned rules. It is most accurate at copying the expert, and it is often faster to solve. It also keeps working on problems larger than the ones it was trained on, which is the main point of the paper.
TL;DR
A learned branching rule for branch-and-bound, the exact method behind most mixed-integer solvers. A bipartite graph convolutional network reads the solver state and is trained with cross-entropy to pick what strong branching would pick. On four NP-hard families it beats earlier learned rules on accuracy and beats SCIP's default rule on time in most settings, including larger instances. All numbers are author-reported on the authors' benchmarks.
Problem
Branch-and-bound solves a mixed-integer linear program by repeatedly splitting one fractional variable into two child problems and pruning subtrees that cannot beat the incumbent §3.1 eq. 2. The choice of variable, the branching rule, changes the tree size a lot §3.2. Strong branching gives the smallest trees, but it solves two LPs per candidate, so it is too expensive to run at every node. Solvers therefore use hybrid rules that switch from strong branching to cheaper heuristics §3.2.
Earlier learned rules imitated strong branching but relied on heavy manual feature engineering, and they were tested on simplified solvers. They also learned scores or rankings rather than the expert's decision §2. The paper asks whether a graph network can learn the decision directly, with less feature engineering, and whether it generalises to instances larger than those seen in training §1.
Assumption: the target is the solve time of a fixed problem family, so a rule is useful when it keeps trees small and its own cost low §6.
Method
Formulation. Branching is a Markov decision process: the state is the branch-and-bound tree and solver statistics, the action is a fractional variable at the focused node, and an episode is one instance §3.3 fig. 1. The paper does not use reinforcement learning. It uses behavioural cloning: run the expert on training instances, record pairs of (state, expert action), and minimise a cross-entropy loss over the candidate variables §4.1 eq. 3.
\mathcal{L}(\theta) = -\frac{1}{N}\sum_{(\mathbf{s}, \mathbf{a}^*)\in\mathcal{D}} \log \pi_\theta(\mathbf{a}^*\,|\,\mathbf{s}) eq. 3
The expert is strong branching. The paper re-implements its vanilla full strong-branching rule inside SCIP so that it has no side effects on the solver [suppl. §1].
State encoding. The state is a bipartite graph §4.2 fig. 2:
- one constraint node per LP row, with 5 features;
- one variable node per LP column, with 19 features;
- an edge for every non-zero coefficient, with 1 feature (the coefficient).
The feature list is in [suppl. §2.1]. Variable features are a one-hot type (binary, integer, implied integer, continuous), the normalised objective coefficient, lower- and upper-bound indicators, solution-at-bound indicators, solution fractionality, a one-hot basis status (lower, basic, upper, zero), the normalised reduced cost, LP age, solution value, incumbent value and average incumbent value. Constraint features are the cosine similarity with the objective, a normalised bias, a tightness indicator, a normalised dual value and LP age. The edge feature is the coefficient normalised per constraint [suppl. §2.1]. The paper notes the graph structure stays fixed during a run when cuts are only allowed at the root §4.2.
Policy. One graph convolution, made of two half-convolutions: first from variables to constraints, then from constraints back to variables §4.3 eq. 4. Each half sums per-edge messages from a 2-layer perceptron with ReLU, without degree normalisation, then applies a prenorm layer §4.3. The policy discards the constraint nodes, applies a final 2-layer perceptron to each variable, and takes a softmax over the fractional candidates only §4.3.
\mathbf{c}_i \gets f_{\mathcal{C}}\Big(\mathbf{c}_i,\; \sum_{j:(i,j)\in\mathcal{E}} g_{\mathcal{C}}(\mathbf{c}_i, \mathbf{v}_j, \mathbf{e}_{ij})\Big), \qquad \mathbf{v}_j \gets f_{\mathcal{V}}\Big(\mathbf{v}_j,\; \sum_{i:(i,j)\in\mathcal{E}} g_{\mathcal{V}}(\mathbf{c}_i, \mathbf{v}_j, \mathbf{e}_{ij})\Big) eq. 4
Prenorm. The authors argue that normalising by degree would remove the ability to count neighbours §4.3. They therefore use un-normalised sums and fix the weight-initialisation problem with a prenorm layer x ← (x − β)/σ. β and σ are set once from the empirical mean and standard deviation of the layer's input over the training data, and then frozen §4.3.
The code also adds an initial 2-layer embedding for constraints and for variables, and an extra prenorm inside the message. The paper text does not describe either; see Paper vs code.
# Expert data: (state, expert choice) pairs from solver runs [§4.1] [suppl. §1]
# Which rule drives the tree is not stated; the code uses pseudo-cost.
# [code: 02_generate_dataset.py#L321]
def collect(instances, n_samples):
samples = []
while len(samples) < n_samples:
# Pick an instance with replacement, and a new seed per run [suppl. §1]
instance = pick_random(instances)
seed = pick_random_seed()
for node in solver_run(instance, seed):
# Code only: expert queried at about 5% of nodes
# [code: 02_generate_dataset.py#L40, #L322]
if random_uniform() >= 0.05:
continue
# Strong branching scores every fractional variable [§3.2]
scores = strong_branching(node)
# Drop samples with negative scores; time-limit artefact
# [code: 02_generate_dataset.py#L58]
if any(score < 0 for score in scores):
continue
# State encoding [§4.2]; label is the best-scoring candidate
# [§4.1]
best = argmax(scores)
samples.append((encode_state(node), node.candidates[best]))
return samples# Freeze prenorm layers from training statistics [§4.3]
# Code: layers are fixed one at a time, in order
# [code: 03_train_gcnn.py#L28-L60]
for layer in prenorm_layers(model):
# beta = empirical mean of the layer input, sigma = its std [§4.3]
layer.beta = mean(layer_input(train_samples, layer))
layer.sigma = std(layer_input(train_samples, layer))# Training loop: cross-entropy over candidates [§4.1] [eq. 3]
# Adam, batch 32, lr 1e-3; /5 after 10 stale epochs, stop after 20
# [suppl. §2.1]
learning_rate = 1e-3
stale_epochs = 0
best_loss = infinity
while stale_epochs < 20:
for batch in minibatches(train_samples, size=32):
# One score per variable from the policy network [§4.3]
scores = model(batch.state)
# Softmax only over the fractional candidates [§4.3]
candidate_scores = scores[batch.candidates]
loss = cross_entropy(candidate_scores, batch.expert_choice)
adam_step(model, loss, learning_rate)
valid_loss = mean_loss(model, valid_samples)
if valid_loss < best_loss:
best_loss = valid_loss
stale_epochs = 0
# Code: keep the best-validation weights [code: 03_train_gcnn.py#L272]
save(model)
else:
stale_epochs += 1
# Divide the learning rate by 5 after each 10 stale epochs
# [suppl. §2.1]
if stale_epochs % 10 == 0:
learning_rate = learning_rate / 5# Half-convolution from source nodes to target nodes [§4.2] [eq. 4]
def half_convolution(target, source, edges, edge_feats):
# Pre-activation per edge (i, j): sum of three linear maps [eq. 4]
# Shape: (num_edges, 64); 64 is from the code, not the text
pre = (linear_target(target[target_index])
+ linear_source(source[source_index])
+ linear_edge(edge_feats))
# Prenorm, ReLU and a second linear map form the message g [§4.3]
messages = linear_msg(relu(prenorm_edge(pre)))
# Un-normalised sum of messages at each target node [§4.3]
summed = segment_sum(messages, target_index, num_targets)
# Prenorm after the sum [§4.3]
# [code: models/baseline/model.py#L142-L144]
summed = prenorm_sum(summed)
# Update each target node with MLP f on [summed, own features] [eq. 4]
# ReLU after each half [code: models/baseline/model.py#L425]
return relu(mlp_f(concat(summed, target)))# Full policy: one forward pass per branching decision [§4.2] [§4.3]
def policy(constraint_feats, edge_feats, variable_feats, edges):
# Initial embeddings: code only, not in the paper text
# [code: models/baseline/model.py#L295-L312]
constraints = embed_constraints(constraint_feats)
variables = embed_variables(variable_feats)
edge_feats = prenorm_edges(edge_feats) # edges: prenorm only, no MLP
# Variables to constraints, then constraints to variables [§4.2]
constraints = half_convolution(constraints, variables, edges, edge_feats)
variables = half_convolution(variables, constraints, edges, edge_feats)
# Constraint nodes are discarded; score each variable [§4.3]
return output_mlp(variables) # one score per variable, masked laterInference. Choose the variable with the highest score among the fractional candidates §4.3. The paper's experiments use the best validation checkpoint.
Hyperparameters
Values in the paper unless marked "code". "Not stated" means the paper and its supplement do not give the value.
| Name | Value | Where | Notes |
|---|---|---|---|
| Solver | SCIP 6.0.1, 1 h limit | §5.1 | Other SCIP settings default |
| Cutting planes | root node only; restarts off | §5.1 | Code: utilities.py |
| Set covering size (train) | 500 rows, 1,000 columns | §5.1 | Density 0.05 (code: 01_generate_instances.py); not in text |
| Combinatorial auction (train) | 100 items, 500 bids | §5.1 | Arbitrary-relationships procedure §5.1 |
| Capacitated facility location (train) | 100 customers, 100 facilities | §5.1 | Capacity/demand ratio 5 (code: 01_generate_instances.py); not in text |
| Max independent set (train) | 500 nodes, affinity 4 | §5.1 | Paper says Erdős–Rényi; see Paper vs code |
| Evaluation sizes | Easy / Medium / Hard | §5.1 | SC 500/1000/2000 rows; CA 100/500 → 200/1000 → 300/1500; CFL 100/200/400 customers; MIS 500/1000/1500 nodes |
| Eval instances | 20 per difficulty, 5 seeds | §5.1 | 100 solving attempts per method and difficulty |
| Training instances | 10,000 (valid 2,000) | [suppl. §1] | Test: 3 × 20 instances |
| Training samples | 100,000 (valid 20,000) | §5.1 [suppl. §1] | Test uses 20,000, same as valid |
| Optimiser | Adam, lr 1e-3 | [suppl. §2.1] | Adam defaults for betas not stated |
| Batch size | 32 (train) | [suppl. §2.1] | |
| LR schedule | /5 after 10 epochs without improvement | [suppl. §2.1] | Code uses factor 0.2 03_train_gcnn.py |
| Early stopping | 20 epochs without improvement | [suppl. §2.1] | |
| Activation | ReLU | §4.3 | |
| Embedding width | Not stated | §4.3 | Code: 64 model.py |
| Layers | 2-layer perceptrons (f, g, output) | §4.3 | Code adds initial embeddings model.py |
| Constraint / variable / edge features | 5 / 19 / 1 | [suppl. §2.1] | Code: model.py |
| Initialiser | Not stated | §4.3 | Code: orthogonal model.py |
| Pretraining | Prenorm only, on training data | §4.3 | Code: every 10th train file, batch 128 03_train_gcnn.py |
| Max epochs | Not stated | — | Code: 1000 03_train_gcnn.py |
| SVMrank | C ∈ {0.001, 0.01, 0.1, 1}; 2nd-order polynomial features; 250k train / 100k valid candidates | [suppl. §2.2] | Query-based normalisation; code 03_train_competitor.py and C grid 03_train_competitor.py |
| LambdaMART | 500 estimators; same subset sizes | [suppl. §2.2] | Code: 03_train_competitor.py |
| ExtraTrees | MSE on strong-branching scores; same subset sizes | [suppl. §2.3] | Tree count not stated; code uses 100 03_train_competitor.py |
| Training samples for the GCNN control | 250k candidates / 100k valid (GCNN-small) | [suppl. §4] | Control for dataset size |
Results
Author-reported. Setup: SCIP 6.0.1 with default settings except for root-only cuts and no restarts, 1-hour time limit, 20 unseen instances per difficulty and 5 seeds §5.1. Models are trained on easy instances only tab. 2. The baseline reliability pseudocost rule (RPB) is SCIP's default §5.1.
Imitation accuracy (test set, mean ± std over 5 seeds, acc@k = the expert's
best candidate is in the model's top k) tab. 1:
| Problem | Model | acc@1 | acc@5 | acc@10 |
|---|---|---|---|---|
| Set covering | TREES | 51.8 ± 0.3 | 80.5 ± 0.1 | 91.4 ± 0.2 |
| Set covering | SVMRANK | 57.6 ± 0.2 | 84.7 ± 0.1 | 94.0 ± 0.1 |
| Set covering | LMART | 57.4 ± 0.2 | 84.5 ± 0.1 | 93.8 ± 0.1 |
| Set covering | GCNN | 65.5 ± 0.1 | 92.4 ± 0.1 | 98.2 ± 0.0 |
| Combinatorial auction | TREES | 52.9 ± 0.3 | 84.3 ± 0.1 | 94.1 ± 0.1 |
| Combinatorial auction | SVMRANK | 57.2 ± 0.2 | 86.9 ± 0.2 | 95.4 ± 0.1 |
| Combinatorial auction | LMART | 57.3 ± 0.3 | 86.9 ± 0.2 | 95.3 ± 0.1 |
| Combinatorial auction | GCNN | 61.6 ± 0.1 | 91.0 ± 0.1 | 97.8 ± 0.1 |
| Capacitated facility location | TREES | 63.0 ± 0.4 | 97.3 ± 0.1 | 99.9 ± 0.0 |
| Capacitated facility location | SVMRANK | 67.8 ± 0.1 | 98.1 ± 0.1 | 99.9 ± 0.0 |
| Capacitated facility location | LMART | 68.0 ± 0.2 | 98.0 ± 0.0 | 99.9 ± 0.0 |
| Capacitated facility location | GCNN | 71.2 ± 0.2 | 98.6 ± 0.1 | 99.9 ± 0.0 |
| Max independent set | TREES | 30.9 ± 0.4 | 47.4 ± 0.3 | 54.6 ± 0.3 |
| Max independent set | SVMRANK | 48.0 ± 0.6 | 69.3 ± 0.2 | 78.1 ± 0.2 |
| Max independent set | LMART | 48.9 ± 0.3 | 68.9 ± 0.4 | 77.0 ± 0.5 |
| Max independent set | GCNN | 56.5 ± 0.2 | 80.8 ± 0.3 | 89.0 ± 0.1 |
A control with the same training-set size as the competitors, GCNN-small, has acc@1 of 57.9, 55.0, 69.1 and 50.1 on the four problems [suppl. §4].
Policy evaluation (time = 1-shifted geometric mean in seconds; wins = times the policy was fastest, over instances it solved; nodes = B&B nodes on instances solved by all baselines; each cell gives mean ± average per-instance std) tab. 2. The four blocks are Set covering, Combinatorial auction, Capacitated facility location and Maximum independent set, mapped as in the Pitfalls.
Set covering
| Model | Easy time | Easy wins | Easy nodes | Medium time | Medium wins | Medium nodes | Hard time | Hard wins | Hard nodes |
|---|---|---|---|---|---|---|---|---|---|
| FSB | 17.30 ± 6.1% | 0 / 100 | 17 ± 13.7% | 411.34 ± 4.3% | 0 / 90 | 171 ± 6.4% | 3600.00 ± 0.0% | 0 / 0 | n/a |
| RPB | 8.98 ± 4.8% | 0 / 100 | 54 ± 20.8% | 60.07 ± 3.7% | 0 / 100 | 1741 ± 7.9% | 1677.02 ± 3.0% | 4 / 65 | 47299 ± 4.9% |
| TREES | 9.28 ± 4.9% | 0 / 100 | 187 ± 9.4% | 92.47 ± 5.9% | 0 / 100 | 2187 ± 7.9% | 2869.21 ± 3.2% | 0 / 35 | 59013 ± 9.3% |
| SVMRANK | 8.10 ± 3.8% | 1 / 100 | 165 ± 8.2% | 73.58 ± 3.1% | 0 / 100 | 1915 ± 3.8% | 2389.92 ± 2.3% | 0 / 47 | 42120 ± 5.4% |
| LMART | 7.19 ± 4.2% | 14 / 100 | 167 ± 9.0% | 59.98 ± 3.9% | 0 / 100 | 1925 ± 4.9% | 2165.96 ± 2.0% | 0 / 54 | 45319 ± 3.4% |
| GCNN | 6.59 ± 3.1% | 85 / 100 | 134 ± 7.6% | 42.48 ± 2.7% | 100 / 100 | 1450 ± 3.3% | 1489.91 ± 3.3% | 66 / 70 | 29981 ± 4.9% |
Combinatorial auction
| Model | Easy time | Easy wins | Easy nodes | Medium time | Medium wins | Medium nodes | Hard time | Hard wins | Hard nodes |
|---|---|---|---|---|---|---|---|---|---|
| FSB | 4.11 ± 12.1% | 0 / 100 | 6 ± 30.3% | 86.90 ± 12.9% | 0 / 100 | 72 ± 19.4% | 1813.33 ± 5.1% | 0 / 68 | 400 ± 7.5% |
| RPB | 2.74 ± 7.8% | 0 / 100 | 10 ± 32.1% | 17.41 ± 6.6% | 0 / 100 | 689 ± 21.2% | 136.17 ± 7.9% | 13 / 100 | 5511 ± 11.7% |
| TREES | 2.47 ± 7.3% | 0 / 100 | 86 ± 15.9% | 23.70 ± 11.2% | 0 / 100 | 976 ± 14.4% | 451.39 ± 14.6% | 0 / 95 | 10290 ± 16.2% |
| SVMRANK | 2.31 ± 6.8% | 0 / 100 | 77 ± 15.0% | 23.10 ± 9.8% | 0 / 100 | 867 ± 13.4% | 364.48 ± 7.7% | 0 / 98 | 6329 ± 7.7% |
| LMART | 1.79 ± 6.0% | 75 / 100 | 77 ± 14.9% | 14.42 ± 9.5% | 1 / 100 | 873 ± 14.3% | 222.54 ± 8.6% | 0 / 100 | 7006 ± 6.9% |
| GCNN | 1.85 ± 5.0% | 25 / 100 | 70 ± 12.0% | 10.29 ± 7.1% | 99 / 100 | 657 ± 12.2% | 114.16 ± 10.3% | 87 / 100 | 5169 ± 14.9% |
Capacitated facility location
| Model | Easy time | Easy wins | Easy nodes | Medium time | Medium wins | Medium nodes | Hard time | Hard wins | Hard nodes |
|---|---|---|---|---|---|---|---|---|---|
| FSB | 30.36 ± 19.6% | 4 / 100 | 14 ± 34.5% | 214.25 ± 15.2% | 1 / 100 | 76 ± 15.8% | 742.91 ± 9.1% | 15 / 90 | 55 ± 7.2% |
| RPB | 26.55 ± 16.2% | 9 / 100 | 22 ± 31.9% | 156.12 ± 11.5% | 8 / 100 | 142 ± 20.6% | 631.50 ± 8.1% | 14 / 96 | 110 ± 15.5% |
| TREES | 28.96 ± 14.7% | 3 / 100 | 135 ± 20.0% | 159.86 ± 15.3% | 3 / 100 | 401 ± 11.6% | 671.01 ± 11.1% | 1 / 95 | 381 ± 11.1% |
| SVMRANK | 23.58 ± 14.1% | 11 / 100 | 117 ± 20.5% | 130.86 ± 13.6% | 13 / 100 | 348 ± 11.4% | 586.13 ± 10.0% | 21 / 95 | 321 ± 8.8% |
| LMART | 23.34 ± 13.6% | 16 / 100 | 117 ± 20.7% | 128.48 ± 15.4% | 23 / 100 | 349 ± 12.9% | 582.38 ± 10.5% | 15 / 95 | 314 ± 7.0% |
| GCNN | 22.10 ± 15.8% | 57 / 100 | 107 ± 21.4% | 120.94 ± 14.2% | 52 / 100 | 339 ± 11.8% | 563.36 ± 10.7% | 30 / 95 | 338 ± 10.9% |
Maximum independent set
| Model | Easy time | Easy wins | Easy nodes | Medium time | Medium wins | Medium nodes | Hard time | Hard wins | Hard nodes |
|---|---|---|---|---|---|---|---|---|---|
| FSB | 23.58 ± 29.9% | 9 / 100 | 7 ± 35.9% | 1503.55 ± 20.9% | 0 / 74 | 38 ± 28.2% | 3600.00 ± 0.0% | 0 / 0 | n/a |
| RPB | 8.77 ± 11.8% | 7 / 100 | 20 ± 36.1% | 110.99 ± 24.4% | 41 / 100 | 729 ± 37.3% | 2045.61 ± 18.3% | 22 / 42 | 2675 ± 24.0% |
| TREES | 10.75 ± 22.1% | 1 / 100 | 76 ± 44.2% | 1183.37 ± 34.2% | 1 / 47 | 4664 ± 45.8% | 3565.12 ± 1.2% | 0 / 3 | 38296 ± 4.1% |
| SVMRANK | 8.83 ± 14.9% | 2 / 100 | 46 ± 32.2% | 242.91 ± 29.3% | 1 / 96 | 546 ± 26.0% | 2902.94 ± 9.6% | 1 / 18 | 6256 ± 15.1% |
| LMART | 7.31 ± 12.7% | 30 / 100 | 52 ± 38.1% | 219.22 ± 36.0% | 15 / 91 | 747 ± 35.1% | 3044.94 ± 7.0% | 0 / 12 | 8893 ± 3.5% |
| GCNN | 6.43 ± 11.6% | 51 / 100 | 43 ± 40.2% | 192.91 ± 110.2% | 42 / 82 | 1841 ± 88.0% | 2024.37 ± 30.6% | 25 / 29 | 2997 ± 26.3% |
Headline reading, from the tables: GCNN has the highest imitation accuracy on all four problems tab. 1. Its solving time is lower than RPB's in 11 of the 12 problem-and-size settings; the exception is maximum independent set, medium, where RPB is faster. GCNN is the fastest method of all in 10 of the 12 tab. 2. The authors say the learned policy generalises to larger instances and beats RPB on time in almost every setting §5.2. For maximum independent set they note that every learned method solves fewer hard instances than RPB §5.2. The 11-of-12 and 10-of-12 counts are read off tab. 2 by this card, not stated by the authors.
Ablation on set covering, 20 instances per difficulty tab. 3.
| Variant | acc@1 | acc@5 | acc@10 |
|---|---|---|---|
| MEAN (mean convolution) | 65.4 ± 0.1 | 92.4 ± 0.1 | 98.2 ± 0.0 |
| SUM (no prenorm) | 65.5 ± 0.2 | 92.3 ± 0.2 | 98.1 ± 0.1 |
| GCNN (sum + prenorm) | 65.5 ± 0.1 | 92.4 ± 0.1 | 98.2 ± 0.0 |
| Variant | Easy time | Easy wins | Easy nodes | Medium time | Medium wins | Medium nodes | Hard time | Hard wins | Hard nodes |
|---|---|---|---|---|---|---|---|---|---|
| MEAN | 6.7 ± 3% | 13 / 100 | 134 ± 6% | 43.7 ± 3% | 19 / 100 | 1894 ± 4% | 1593.0 ± 4% | 6 / 70 | 62227 ± 6% |
| SUM | 6.6 ± 3% | 27 / 100 | 134 ± 6% | 42.5 ± 3% | 45 / 100 | 1882 ± 4% | 1511.7 ± 3% | 22 / 70 | 57864 ± 4% |
| GCNN | 6.6 ± 3% | 60 / 100 | 134 ± 8% | 42.5 ± 3% | 36 / 100 | 1870 ± 3% | 1489.9 ± 3% | 42 / 70 | 56348 ± 5% |
The authors read this as evidence that sum convolutions generalise better and that the prenorm layer stabilises training §5.3. The GCNN row's node counts differ from tab. 2 (see Pitfalls).
Costs [suppl. §5]. GCNN training took 14.45, 3.84, 18.18 and 4.73 hours on set covering, combinatorial auction, facility location and max independent set. The competitors took at most 2.87 hours, and TREES under 0.2 hours. GCNN features are cheaper to extract, but its prediction is slower [suppl. §5].
Paper vs code
Code: official repository ds4dm/learn2branch at commit
57e82603fba39c34ff81baf9bd0b5768f5a1a860, MIT licence LICENSE.
- Max independent set graphs. Paper: Erdős–Rényi graphs with affinity 4 §5.1. Code: the generator calls
Graph.barabasi_albertwith affinity 4 01_generate_instances.py. An Erdős–Rényi generator exists but the instance path does not call it 01_generate_instances.py. - Expert data collection. Paper: solve with SCIP and record states and strong-branching decisions during B&B [suppl. §1]. Code: the tree is driven by pseudo-cost branching, and the expert is queried at 5% of nodes 02_generate_dataset.py.
- Data-collection time limit. Paper: one-hour limit for evaluation §5.1. Code: 3600 s for training data, 600 s for facility location 02_generate_dataset.py.
- Constraint nodes. Paper: one node per LP row §4.2. Code: one node per finite side, so a two-sided row gives two nodes with opposite-sign features utilities.py.
- Prenorm layers. Paper: one prenorm layer, after the summation §4.3. Code: one after the per-edge pre-activation, and one after the summation model.py.
- Initial embeddings. Paper: none described. Code: a 2-layer ReLU embedding for constraints and for variables, and only a prenorm for edges model.py.
- Embedding width. Paper: not stated. Code: 64 model.py.
- Feature normalisation. Paper: "normalized" only. Code: objective and row norms, and LP age divided by (LP count + 5) utilities.py.
- Model selection. Paper: LR schedule and early stopping [suppl. §2.1]. Code: also restores the best-validation weights and caps training at 1000 epochs 03_train_gcnn.py.
- Pretraining data. Paper: not stated. Code: every 10th training sample file, batch 128 03_train_gcnn.py.
- Epoch definition. Paper: not stated. Code: 312 minibatches of 32 samples drawn with replacement 03_train_gcnn.py.
- Accuracy ties. Code counts a prediction as a hit when its score equals the best score, so ties count 03_train_gcnn.py.
- Time measure. Paper: a 1-shifted geometric mean of solving times in seconds §5.1. Code: CPU user time, clock type 1, limit 3600 05_evaluate.py. The paper does not name the clock.
- Strong branching. Paper: re-implemented in SCIP [suppl. §1]. Code: a patch to SCIP is supplied vanillafullstrong.patch.
No discrepancies were found in the SCIP parameters: root-only separation and disabled restarts match §5.1 utilities.py.
Pitfalls
- Table 2 block labels. In the LaTeX source the four problem titles of tab. 2 sit below their blocks, and the last title sits after the bottom rule. The mapping used here (first block = set covering, then auction, facility location, max independent set) is inferred, not stated. It is supported by three matches, to rounding, between the first block's GCNN times and the GCNN times in tab. 3; by the paper's text on where LMART and RPB win; and by the paper's remark that every learned method solves fewer hard instances than RPB, which holds only for the last block. Check against the PDF before relying on any single cell.
- Node counts disagree within the paper. For set covering, GCNN node counts are 1450 (medium) and 29981 (hard) in tab. 2, but 1870 and 56348 in tab. 3. The times agree to rounding. Either the ablation was run differently or one table is wrong. Cite the times and treat the node counts as uncertain.
- Strong-branching labels need a patched SCIP. Stock SCIP's strong branching changes solver state, so the paper uses a re-implementation [suppl. §1]. Without it, the labels differ from the paper's.
- The sampling policy is not in the paper. The code drives the tree with pseudo-cost and queries the expert at 5% of nodes 02_generate_dataset.py. The state distribution, and so the learned policy, depends on this choice.
- Samples are dropped silently. Any node where a strong-branching score is negative is skipped, which happens when the solver stops early 02_generate_dataset.py.
- Prenorm is frozen once. The shift and scale come from training data and never change §4.3. The code guards zero variance by using scale 1 model.py. A new distribution of instances does not refresh them.
- Un-normalised sums grow with degree. Without prenorm, activations scale with the number of neighbours. The ablation shows the prenorm version generalises better §5.3, so do not drop it.
- Constraint node count depends on the LP. Ranged rows create two nodes, so the graph size is not simply the number of rows utilities.py. Implement this rule exactly or the features will not match the trained weights.
- Normalisation constants are not in the paper. The "+5" in the LP-age feature and the norms used for coefficients, reduced costs and duals are code-only utilities.py. Missing any of them changes every input.
- Competitors trained on less data. SVMrank, LambdaMART and ExtraTrees were trained on 250k candidates because they ran out of memory on the full set [suppl. §2.2]. GCNN-small, trained on the same amount, beats them on accuracy in every column except auction acc@1, where it scores 55.0 against LMART's 57.3 [suppl. §4]. The time comparison in tab. 2 uses the full GCNN training set.
- Generalisation limit. Early experiments on even larger instances showed a drop for the model trained on small ones. The authors say training on larger instances fixes it §6. This result is not in the tables.
- Training cost. GCNN is the slowest to train on every problem [suppl. §5]. Plan for hours of GPU time per problem.
- Missing details. Adam betas, initialiser, maximum epochs and the number of ExtraTrees trees are not in the text. The code sets the initialiser (orthogonal), the epoch cap and the tree count; Adam uses TensorFlow's defaults.
Lineage
- Builds on: imitation of strong branching with ranking or score targets, by Khalil et al. (AAAI 2016), Alvarez et al. (INFORMS JoC 2017) and Hansknecht et al. (2018). This paper uses classification over the expert's choice instead §2. No arXiv ids are given in the text, so none are linked.
- Compared against: SCIP's reliability pseudocost rule (RPB), full strong branching (FSB), and the three learned baselines TREES, SVMRANK and LMART §5.1.
- Superseded by: not stated in this card.
Source and license
Adapted from “Exact Combinatorial Optimization with Graph Convolutional Neural Networks” by Maxime Gasse, Didier Chételat, Nicola Ferroni, Laurent Charlin, Andrea Lodi (arXiv:1906.01629), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/ds4dm/learn2branch at commit 57e82603fba3 (MIT). Any quoted code is shown under that license.