Package Class Diagram
The core components of the package are:
Problem: Abstract base class representing a discrete optimization (sub)problem. Users subclass it to define bounding, feasibility, and branching logic.
BranchAndBound: The main search engine. It traverses the search tree, tracks incumbent solutions and global bounds, and delegates node selection to a manager.
Node: Wraps a
Probleminstance and maintains the rooted tree structure (parent, children, depth level).BaseNodeManager: Abstract interface for storing unexplored nodes and deciding which node to explore next. Concrete implementations define the search strategy.
Solution: Holds the optimization status, lower bound, and cost (upper bound) for a given subproblem.
OptStatus: Enum encoding possible optimization states (
OPTIMAL,FEASIBLE,INFEASIBLE, etc.).
A concise class diagram can be represented as shown below.
classDiagram
direction LR
class Solution {
+cost : double
+lb : double
+status : OptStatus
}
class Problem {
<<abstract>>
+solution : Solution
+calc_bound()* double
+is_feasible()* bool
+branch()* list~Problem~
}
class Node {
+problem : Problem
+parent : Node
+level : int
+lb : double
+children : list~Node~
}
class BaseNodeManager {
<<abstract>>
+enqueue(node)*
+dequeue()* Node
}
class BranchAndBound {
+problem : Problem
+root : Node
+manager : BaseNodeManager
+incumbent : Node
+bound_node: Node
}
Problem *-- Solution
Node *-- Problem
BranchAndBound --> Problem
BranchAndBound --> Node : root, incumbent, bound_node
BranchAndBound o-- BaseNodeManager : manager
BaseNodeManager ..> Node : enqueue, dequeue
Which, in a more detailed form, can encompass additional elements.
classDiagram
direction LR
class OptStatus {
<<enumeration>>
NO_SOLUTION
RELAXATION
OPTIMAL
FEASIBLE
INFEASIBLE
FATHOM
}
class Solution {
+cost : double
+lb : double
+status : OptStatus
+set_optimal()
+set_feasible()
+set_infeasible()
+fathom()
}
class Problem {
<<abstract>>
+solution : Solution
+calc_bound()* double
+is_feasible()* bool
+branch()* list~Problem~
+warmstart() Problem
+primal_heuristic() Problem
+stronger_bound() double
}
class Node {
+problem : Problem
+parent : Node
+level : int
+lb : double
+children : list~Node~
+compute_bound()
+check_feasible() bool
+branch() list~Node~
+primal_heuristic() Node
}
class BaseNodeManager {
<<abstract>>
+enqueue(node)*
+dequeue()* Node
+not_empty()* bool
+size()* int
+get_lower_bound()* Node
+filter_by_lb(max_lb)
+clear()
}
class SearchResults {
+solution : Solution
+problem : Problem
}
class BranchAndBound {
+problem : Problem
+root : Node
+manager : BaseNodeManager
+incumbent : Node
+bound_node: Node
+explored : int
+gap : double
+rtol : double
+atol : double
+solve(maxiter, maxtime) SearchResults
+branch(node)
+prune(node)
+primal_heuristic(node)
+set_manager(manager)
+reset()
}
Solution --> OptStatus
Problem *-- Solution
Node *-- Problem
Node o-- Node : parent / children
BranchAndBound --> Problem
BranchAndBound --> Node : root, incumbent, bound_node
BranchAndBound o-- BaseNodeManager : manager
BranchAndBound ..> SearchResults : returns
BaseNodeManager ..> Node : enqueue, dequeue
SearchResults --> Solution
SearchResults --> Problem