26#ifndef OR_TOOLS_GRAPH_PERFECT_MATCHING_H_ 
   27#define OR_TOOLS_GRAPH_PERFECT_MATCHING_H_ 
   35#include "absl/base/attributes.h" 
   61  void Reset(
int num_nodes);
 
  103    DCHECK(optimal_solution_found_);
 
  104    return optimal_cost_;
 
 
  110    DCHECK(optimal_solution_found_);
 
  111    return matches_[node];
 
 
  114    DCHECK(optimal_solution_found_);
 
 
  119  std::unique_ptr<BlossomGraph> graph_;
 
  125  bool optimal_solution_found_ = 
false;
 
  126  int64_t optimal_cost_ = 0;
 
  127  int64_t maximum_edge_cost_ = 0;
 
  128  std::vector<int> matches_;
 
 
  352  int NumMatched()
 const { 
return nodes_.size() - unmatched_nodes_.size(); }
 
  408  void AppendNodePathToRoot(
NodeIndex n, std::vector<NodeIndex>* path) 
const;
 
  414  void AddToDualObjective(
CostValue delta);
 
  421    return root_blossom_node_[edge.tail];
 
  424    return root_blossom_node_[edge.head];
 
  431    return root_blossom_node_[edge.OtherEnd(node)];
 
  439      DCHECK_EQ(node, Tail(edge));
 
  448  const std::vector<NodeIndex>& SubNodes(
NodeIndex n);
 
  451  bool is_initialized_ = 
false;
 
  454  util_intops::StrongVector<EdgeIndex, Edge> edges_;
 
  455  util_intops::StrongVector<NodeIndex, Node> nodes_;
 
  459  util_intops::StrongVector<NodeIndex, NodeIndex> root_blossom_node_;
 
  463  util_intops::StrongVector<NodeIndex, std::vector<EdgeIndex>> graph_;
 
  466  std::vector<NodeIndex> subnodes_;
 
  472  std::vector<NodeIndex> unmatched_nodes_;
 
  475  std::vector<EdgeIndex> primal_update_edge_queue_;
 
  476  std::vector<EdgeIndex> possible_shrink_;
 
  479  AdjustablePriorityQueue<Edge, std::greater<Edge>> plus_plus_pq_;
 
  480  AdjustablePriorityQueue<Edge, std::greater<Edge>> plus_free_pq_;
 
  481  std::vector<Edge*> tmp_all_tops_;
 
  488  int64_t num_grows_ = 0;
 
  489  int64_t num_augments_ = 0;
 
  490  int64_t num_shrinks_ = 0;
 
  491  int64_t num_expands_ = 0;
 
  492  int64_t num_dual_updates_ = 0;
 
 
void AddEdge(NodeIndex tail, NodeIndex head, CostValue cost)
Same comment as MinCostPerfectMatching::AddEdgeWithCost() applies.
std::string DebugString() const
void UpdateAllTrees(CostValue delta)
CostValue DualObjective() const
void Augment(EdgeIndex e)
void ExpandAllBlossoms()
This must be called at the end of the algorithm to recover the matching.
void DisplayStats() const
Display to VLOG(1) some statistic about the solve.
CostValue ComputeMaxCommonTreeDualDeltaAndResetPrimalEdgeQueue()
DEFINE_INT_TYPE(NodeIndex, int)
Typed index used by this class.
bool DebugDualsAreFeasible() const
const Edge & GetEdge(int e) const
CostValue Slack(const Edge &edge) const
Return the "slack" of the given edge.
NodeIndex Match(NodeIndex n) const
void DebugUpdateNodeDual(NodeIndex n, CostValue delta)
int NumMatched() const
Returns the current number of matched nodes.
BlossomGraph(int num_nodes)
Creates a BlossomGraph on the given number of nodes.
void DebugCheckNoPossiblePrimalUpdates()
std::string NodeDebugString(NodeIndex n) const
Display information for debugging.
static const EdgeIndex kNoEdgeIndex
const Node & GetNode(int n) const
std::string EdgeDebugString(EdgeIndex e) const
bool DebugEdgeIsTightAndExternal(const Edge &edge) const
static const NodeIndex kNoNodeIndex
CostValue Dual(const Node &node) const
Returns the dual value of the given node (which might be a pseudo-node).
void Expand(NodeIndex to_expand)
Expands a Blossom into its component.
DEFINE_INT_TYPE(EdgeIndex, int)
bool NodeIsMatched(NodeIndex n) const
ABSL_MUST_USE_RESULT bool Initialize()
DEFINE_INT_TYPE(CostValue, int64_t)
void Grow(EdgeIndex e, NodeIndex tail, NodeIndex head)
static const CostValue kMaxCostValue
int Match(int node) const
void Reset(int num_nodes)
void AddEdgeWithCost(int tail, int head, int64_t cost)
int64_t OptimalCost() const
@ INFEASIBLE
There is no perfect matching in this graph.
@ OPTIMAL
A perfect matching with min-cost has been found.
const std::vector< int > & Matches() const
ABSL_MUST_USE_RESULT Status Solve()
MinCostPerfectMatching(int num_nodes)
In SWIG mode, we don't want anything besides these top-level includes.
BlossomGraph::CostValue CostValue
BlossomGraph::NodeIndex NodeIndex
An undirected edge between two nodes: tail <-> head.
CostValue pseudo_slack
See the formula is Slack() used to derive the true slack of this edge.
bool operator>(const Edge &other) const
void SetHeapIndex(int index)
NodeIndex OtherEnd(NodeIndex n) const
Returns the "other" end of this edge.
Edge(NodeIndex t, NodeIndex h, CostValue c)
CostValue slack
We only maintain this in debug mode.
CostValue dual
The true dual of this node. We only maintain this in debug mode.
bool is_internal
Whether this node is part of a blossom.
CostValue saved_pseudo_dual
std::vector< NodeIndex > saved_blossom
std::vector< NodeIndex > blossom
CostValue tree_dual_delta