A parallel branch-and-bound engine for Python.

Overview

pybnb

PyPI-Status PyPI-Versions PyPI-Downloads

Testing-Status Coverage-Status Documentation-Status

Codacy-Grade Mypy Black

A parallel branch-and-bound engine for Python. (https://pybnb.readthedocs.io)

This software is copyright (c) by Gabriel A. Hackebeil ([email protected]).

This software is released under the MIT software license. This license, including disclaimer, is available in the 'LICENSE' file.

Quick Start

Define a problem:

# simple.py

import pybnb
class Simple(pybnb.Problem):
    def __init__(self):
        self.bounds = [0.0,1.0]
    def sense(self):
        return pybnb.minimize
    def objective(self):
        return round(self.bounds[1] - self.bounds[0], 3)
    def bound(self):
        return -(self.bounds[1] - self.bounds[0])**2
    def save_state(self, node):
        node.state = self.bounds
    def load_state(self, node):
        self.bounds = node.state
    def branch(self):
        L, U = self.bounds
        mid = 0.5 * (L + U)
        for l,u in [(L,mid), (mid,U)]:
            child = pybnb.Node()
            child.state = (l,u)
            yield child

Write a solve script:

# solve_simple.py

import simple
problem = simple.Simple()
results = pybnb.solve(problem,
                      absolute_gap=1e-9)

Run the script:

$ mpirun -np 4 python solve_simple.py

Using non-default solver options:
 - absolute_gap: 1e-09 (default: 0)

Starting branch & bound solve:
 - dispatcher pid: 34902 (Ozymandias.local)
 - worker processes: 3
---------------------------------------------------------------------------------------------------------------------------
         Nodes        |                      Objective Bounds                        |              Work
      Expl    Unexpl  |      Incumbent           Bound     Rel. Gap         Abs. Gap | Time (s)  Nodes/Sec Imbalance   Idle
         0         1  |            inf            -inf          inf%             inf |      0.0       0.00     0.00%      0
*        1         2  |              1              -1  200.0000000%               2 |      0.0    1226.99   300.00%      1
*        2         3  |            0.5              -1  150.0000000%             1.5 |      0.0    2966.04   150.00%      0
*        4         5  |           0.25           -0.25   50.0000000%             0.5 |      0.0    8081.95    75.00%      0
*        8         9  |          0.125         -0.0625   18.7500000%          0.1875 |      0.0   12566.90    37.50%      0
      Expl    Unexpl  |      Incumbent           Bound     Rel. Gap         Abs. Gap | Time (s)  Nodes/Sec Imbalance   Idle
*       16        17  |          0.062       -0.015625    7.7625000%        0.077625 |      0.0   15352.74    18.75%      0
*       32        33  |          0.031     -0.00390625    3.4906250%      0.03490625 |      0.0   15981.49    18.75%      0
*       64        65  |          0.016   -0.0009765625    1.6976563%    0.0169765625 |      0.0   18740.68    18.75%      0
*      128       129  |          0.008   -0.0002441406    0.8244141%  0.008244140625 |      0.0   21573.51    11.72%      0
*      256       257  |          0.004   -6.103516e-05    0.4061035%  0.004061035156 |      0.0   22166.96     8.20%      0
      Expl    Unexpl  |      Incumbent           Bound     Rel. Gap         Abs. Gap | Time (s)  Nodes/Sec Imbalance   Idle
*      512       513  |          0.002   -1.525879e-05    0.2015259%  0.002015258789 |      0.0   21177.00     5.86%      0
*     1024      1025  |          0.001   -3.814697e-06    0.1003815%  0.001003814697 |      0.1   19978.42     9.38%      0
*     2048      2049  |              0   -9.536743e-07    0.0000954% 9.536743164e-07 |      0.1   21606.45     5.42%      0
     24029     24030  |              0   -1.490116e-08    0.0000015% 1.490116119e-08 |      1.1   21961.03     5.98%      0
     46159     46160  |              0    -3.72529e-09    0.0000004% 3.725290298e-09 |      2.1   22120.75     5.73%      0
      Expl    Unexpl  |      Incumbent           Bound     Rel. Gap         Abs. Gap | Time (s)  Nodes/Sec Imbalance   Idle
     65537     65538  |              0   -9.313226e-10    0.0000001% 9.313225746e-10 |      3.0   22459.50     6.20%      0
---------------------------------------------------------------------------------------------------------------------------

Absolute optimality tolerance met
Optimal solution found!

solver results:
 - solution_status: optimal
 - termination_condition: optimality
 - objective: 0
 - bound: -9.313226e-10
 - absolute_gap: 9.313226e-10
 - relative_gap: 9.313226e-10
 - nodes: 65537
 - wall_time: 2.96 s
 - best_node: Node(objective=0)

Number of Workers:        3
Load Imbalance:       6.20%
 - min: 21355 (proc rank=3)
 - max: 22710 (proc rank=1)
Average Worker Timing:
 - queue:      80.78% [avg time: 109.6 us, count: 65537]
 - load_state:  0.44% [avg time: 596.1 ns, count: 65537]
 - bound:       0.59% [avg time: 796.1 ns, count: 65537]
 - objective:   3.52% [avg time:   4.7 us, count: 65537]
 - branch:      3.36% [avg time:   4.6 us, count: 65537]
 - other:      11.31% [avg time:  15.3 us, count: 65537]
Comments
  • Redesigning Node Serialization

    Redesigning Node Serialization

    This is a major rewrite of the serialization strategy for nodes.

    Improvements include:

    • much faster serial performance (especially with pypy)
    • removed numpy as a dependency
    • any pickle-able object can be assigned to node.state (no longer needs to be a numpy float array)
      • old way:
      def save_state(self, node):
          node.resize(2)
          node.state[:] = (self.lb, self.ub)
      def load_state(self, node):
          self.lb, self.ub = node.state[:]
      
      • new way:
      def save_state(self, node):
          node.state = (self.lb, self.ub)
      def load_state(self, node):
          self.lb, self.ub = node.state
      
    • lexicographic node priorities can now be used (fixes #4):
      • example: solver.solve(problem, queue_strategy=('bound','objective'))
    • added a config object to allow users to adjust serialization settings (e.g., use dill instead of pickle)
    opened by ghackebeil 6
  • Getting the answers & path out?

    Getting the answers & path out?

    Hey, cool library!

    Maybe I'm missing something here, but it doesn't seem like there's any way to get the answers or the path to the answers out? SolverResults doesn't have the best node and there's no bookeeping to keep the chain of nodes?

    opened by MisterTea 4
  • Access solver attributes within problem

    Access solver attributes within problem

    Hi ! Thank you for the development of this package ! I was wondering if there was a way to call the solver attributes inside the problem methods. For instance, I would like to have access to the best objective within the bound method in the following way :

    class Problem(pybnb.Problem):
        ...
        def bound(self):
            best_objective = self.retrieve_solver_attribute("best_objective")
            return do_bounding_using_best_objective()
        ...
    

    Thank you for your answer, Théo

    opened by TheoGuyard 2
  • Obtain optimal assignment

    Obtain optimal assignment

    Hi Gabriel

    Thanks for a great project!

    I am struggling to find a way to obtain the variables' assignments once I have solved the example knapsack problem and obtained an optimal solution. Somehow I cannot access the decision variables' values leading to the obtained optimal objective value.

    I am assuming there must be a way to obtain the values of each integer variables in the results object, but I cannot figure out how. I have gone through the documentation, but can't seem to find anything. Any help? :)

    opened by alexberndt 2
  • Option to disable queue bound tracking

    Option to disable queue bound tracking

    This PR adds a solver option, track_bound, that allows one to disable functionality that tracks the global queue bound until the solve terminates. This can significantly reduce the overhead for certain queue implementations (except for worst-bound first, which tracks the bound for free).

    opened by ghackebeil 1
  • [WIP] Drop Support for Python 2.x

    [WIP] Drop Support for Python 2.x

    This PR tracks changes that can be made when support for Python 2 is dropped at the end of 2019. So far, changes are almost entirely cosmetic:

    • drop enum34 and six dependency
    • replace class Name(object): with class Name:
    • drop 2 or 3 lines that dealt with bytes <-> str casting
    • use keyword-only arguments

    Type annotations are not included in this PR as they are not entirely supported in Python 3.5. In particular, x: <type> = <value> is only supported outside function declarations in Python 3.6+.

    opened by ghackebeil 1
  • Issue when bound() and objective() methods return numpy types (parallel only)

    Issue when bound() and objective() methods return numpy types (parallel only)

    If the objective/bound computation uses NumPy and happens to return, for instance, a numpy.float64 type, this creates issues when serializing these node attributes through marshal.dumps(...). When the dispatcher receives the node, the call to marshal.loads produces an object of type bytes rather than a number that can be used for computation.

    I think the best fix is to add some code on the worker side that appropriately casts the objective/bound value returned from the problem to an int or float built-in type (possibly do the same with the queue_priority attribute in case the user sets this).

    An alternative would be to use pickle to serialize these node attributes, but I believe this can be noticeable slower than marshal (double check this).

    bug 
    opened by ghackebeil 1
  • Knapsack example

    Knapsack example

    Can you include a knapsack implementation in your examples? I'm struggling a bit with the documentation. It would be helpful for newcomers to familiarize with your library.

    opened by ggaylord 1
  • Formalize nested solver implementation

    Formalize nested solver implementation

    Things to address:

    • [ ] Setting up the communicator tree and listeners could be made easier
    • [ ] Allow load balance and timing statistics to be sent up to the root solver
    TODO 
    opened by ghackebeil 1
  • Allow lexicographic node prioritization in the queue

    Allow lexicographic node prioritization in the queue

    This would require allowing a tuple to be assigned to Node.queue_priority rather than just a number. One could utilize this either by implementing a custom queue strategy, or by setting the queue_strategy option to a tuple of queue strategy names.

    TODO 
    opened by ghackebeil 0
  • Automatically save the best node

    Automatically save the best node

    It can currently be done by the user using optional Problem methods, but it should probably done by the solver.

    Possible implementation:

    • When a worker thinks it has a new best node, send it to the dispatcher on the next update.
    • The dispatcher sends the best node to workers on the final update (or possibly earlier with every update).
    • If load_solution=True (new solver options, default True), load_state will be called with this node rather than the root at the end of the solve. If load_solution=False, the node will be placed on the results object.
    TODO 
    opened by ghackebeil 0
  • Multihreading instead of multiprocessing

    Multihreading instead of multiprocessing

    Hi there, Will there ever be a multithreading support instead of the already implemented multiprocess version? This may be very useful if multiple nodes share a child, and the bound() function makes use of all parents infos.

    opened by DarioSimonato 1
Releases(0.6.2)
  • 0.6.2(Dec 10, 2019)

  • 0.6.1(Mar 30, 2019)

  • 0.6.0(Mar 12, 2019)

    This is a major release that changes default optimality and tolerance settings to make solver behavior more intuitive. It also includes a new option for reducing dispatcher overhead for non-default queue strategies.

    Source code(tar.gz)
    Source code(zip)
  • 0.5.2(Feb 13, 2019)

    This is a minor release that adds a configuration option to enable compression and fixes a serialization issues when the bound or objective Problem methods return NumPy scalar types.

    Source code(tar.gz)
    Source code(zip)
  • 0.5.1(Feb 11, 2019)

    This is a minor release that includes some improvements to the documentation as well as fixes for some edge case behavior for unbounded problems.

    Source code(tar.gz)
    Source code(zip)
  • 0.5.0(Feb 10, 2019)

    This is a major release that includes some backward incompatible changes. Major changes include:

    • automatically saving the best node (rather than just the best objective)
    • changing the signature of the branch method so that it has more clear semantics
    • removing / renaming some of the optional problem callbacks
    • adding built-in support for nested solver implementations
    Source code(tar.gz)
    Source code(zip)
  • 0.4.0(Jan 31, 2019)

  • 0.3.0(Jan 21, 2019)

    This is a major release that includes some backward incompatible changes. Major changes include

    • renaming of a few solver options
    • addition of options for early termination of a solve
    • new queue management strategies
    • improvements to the online documentation
    Source code(tar.gz)
    Source code(zip)
  • 0.2.9(Dec 3, 2018)

  • 0.2.8(Nov 26, 2018)

  • 0.2.7(Nov 26, 2018)

  • 0.2.6(Jul 13, 2018)

    This minor release includes changes that improve dispatcher performance. It also includes an additional queue strategy that prioritizes nodes with the best objective first.

    Source code(tar.gz)
    Source code(zip)
  • 0.2.5(May 30, 2018)

  • 0.2.4(May 26, 2018)

    This release fixes a bug in pyomo_tools that left uncollected messages on the communicator. See the CHANGELOG for additional details about this release.

    Source code(tar.gz)
    Source code(zip)
  • 0.2.3(May 22, 2018)

  • 0.2.2(May 22, 2018)

  • 0.2.0(May 22, 2018)

Owner
Gabriel Hackebeil
Gabriel Hackebeil
Prop-based map editor for the Apex Legends mod, R5Reloaded

R5R Map Editor A tool to build maps out of props in the Apex Legends mod, R5Reloaded Instuctions Install R5R Download this program Get the prop spawne

7 Dec 16, 2022
Got-book-6 - LSTM trained on the first five ASOIAF/GOT books

GOT Book 6 Generator Are you tired of waiting for the next GOT book to come out? I know that I am, which is why I decided to train a RNN on the first

Zack Thoutt 974 Oct 27, 2022
Python client library for the Databento API

Databento Python Library The Databento Python client library provides access to the Databento API for both live and historical data, from applications

Databento, Inc. 35 Dec 24, 2022
A simple wrapper for joy library

Joy CodeGround A simple wrapper for joy library to render joy sketches in browser using vs code, (or in other words, for those who are allergic to Jup

rijfas 9 Sep 08, 2022
LINUX-AOS (Automatic Optimization System)

LINUX-AOS (Automatic Optimization System)

1 Jul 12, 2022
People tracker on the Internet: OSINT analysis and research tool by Jose Pino

trape (stable) v2.0 People tracker on the Internet: Learn to track the world, to avoid being traced. Trape is an OSINT analysis and research tool, whi

Jose Pino 7.3k Dec 30, 2022
Fly DCS without a joystick

Intro Usage Delete all mouse view axis Install DCSEasyControlExports to your "Saved Games/DCS/" Path python DCSEasyControl/main.py Set DCS to F12 view

XuHao 36 Dec 27, 2022
Feature engineering library that helps you keep track of feature dependencies, documentation and schema

Feature engineering library that helps you keep track of feature dependencies, documentation and schema

28 May 31, 2022
Transform a Google Drive server into a VFX pipeline ready server

Google Drive VFX Server VFX Pipeline About The Project Quick tutorial to setup a Google Drive Server for multiple machines access, and VFX Pipeline on

Valentin Beaumont 17 Jun 27, 2022
Mmr image postbot - Бот для создания изображений с новыми релизами в сообщество ВК MMR Aggregator

Mmr image postbot - Бот для создания изображений с новыми релизами в сообщество ВК MMR Aggregator

Max 3 Jan 07, 2022
A collection of common regular expressions bundled with an easy to use interface.

CommonRegex Find all times, dates, links, phone numbers, emails, ip addresses, prices, hex colors, and credit card numbers in a string. We did the har

Madison May 1.5k Dec 31, 2022
Xbox-Flood is for flood anything

Intruduction Installation Usage Installing Python 3 Wiki Getting Started Creating a Key Intruduction Xbox-Flood is for flooding messages (invitations

kayake 4 Feb 18, 2022
Very simple encoding scheme that will encode data as a series of OwOs or UwUs.

OwO Encoder Very simple encoding scheme that will encode data as a series of OwOs or UwUs. The encoder is a simple state machine. Still needs a decode

1 Nov 15, 2021
Python script to combine the statistical results of a TOPAS simulation that was split up into multiple batches.

topas-merge-simulations Python script to combine the statistical results of a TOPAS simulation that was split up into multiple batches At the top of t

Sebastian Schäfer 1 Aug 16, 2022
A Python library for inspecting JVM class files (.class)

lawu Lawu is a human-friendly library for assembling, disassembling, and exploring JVM class files. It's highly suitable for automation tasks. Documen

Tyler Kennedy 45 Oct 23, 2022
Draw random mazes in python

a-maze Draw random mazes in python This program generates and draws a rectangular maze, with an entrance on one side and one on the opposite side. The

Andrea Pasquali 1 Nov 21, 2021
An extended, game oriented, turtle

Burtle A Better TURTLE. Makes making games easier. write less do more!! Documentation & guide: https://alannxq.github.io/burtle/ Installation pip inst

5 May 19, 2022
Airplane reservation system python 2

airplane-reservation-system-python-2 Announcement 🔊 : 🔴 IMPORTANT 🔴 : Few new things have been added into the code [16/05/2021] different names is

voyager2005 1 Dec 06, 2021
Kivy program for identification & rotation sensing of objects on multi-touch tables.

ObjectViz ObjectViz is a multitouch object detection solution, enabling you to create physical markers out of any reliable multitouch solution. It's e

TangibleDisplay 8 Apr 04, 2022
Opendrop - An open Apple AirDrop implementation written in Python

OpenDrop: an Open Source AirDrop Implementation OpenDrop is a command-line tool that allows sharing files between devices directly over Wi-Fi. Its uni

Secure Mobile Networking Lab 7.5k Jan 03, 2023