1
0
Fork 0

Use priority queue for delta4

This commit is contained in:
Joris van Rantwijk 2024-11-16 20:23:51 +01:00
parent 2271df1897
commit e8020f3e58
1 changed files with 33 additions and 15 deletions

View File

@ -430,7 +430,9 @@ struct NonTrivialBlossom : public Blossom<WeightType>
*/ */
WeightType dual_var; WeightType dual_var;
// TODO -- delta4_node /** Top-level T-blossoms are elements in the delta4 queue. */
typedef PriorityQueue<WeightType, NonTrivialBlossom*> BlossomQueue;
typename BlossomQueue::Node delta4_node;
/** Initialize a non-trivial blossom. */ /** Initialize a non-trivial blossom. */
NonTrivialBlossom( NonTrivialBlossom(
@ -637,7 +639,12 @@ public:
/** For each edge, a node in delta3_queue. */ /** For each edge, a node in delta3_queue. */
std::vector<typename EdgeQueue::Node> delta3_node; std::vector<typename EdgeQueue::Node> delta3_node;
// TODO -- delta4_queue /**
* Queue of top-level non-trivial T-blossoms.
* Priority of a blossom is its modified dual variable.
*/
typedef PriorityQueue<WeightType, NonTrivialBlossomT*> BlossomQueue;
BlossomQueue delta4_queue;
// TODO -- vertex_sedge_queue // TODO -- vertex_sedge_queue
// TODO -- vertex_sedge_node // TODO -- vertex_sedge_node
@ -961,12 +968,16 @@ public:
blossom->label = LABEL_T; blossom->label = LABEL_T;
// Unlabeled blossoms and T-blossoms use different rules
// for modified blossom duals. Adjust the modified dual variable
// to preserve the true blossom dual while switching labels.
NonTrivialBlossomT* ntb = blossom->nontrivial(); NonTrivialBlossomT* ntb = blossom->nontrivial();
if (ntb) { if (ntb) {
// Unlabeled blossoms and T-blossoms use different rules
// for modified blossom duals. Adjust the modified dual variable
// to preserve the true blossom dual while switching labels.
ntb->dual_var += 2 * delta_sum; ntb->dual_var += 2 * delta_sum;
// Top-level T-blossoms are tracked in the delta4 queue.
assert(! ntb->delta4_node.valid());
delta4_queue.insert(&ntb->delta4_node, ntb->dual_var, ntb);
} }
// Unlabeled vertices and T-vertices use different rules for // Unlabeled vertices and T-vertices use different rules for
@ -1025,9 +1036,13 @@ public:
blossom->label = LABEL_NONE; blossom->label = LABEL_NONE;
// Adjust modified blossom dual to preserve true blossom dual.
NonTrivialBlossomT* ntb = blossom->nontrivial(); NonTrivialBlossomT* ntb = blossom->nontrivial();
if (ntb) { if (ntb) {
// Unlabeled blossoms are not tracked in the delta4 queue.
assert(ntb->delta4_node.valid());
delta4_queue.remove(&ntb->delta4_node);
// Adjust modified blossom dual to preserve true blossom dual.
ntb->dual_var -= 2 * delta_sum; ntb->dual_var -= 2 * delta_sum;
} }
@ -1756,14 +1771,17 @@ public:
} }
// Compute delta4: half minimum dual of a top-level T-blossom. // Compute delta4: half minimum dual of a top-level T-blossom.
for (NonTrivialBlossomT& blossom : nontrivial_blossom) { // This takes time O(1).
if ((! blossom.parent) && (blossom.label == LABEL_T)) { if (! delta4_queue.empty()) {
WeightType true_dual_var = blossom.dual_var - 2 * delta_sum; NonTrivialBlossomT* blossom = delta4_queue.min_elem();
if (true_dual_var / 2 <= delta.value) { assert(! blossom->parent);
delta.kind = 4; assert(blossom->label == LABEL_T);
delta.value = true_dual_var / 2; // Calculate true blossom dual variable from modified dual.
delta.blossom = &blossom; WeightType blossom_dual = blossom->dual_var - 2 * delta_sum;
} if (blossom_dual / 2 <= delta.value) {
delta.kind = 4;
delta.value = blossom_dual / 2;
delta.blossom = blossom;
} }
} }
@ -1923,7 +1941,7 @@ public:
// TODO -- check delta2_queue empty // TODO -- check delta2_queue empty
assert(delta3_queue.empty()); assert(delta3_queue.empty());
// TODO -- check delta4_queue empty assert(delta4_queue.empty());
} }
/** Run the matching algorithm. */ /** Run the matching algorithm. */