|
| 1 | +from pyscipopt import Branchrule, SCIP_RESULT |
| 2 | +from helpers.utils import random_mip_1 |
| 3 | + |
| 4 | +import numpy as np |
| 5 | + |
| 6 | + |
| 7 | +class MostInfBranchRule(Branchrule): |
| 8 | + |
| 9 | + def __init__(self, scip): |
| 10 | + self.scip = scip |
| 11 | + |
| 12 | + def branchexeclp(self, allowaddcons): |
| 13 | + |
| 14 | + # Get the branching candidates. Only consider the number of priority candidates (they are sorted to be first) |
| 15 | + # The implicit integer candidates in general shouldn't be branched on. Unless specified by the user |
| 16 | + # npriocands and ncands are the same (npriocands are variables that have been designated as priorities) |
| 17 | + branch_cands, branch_cand_sols, branch_cand_fracs, ncands, npriocands, nimplcands = self.scip.getLPBranchCands() |
| 18 | + |
| 19 | + # Find the variable that is most fractional |
| 20 | + best_cand_idx = 0 |
| 21 | + best_dist = np.inf |
| 22 | + for i in range(npriocands): |
| 23 | + if abs(branch_cand_fracs[i] - 0.5) <= best_dist: |
| 24 | + best_dist = abs(branch_cand_fracs[i] - 0.5) |
| 25 | + best_cand_idx = i |
| 26 | + |
| 27 | + # Branch on the variable with the largest score |
| 28 | + down_child, eq_child, up_child = self.model.branchVarVal( |
| 29 | + branch_cands[best_cand_idx], branch_cand_sols[best_cand_idx]) |
| 30 | + |
| 31 | + return {"result": SCIP_RESULT.BRANCHED} |
| 32 | + |
| 33 | + |
| 34 | +def test_branch_mostinfeas(): |
| 35 | + scip = random_mip_1(node_lim=1000, small=True) |
| 36 | + most_inf_branch_rule = MostInfBranchRule(scip) |
| 37 | + scip.includeBranchrule(most_inf_branch_rule, "python-mostinf", "custom most infeasible branching rule", |
| 38 | + priority=10000000, maxdepth=-1, maxbounddist=1) |
| 39 | + scip.optimize() |
0 commit comments