50#include <unordered_map>
51#include <unordered_set>
62template<
typename TWeight>
85 std::unique_ptr<AlternatingTree<TWeight>>
m_tree;
87#ifdef OGDF_HEAVY_DEBUG
89 void assertConsistency() {
113 if (v !=
m_tree->root()) {
134 long unsigned int hiddenNodes = 0;
135 for (
auto entry :
m_helper.pseudonodes()) {
136 auto pseudonode = entry.second;
137 hiddenNodes += pseudonode->cycle->nodes().size();
138 for (
node v : pseudonode->cycle->nodes()) {
143 == (
size_t)
m_helper.graph().numberOfNodes());
179 std::unordered_set<edge>& matching) {
180 return _doCall(G, weights, matching);
188 template<
class WeightContainer>
189 bool _doCall(
const Graph& G,
const WeightContainer& weights, std::unordered_set<edge>& matching) {
226#ifdef OGDF_HEAVY_DEBUG
232 lout() <<
"new root: " <<
m_tree->root() << std::endl;
239 m_helper.getOriginalMatching(matching);
245#ifdef OGDF_HEAVY_DEBUG
246 std::unordered_map<edge, TWeight> edgeWeights;
247 m_helper.getReducedEdgeWeights(edgeWeights);
251#ifdef OGDF_HEAVY_DEBUG
252 m_helper.assertConsistentEdgeWeights(edgeWeights);
264 for (
adjEntry adj : u->adjEntries) {
265 node v = adj->twinNode();
268 m_tree->augmentMatching(adj->theEdge());
272 lout() <<
"augmented matching with " << adj->theEdge() << std::endl;
287 for (
adjEntry adj : u->adjEntries) {
288 node v = adj->twinNode();
290 if (matchingEdge && !
m_tree->contains(v)) {
291 m_tree->grow(u, adj->theEdge(), matchingEdge);
292 lout() <<
"augmented tree with " << adj->theEdge() << std::endl;
307 for (
adjEntry adj : u->adjEntries) {
308 node v = adj->twinNode();
336 TWeight delta = infinity<TWeight>();
341 for (
adjEntry adj : u->adjEntries) {
342 node v = adj->twinNode();
343 TWeight potentialChange =
m_helper.getReducedWeight(adj->theEdge());
346 potentialChange *= 0.5;
347 }
else if (
m_tree->isOdd(v)) {
352 delta = std::min(delta, potentialChange);
358 delta = std::min(delta,
m_helper.y(v));
362 if (delta == infinity<TWeight>()) {
376 for (
adjEntry adj : v->adjEntries) {
377 edge e = adj->theEdge();
388 for (
adjEntry adj : u->adjEntries) {
389 node v = adj->twinNode();
390 edge e = adj->theEdge();
397 lout() <<
"dual change: " << delta << std::endl;
405 std::vector<std::tuple<edge, bool>> selfLoops;
414 for (
auto adj : u->adjEntries) {
415 edge e = adj->theEdge();
424 if (
m_helper.matching(newNode) ==
nullptr) {
427 lout() <<
"shrunk odd cycle of length " << cycle->
nodes().size() <<
" at " << cycleEdge
428 <<
" into pseudonode " << pseudonode->
graphNode << std::endl;
439 int pseudonodeIndex = graphNode->
index();
440 m_tree->expand(pseudonode);
445 for (
auto adj : u->adjEntries) {
446 edge e = adj->theEdge();
454 lout() <<
"expanded pseudonode " << pseudonodeIndex << std::endl;
Implementation of an Alternating Tree helper structure for the Blossom algorithm.
Utility class for the Blossom algorithm, providiing access to all important data structures.
Utility class representing a cycle in the Blossom algorithm.
Includes declaration of graph class.
Declaration of class GraphAttributes which extends a Graph by additional attributes.
Decralation of GraphElement and GraphList classes.
Contains logging functionality.
Declaration of interface for matching algorithms.
Helper structure representing a pseudonode in the Blossom algorithm.
Basic declarations, included by all source files.
Class for adjacency list elements.
Class for the representation of edges.
Functionality for temporarily hiding edges in constant time.
Stores additional attributes of a graph (like layout information).
const Graph & constGraph() const
Returns a reference to the associated graph.
Data type for general directed graphs (adjacency list representation).
std::ostream & lout(Level level=Level::Default, bool indent=true) const
stream for logging-output (local)
Implementation of the Blossom-I algorithm by Edmonds (1965) for Minimum Weight Perfect Matching.
bool findShrinkableCycle()
Finds and shrinks an odd cycle, if possible.
bool dualChange()
Executes a dual change step.
MatchingBlossom(bool greedyInit=true)
Construct a MatchingBlossom instance.
bool findMatchingAugmentation()
Finds and executes a matching augmentation, if possible.
bool findExpandablePseudonode()
Finds and expands an odd pseudonode, if possible.
bool doCall(const Graph &G, const EdgeArray< TWeight > &weights, std::unordered_set< edge > &matching)
Main call function for the algorithm with an EdgeArray as weight container.
void expand(Pseudonode *pseudonode)
Expand the pseudonode pseudonode.
std::unordered_set< edge > m_nonEqualityEdges
Set of all non-equality edges.
std::unordered_set< node > m_unmatchedNodes
All nodes which are not part of the matching yet.
void shrink(edge cycleEdge)
Shrink the odd cycle induced by the current tree together with cycleEdge.
bool findTreeAugmentation()
Finds and executes a tree augmentation, if possible.
void hideNonEqualityEdges()
Helper function to hide all non-equality edges.
std::ostream & lout(Level level=Level::Default, bool indent=true) const
stream for logging-output (local)
std::unique_ptr< Graph::HiddenEdgeSet > m_nonEqualityEdgesHiddenSet
Pointer to the HiddenEdgeSet containing all non-equality edges.
bool primalChange()
Executes a primal change step.
bool doCall(const GraphAttributes &GA, std::unordered_set< edge > &matching)
Main call function for the algorithm with GraphAttrubtes as weight container.
BlossomHelper< TWeight > m_helper
Helper class to store the current state of the algorithm.
std::unordered_set< node > m_graphNodes
All nodes currently present in the graph.
std::unique_ptr< AlternatingTree< TWeight > > m_tree
The alternating tree.
std::unordered_set< node > m_pseudonodes
All top-level pseudonodes.
bool findMatching(std::unordered_set< edge > &matching)
Main function of the algorithm.
node getNewRoot()
Helper function to get a new root for the tree.
bool _doCall(const Graph &G, const WeightContainer &weights, std::unordered_set< edge > &matching)
Helper for the main call function since abstract functions cannot be templated.
void restoreNonEqualityEdges()
Helper function to restore all non-equality edges.
Class for the representation of nodes.
int index() const
Returns the (unique) node index.
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Helper class for the blossom matching algorithms.
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.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
The namespace for all OGDF objects.