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;
// 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. */
NonTrivialBlossom(
@ -637,7 +639,12 @@ public:
/** For each edge, a node in delta3_queue. */
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_node
@ -961,12 +968,16 @@ public:
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();
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;
// 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
@ -1025,9 +1036,13 @@ public:
blossom->label = LABEL_NONE;
// Adjust modified blossom dual to preserve true blossom dual.
NonTrivialBlossomT* ntb = blossom->nontrivial();
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;
}
@ -1756,14 +1771,17 @@ public:
}
// Compute delta4: half minimum dual of a top-level T-blossom.
for (NonTrivialBlossomT& blossom : nontrivial_blossom) {
if ((! blossom.parent) && (blossom.label == LABEL_T)) {
WeightType true_dual_var = blossom.dual_var - 2 * delta_sum;
if (true_dual_var / 2 <= delta.value) {
delta.kind = 4;
delta.value = true_dual_var / 2;
delta.blossom = &blossom;
}
// This takes time O(1).
if (! delta4_queue.empty()) {
NonTrivialBlossomT* blossom = delta4_queue.min_elem();
assert(! blossom->parent);
assert(blossom->label == LABEL_T);
// Calculate true blossom dual variable from modified dual.
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
assert(delta3_queue.empty());
// TODO -- check delta4_queue empty
assert(delta4_queue.empty());
}
/** Run the matching algorithm. */