50#include <unordered_map>
51#include <unordered_set>
56namespace matching_blossom {
59template<
class TWeight>
88 static const int WEIGHT_FACTOR = std::numeric_limits<TWeight>::is_integer ? 4 : 1;
95 if (v->degree() == 0) {
107 edge matchingEdge =
nullptr;
108 TWeight maxChange = infinity<TWeight>();
109 for (
auto adj : v->adjEntries) {
110 edge e = adj->theEdge();
111 node w = adj->twinNode();
113 if (
m_eps.
leq(reducedWeight, maxChange)) {
114 maxChange = reducedWeight;
127 lout() <<
"initial y for node " << v <<
": " <<
y(v) << std::endl;
129 if (e && e->
source() == v) {
132 lout() <<
"initial matching edge: " << e << std::endl;
167#ifdef OGDF_HEAVY_DEBUG
168 void getReducedEdgeWeights(std::unordered_map<edge, TWeight>& edges) {
170 if (
repr(e->source()) == e->source() &&
repr(e->target()) == e->target()) {
176 void assertConsistentEdgeWeights(std::unordered_map<edge, TWeight>& edges) {
178 if (
repr(e->source()) == e->source() &&
repr(e->target()) == e->target()
179 && edges.find(e) != edges.end()) {
196 template<
class WeightContainer>
206 if (e->isSelfLoop()) {
207 throw std::runtime_error(
"Self-loops are not supported.");
213 auto halfWeight = weight / 2;
214 for (
node v : e->nodes()) {
215 if (minY[v] == -1 ||
m_eps.
less(halfWeight, minY[v])) {
216 minY[v] = halfWeight;
259 if (parent == v || parent ==
nullptr) {
264 if (parent ==
nullptr) {
275 if (parent == shortcut || parent ==
nullptr) {
326 if (v !=
nullptr &&
repr(target) == v) {
327 return {target, source};
330 return {source, target};
353 std::vector<Pseudonode*> stack;
355 if (
repr(entry.first) == entry.first) {
356 stack.push_back(entry.second);
360 while (!stack.empty()) {
375 auto startIndex = cycle->indexOf(matchedNode);
376 auto edges = cycle->edgeOrder();
380 for (
size_t i = 2; i < edges.size(); i += 2) {
381 edge e = edges[(startIndex + i) % edges.size()];
385 for (
node v : cycle->nodes()) {
387 stack.push_back(child);
Utility class representing a cycle in the Blossom algorithm.
Compare floating point numbers with epsilons and integral numbers with normal compare operators.
Includes declaration of graph class.
Declaration of graph copy classes.
Decralation of GraphElement and GraphList classes.
Contains logging functionality.
Helper structure representing a pseudonode in the Blossom algorithm.
Basic declarations, included by all source files.
Class for the representation of edges.
node target() const
Returns the target node of the edge.
node source() const
Returns the source node of the edge.
std::enable_if< std::is_integral< T >::value, bool >::type leq(const T &x, const T &y) const
Compare if x is LEQ than y for integral types.
std::enable_if< std::is_integral< T >::value, bool >::type less(const T &x, const T &y) const
Compare if x is LESS than y for integral types.
std::enable_if< std::is_integral< T >::value, bool >::type equal(const T &x, const T &y) const
Compare if x is EQUAL to y for integral types.
void delNode(node v) override
Removes node v.
void init(const Graph &G)
Re-initializes the copy using G, creating copies for all nodes and edges in G.
const Graph & original() const
Returns a reference to the original graph.
Copies of graphs with mapping between nodes and edges.
void clear() override
Removes all nodes and edges from this copy but does not break the link with the original graph.
edge copy(edge e) const override
Returns the edge in the graph copy corresponding to e.
Data type for general directed graphs (adjacency list representation).
int numberOfNodes() const
Returns the number of nodes in the graph.
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Centralized global and local logging facility working on streams like std::cout.
std::ostream & lout(Level level=Level::Default, bool indent=true) const
stream for logging-output (local)
Class for the representation of nodes.
int index() const
Returns the (unique) node index.
void init(const Base *base=nullptr)
Reinitializes the array. Associates the array with the matching registry of base.
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
RegisteredArray for nodes, edges and adjEntries of a graph.
Helper class for the blossom matching algorithms.
bool m_greedyInit
Whether or not to use the greedy initialization.
std::vector< node > m_shortcuts
A shortcut array for the tree, mapping each node index to the penultimate node.
EdgeArray< TWeight > m_c
LP-induced data used by the algorithm.
bool isZeroCostNode(node v)
Checks whether v is a zero-cost node, i.e. the y value is 0.
std::pair< node, node > getBaseNodes(edge e, node v=nullptr)
Return both original end points of e where the first end point is currently represented by v.
TWeight getReducedWeight(edge e)
Returns the reduced weight of e, taking into account the y values of the endpoints.
TWeight & c(edge e)
Returns the base edge weight of e.
node reprChild(node v)
Returns the child of the representative of v in the tree induced by the pseudonodes.
GraphCopySimple & graph()
node findParentInRepr(node v, node child=nullptr)
Finds the parent of v in the tree induced by the pseudonodes.
TWeight & y(node v)
Returns the base y value of v.
std::unordered_map< node, Pseudonode * > & pseudonodes()
void getOriginalMatching(std::unordered_set< edge > &matching)
Fills matching with the original edges which correspond to the edges in m_matching after expanding it...
std::unordered_map< node, Pseudonode * > m_pseudonodes
A mapping of all pseudonodes in the graph.
std::vector< node > m_repr
The tree induced by the pseudonodes, mapping each node index to its parent.
NodeArray< edge > m_matching
The current matching, mapping both endpoints to the corresponding matching edge.
GraphCopySimple m_graph
A copy of the graph to work on.
void addToMatching(edge e)
Adds the edge e to the matching.
void addPseudonode(Pseudonode *pseudonode)
Adds a pseudonode to the current representation structure.
NodeArray< edge > & matching()
void deletePseudonodes()
Deletes all pseudonodes.
static const int WEIGHT_FACTOR
EpsilonTest m_eps
The epsilon test used for floating point comparisons.
virtual bool isEqualityEdge(edge e)
Checks whether e is an equality edge, i.e. the reduced weight is 0.
node getOppositeBaseNode(edge e, node v)
Returns the original end point of e where the other end point is currently represented by v.
node repr(node v)
Returns the representative of v in the tree induced by the pseudonodes.
node getBaseNode(edge e, node v)
Returns the original end point of e which is currently represented by v.
bool isZero(TWeight x)
Helper function to determine whether a floating point value is 0.
void expandRepr(Pseudonode *pseudonode)
Expands a pseudonode in the current representation structure.
Pseudonode * pseudonode(node v)
Returns the pseudonode corresponding to v, or nullptr if v is not a pseudonode.
virtual TWeight getRealReducedWeight(edge e)
Returns the real reduced weight. Can be overridden by subclasses to consider additional factors.
edge & matching(node v)
Returns the matching edge of v, or nullptr if v is not matched.
bool initDualSolution(NodeArray< TWeight > &minY)
Initializes the dual solution with the given y values.
void removePseudonode(Pseudonode *pseudonode)
Removes a pseudonode from the current representation structure.
BlossomHelper(bool greedyInit)
Construct a new Blossom V Helper object.
bool isPseudonode(node v)
Checks whether v is a pseudonode.
bool init(const Graph &graph, const WeightContainer &weights)
Reinitialize the helper class with a new graph and edge weights. Resets all helper members....
const std::unordered_set< node > & nodes()
Helper class representing a pseudonode in the Blossom algorithm.
Cycle * cycle
The odd-length cycle that this pseudonode represents.
node graphNode
The node in the graph that this pseudonode is linked to.
Utility functions and classes regarding map access and iteration.
EdgeElement * edge
The type of edges.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
V * tryGetPointerFromMap(const std::unordered_map< K, V * > &map, const K &key)
Return the pointer belonging to key key int the given map map, or nullptr if key does not exist.
The namespace for all OGDF objects.