Skip to main content

Balans: Bandit-based Adaptive Large Neighborhood Search

Project description

Balans: Bandit-based Adaptive Large Neighborhood Search

Balans is a meta-solver for Mixed-Integer Programming problems (MIPs) using multi-armed bandit-based adaptive large neighborhood search.

The hybrid framework integrates MABWiser for contextual multi-armed bandits, ALNS for adaptive large neighborhood search, and SCIP or Gurobi for solving mixed-integer linear programming problems.

Quick Start

# ALNS for adaptive large neigborhood search
from alns.select import MABSelector
from alns.accept import HillClimbing, SimulatedAnnealing
from alns.stop import MaxIterations, MaxRuntime

# MABWiser for contextual multi-armed bandits
from mabwiser.mab import LearningPolicy

# Balans meta-solver for solving mixed integer programming problems
from balans.solver import Balans, DestroyOperators, RepairOperators

# Destroy operators
destroy_ops = [DestroyOperators.Crossover,
               DestroyOperators.Dins,
               DestroyOperators.Mutation_25,
               DestroyOperators.Local_Branching_10,
               DestroyOperators.Rins_25,
               DestroyOperators.Proximity_05,
               DestroyOperators.Rens_25,
               DestroyOperators.Random_Objective]

# Repair operators
repair_ops = [RepairOperators.Repair]

# Rewards for online learning feedback loop
best, better, accept, reject = 4, 3, 2, 1

# Bandit selector
selector = MABSelector(scores=[best, better, accept, reject],
                       num_destroy=len(destroy_ops),
                       num_repair=len(repair_ops),
                       learning_policy=LearningPolicy.EpsilonGreedy(epsilon=0.50))

# Acceptance criterion
# accept = HillClimbing() # for pure exploitation 
accept = SimulatedAnnealing(start_temperature=20, end_temperature=1, step=0.1)

# Stopping condition
# stop = MaxRuntime(100)
stop = MaxIterations(10)

# Balans
balans = Balans(destroy_ops=destroy_ops,
                repair_ops=repair_ops,
                selector=selector,
                accept=accept,
                stop=stop,
                mip_solver="scip") # "gurobi"

# Run a mip instance to retrieve results 
instance_path = "data/miplib/noswot.mps"
result = balans.solve(instance_path)

# Results of the best found solution and the objective
print("Best solution:", result.best_state.solution())
print("Best solution objective:", result.best_state.objective())

Quick Start - ParBalans

# Parallel version of Balans, that runs several configurations parallely
from balans.solver import ParBalans
from alns.stop import MaxIterations

# ParBalans to run different Balans configs in parallel and save results
parbalans = ParBalans(n_jobs=2,                 # parallel Balans runs
                      n_mip_jobs=1,             # parallel MIP threads, Only supported by Gurobi solver
                      mip_solver="scip",
                      output_dir="results/", 
                      stop=MaxIterations(10))   # Stop criteria per each run

# Run a mip instance to retrieve several results 
instance_path = "data/miplib/noswot.mps"
best_solution, best_objective = parbalans.run(instance_path)

# Results of the best found solution and the objective
print("Best solution:", best_solution)
print("Best solution objective:", best_objective)

Available Destroy Operators

  • Dins[^1] [^1]: S. Ghosh. DINS, a MIP Improvement Heuristic. Integer Programming and Combinatorial Optimization: IPCO, 2007.
  • Local Branching[^2] [^2]: M. Fischetti and A. Lodi. Local branching. Mathematical Programming, 2003.
  • Mutation[^3] [^3]: Rothberg. An Evolutionary Algorithm for Polishing Mixed Integer Programming Solutions. INFORMS Journal on Computing, 2007.
  • Rens[^4] [^4]: Berthold. RENS–the optimal rounding. Mathematical Programming Computation, 2014.
  • Rins[^5] [^5]: E. Danna, E. Rothberg, and C. L. Pape. Exploring relaxation induced neighborhoods to improve MIP solutions. Mathematical Programming, 2005.
  • Random Objective[^6] [^6]: Random Objective.
  • Proximity Search[^7] [^7]: M. Fischetti and M. Monaci. Proximity search for 0-1 mixed-integer convex programming. Journal of Heuristics, 20(6):709–731, Dec 2014.
  • Crossover[^8] [^8]: E. Rothberg. An Evolutionary Algorithm for Polishing Mixed Integer Programming Solutions. INFORMS Journal on Computing, 19(4):534–541, 2007.

Available Repair Operators

  • Repair MIP

Installation

Balans requires Python 3.10+ can be installed from PyPI via pip install balans.

Test Your Setup

$ cd balans
$ python -m unittest discover tests

Citation

If you use Balans in a publication, please cite it as:

    @inproceedings{balans25,
      author       = {Junyang Cai and
                      Serdar Kadioglu and
                      Bistra Dilkina},
      title        = {BALANS: Multi-Armed Bandits-based Adaptive Large Neighborhood Search for Mixed-Integer Programming Problems},
      booktitle    = {Proceedings of the Thirty-Fourth International Joint Conference on
                      Artificial Intelligence, {IJCAI} 2025, Montreal, Canada, August 16-22,
                      2025},
      pages        = {xx--xx},
      publisher    = {ijcai.org},
      year         = {2025},
      url          = {https://www.ijcai.org/proceedings/2025/xx},
    }

License

Balans is licensed under the Apache License 2.0.


Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

Balans-1.0.0.tar.gz (26.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

balans-1.0.0-py3-none-any.whl (34.0 kB view details)

Uploaded Python 3

Balans-1.0.0-py3-none-any.whl (34.0 kB view details)

Uploaded Python 3

File details

Details for the file Balans-1.0.0.tar.gz.

File metadata

  • Download URL: Balans-1.0.0.tar.gz
  • Upload date:
  • Size: 26.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.11.3

File hashes

Hashes for Balans-1.0.0.tar.gz
Algorithm Hash digest
SHA256 5fa6dcaf5fc2663f854cdcf177113893c37543ab0264df4c24f33037ea3afad2
MD5 d40b16f16940b69927a2be7b1461389e
BLAKE2b-256 3fad8e874fed45a87d35472c891f8b62be11caf5f6c01176c817ad60929534e6

See more details on using hashes here.

File details

Details for the file balans-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: balans-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 34.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.11.3

File hashes

Hashes for balans-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a61c9d0395d4d6e7d2294be2c08815e2f74267578adeade0e12708933fd286a6
MD5 2909ba4716b0de6ee0e45861463c003a
BLAKE2b-256 1641a1e4b671e1867fdc1b35ece46933e4732df92b38e74f6a96963049139c49

See more details on using hashes here.

File details

Details for the file Balans-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: Balans-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 34.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.11.3

File hashes

Hashes for Balans-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 659cab9db0d4ebc23d45dd9e27dc35536e37def0de694a9aa96fd6744f72f742
MD5 ea0ddf69e10e15508be6edf3947e49e5
BLAKE2b-256 46df2f9c21aa0c77e1d3350565ca9c37d791af6a8ccae47de67180aea6c93c0d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page