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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file balans-1.0.1.tar.gz.
File metadata
- Download URL: balans-1.0.1.tar.gz
- Upload date:
- Size: 28.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.11.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af3b38547cf445ae02054d37a80da3d12eb6500568512fd92b9d9aed9c996a16
|
|
| MD5 |
e0fb25dcc89a0f27005f0d4c1676368b
|
|
| BLAKE2b-256 |
a815f7acbe4172d37788ec17f31e23271c47e908f0af06117d3ed6662d73b777
|
File details
Details for the file balans-1.0.1-py3-none-any.whl.
File metadata
- Download URL: balans-1.0.1-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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f31a48a2b03b8e6605bc7b964661b67782ea2ba52c6ee76e73810684cdcc3cf9
|
|
| MD5 |
85960af7bde0c6cd0bf5de98468d5072
|
|
| BLAKE2b-256 |
ef55e8c3268b40f96a5436345b9a10b52cef17ba4eb6479d8c73d6badceafa79
|