GithubHelp home page GithubHelp logo

wikunia / bonobo.jl Goto Github PK

View Code? Open in Web Editor NEW
30.0 5.0 2.0 275 KB

A general branch and bound framework

Home Page: https://wikunia.github.io/Bonobo.jl/dev

License: MIT License

Julia 100.00%
optimization-tools julia-language hacktoberfest

bonobo.jl's Introduction

Bonobo

Stable Dev Build Status Coverage

bonobo.jl's People

Contributors

github-actions[bot] avatar matbesancon avatar wikunia avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

bonobo.jl's Issues

Branching split up into several steps

Currently branch! is a single function I think it makes sense to split it up into:

  • get_branching_variable
  • branch_on_variable

or even

  • get_branching_variable
  • get_left_node
  • get_right_node

maybe also a combination of the two is possible.
By calling the lower one as a default but allowing the way like this:

var = get_branching_variable(tree, node)
branch_on_variable(tree, node, var)

branch_on_variable(tree, node, var) = get_left_node(tree, node, var); get_right_node(tree, node, var)

this way there is a possibility to have more than two children easily.

Options

Save a struct options inside the tree object to save all kinds of options including:

  • traversing strategy
  • printing
  • branching strategy
  • all_solutions
  • all_optimal_solutions

This can be a struct just for options regarding Bonobo. For options that are needed from the user for their own implementation of details these can be stored in the root struct itself.

update tree.lb

We currently have to set the lower bound in our callback:
tree.lb = min(minimum([prio[2][1] for prio in tree.node_queue]), tree.incumbent)
Otherwise tree.lb and tree.incumbent are not the same in the last iteration.

The lower bound should be updated in the optimize! loop directly.

structfromnt lacks flexibility

It does require all structs of the node to be passed as info, it is not super idiomatic since it does not leverage multiple constructors for instance.
I would remove it in favour of dispatch IMO

tree.solutions naming

Solutions should collect all solutions in the search process and have a way to sort them by objective value OR should be renamed to best_solution to indicate it is unique

make add_new_solution! more flexible

function add_new_solution!(tree::BnBTree{N,R,V,S}, node::AbstractNode) where {N,R,V,S<:DefaultSolution{N,V}}
    sol = DefaultSolution(node.ub, get_relaxed_values(tree, node), node)
    if isempty(tree.solutions)
        push!(tree.solutions, sol)
    else
        tree.solutions[1] = sol
    end
end

This assumes that the solution is computed from get_relaxed_values, the function should take other arguments for the solution itself and its value.

On example is when another subroutine (like a heuristic run at the node) is finding a feasible solution different from the relaxed vector

Rename cb to callback

This will make the argument more understandable for people not used to the terminology. It should also be documented what is expected and allowed in the callback (I think mostly everything?) and at which stage it is supposed to remain

Close nodes when finding a solution

Hello,
I just tested a binary minimization problem using the Bonobo tree structure and realized that even after finding a possible optimal solution nodes were evaluated whose parent had a worse lower bound than the incumbent. I checked the source code and I think the issue stems from the fact then a new node is added its lower bound is always set to -Inf. (nodes.jl line 51)

function add_node!(tree::BnBTree{Node}, node_info::NamedTuple) where Node <: AbstractNode
node_id = tree.num_nodes + 1
node = create_node(Node, node_id, node_info)
tree.nodes[node_id] = node
tree.num_nodes += 1
end

function create_node(Node, node_id::Int, node_info::NamedTuple)
bnb_node = structfromnt(BnBNodeInfo, (id = node_id, lb = -Inf, ub = Inf)) # here!
bnb_nt = (std = bnb_node,)
node_nt = merge(bnb_nt, node_info)
return structfromnt(Node, node_nt)
end

The node should inherit the lower bound from its parent otherwise we can never close nodes without evaluating them.

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

Only set tree.lb if lower bound over nodes is smaller than incunbent

In some cases in the last nodes, we can have a lower bound that is greater than the incumbent (if all incoming nodes are about to be pruned because infeasible or greater than the incumbent). The tree lower bound should always remain below, if we are about to update it to a value greater than the incumbent, clip to the incumbent instead for printing purposes

When should tree.lb be updated

We realized recently that tree.lb is never used nor updated(in Bonobo nor in the user implementation)

When should it be done? Should it be included in the Bonobo mechanism in itself or expected in one of the user functions?

The moment at which it should be done is also non-trivial to determine, after having processed all the children of the node that was previously the current active lower bound?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.