wikunia / bonobo.jl Goto Github PK
View Code? Open in Web Editor NEWA general branch and bound framework
Home Page: https://wikunia.github.io/Bonobo.jl/dev
License: MIT License
A general branch and bound framework
Home Page: https://wikunia.github.io/Bonobo.jl/dev
License: MIT License
I would like to add a generic debugging tool to this which saves the tree nodes in a json file as this is extremely helpful in my ConstraintSolver project.
This project would simply need to create this JSON struct and I need to refine and publish my Javascript visual branch and bound debgugger then ๐
The "interface" can be seen here:
https://opensourc.es/blog/constraint-solver-bugs-and-benchmarks/#the_real_bug
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.
Save a struct options inside the tree object to save all kinds of options including:
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.
Hi, thanks for this really cool package! Does Bonobo support heuristic callbacks?
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.
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
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
I would like to add a generic debugging tool to this which saves the tree nodes in a json file as this is extremely helpful in my ConstraintSolver project.
This project would simply need to create this JSON struct and I need to refine and publish my Javascript visual branch and bound debgugger then ๐
The "interface" can be seen here:
https://opensourc.es/blog/constraint-solver-bugs-and-benchmarks/#the_real_bug
Currently the search continues even if we find the best solution at the very first step.
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
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
traverse_strategy = BFS,
branch_strategy = FIRST,
should be
traverse_strategy = BFS(),
branch_strategy = FIRST(),
and overall expect values with subtypes of AbstractXY.
The reason is that some additional strategies might take parameters stored as values
Being able to store several solutions (all optimal solutions or even all solutions)
@JuliaRegistrator register()
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.
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!
There should be an easy way of logging the current status to a table see https://opensourc.es/blog/table-logging/index.html for more info.
Maybe this can be another package as well though.
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
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?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.