1
0
Fork 0

Simplify expand_t_blossom()

This commit is contained in:
Joris van Rantwijk 2024-11-22 20:12:25 +01:00
parent b5ccbdeda4
commit 1e6f2a11c4
1 changed files with 36 additions and 71 deletions

View File

@ -1414,7 +1414,7 @@ public:
assert(sub_blossom->vertex_dual_offset == 0); assert(sub_blossom->vertex_dual_offset == 0);
sub_blossom->vertex_dual_offset = vertex_dual_offset; sub_blossom->vertex_dual_offset = vertex_dual_offset;
// Add unlabeled blossom to the delta2 queue. // Add unlabeled sub-blossom to the delta2 queue.
delta2_enable_blossom(sub_blossom); delta2_enable_blossom(sub_blossom);
} }
@ -1423,65 +1423,53 @@ public:
// that ran through this blossom by linking some of the sub-blossoms // that ran through this blossom by linking some of the sub-blossoms
// into the tree. // into the tree.
// Find the sub-blossom that was attached to the parent node // Find the sub-blossom through which the expanding blossom was
// in the alternating tree. // attached to the alternating tree.
BlossomT* entry = top_level_blossom(blossom->tree_edge.second); BlossomT* entry = top_level_blossom(blossom->tree_edge.second);
// Assign label T to that blossom and link to the alternating tree.
assign_blossom_label_t(entry);
entry->tree_edge = blossom->tree_edge;
entry->tree_root = blossom->tree_root;
// Find the position of this sub-blossom within the expanding blossom. // Find the position of this sub-blossom within the expanding blossom.
auto subblossom_loc = blossom->find_subblossom(entry); auto subblossom_loc = blossom->find_subblossom(entry);
VertexId entry_pos = subblossom_loc.first; VertexId entry_pos = subblossom_loc.first;
auto entry_it = subblossom_loc.second; auto entry_it = subblossom_loc.second;
// Walk around the blossom from "entry" to the base // Get the edge that attaches this blossom to the alternating tree.
VertexId x, y;
std::tie(x, y) = blossom->tree_edge;
// Walk around the expanding blossom from "entry" to its base
// in an even number of steps. // in an even number of steps.
auto sub_begin = blossom->subblossoms.begin();
auto sub_end = blossom->subblossoms.end();
auto sub_it = entry_it; auto sub_it = entry_it;
if (entry_pos % 2 == 0) { while ((sub_it != sub_begin) && (sub_it != sub_end)) {
// Walk backward to the base. // Assign label T to the current sub-blossom on the path.
auto sub_begin = blossom->subblossoms.begin(); // This also assigns label S to the next sub-blossom.
while (sub_it != sub_begin) { extend_tree_s_to_t(x, y);
// Assign label S to the next node on the path.
if (entry_pos % 2 == 0) {
// Walk two steps backward to the base.
--sub_it; --sub_it;
extend_tree_t_to_s(sub_it->edge.first);
// Assign label T to the next node on the path.
assert(sub_it != sub_begin); assert(sub_it != sub_begin);
--sub_it; --sub_it;
BlossomT* sub_blossom = sub_it->blossom; // Get the edge from S-sub-blossom to next sub-blossom.
assign_blossom_label_t(sub_blossom); std::tie(y, x) = sub_it->edge;
sub_blossom->tree_edge = flip_vertex_pair(sub_it->edge); } else {
sub_blossom->tree_root = blossom->tree_root; // Walk two steps forward to the base.
}
} else {
// Walk forward to the base.
auto sub_end = blossom->subblossoms.end();
while (sub_it != sub_end) {
// Assign label S to the next node on the path.
extend_tree_t_to_s(sub_it->edge.second);
++sub_it; ++sub_it;
// Assign label T to the next node on the path.
// We may wrap past the end of the subblossom list.
assert(sub_it != sub_end); assert(sub_it != sub_end);
VertexPair& tree_edge = sub_it->edge; // Get the edge from S-sub-blossom to next sub-blossom.
std::tie(x, y) = sub_it->edge;
++sub_it; ++sub_it;
BlossomT *sub_blossom = (sub_it == sub_end) ?
blossom->subblossoms.front().blossom :
sub_it->blossom;
assign_blossom_label_t(sub_blossom);
sub_blossom->tree_edge = tree_edge;
sub_blossom->tree_root = blossom->tree_root;
} }
} }
// Finally, assign label T to the base sub-blossom.
BlossomT* base = blossom->subblossoms.front().blossom;
assign_blossom_label_t(base);
base->tree_edge = std::make_pair(x, y);
base->tree_root = blossom->tree_root;
// Delete the expanded blossom. // Delete the expanded blossom.
nontrivial_blossom.erase(blossom->this_blossom_iterator); nontrivial_blossom.erase(blossom->this_blossom_iterator);
} }
@ -1655,34 +1643,6 @@ public:
/* ********** Alternating tree: ********** */ /* ********** Alternating tree: ********** */
/**
* Assign label S to the unlabeled blossom that contains vertex "x".
*
* The newly labeled S-blossom is added to the alternating tree
* via its matched edge. All vertices in the newly labeled S-blossom
* are added to the scan queue.
*
* @pre "x" is an unlabeled vertex.
* @pre "x" is matched to a T-vertex via a tight edge.
*/
void extend_tree_t_to_s(VertexId x)
{
// Assign label S to the blossom that contains vertex "x".
BlossomT* bx = top_level_blossom(x);
assign_blossom_label_s(bx);
// Vertex "x" is matched to T-vertex "y".
VertexId y = vertex_mate[x];
assert(y != NO_VERTEX);
BlossomT* by = top_level_blossom(y);
assert(by->label == LABEL_T);
// Attach the blossom to the alternating tree via vertex "y".
bx->tree_edge = std::make_pair(y, x);
bx->tree_root = by->tree_root;
}
/** /**
* Assign label T to the unlabeled blossom that contains vertex "y". * Assign label T to the unlabeled blossom that contains vertex "y".
* *
@ -1708,9 +1668,14 @@ public:
by->tree_root = bx->tree_root; by->tree_root = bx->tree_root;
// Assign label S to the blossom that is mated to the T-blossom. // Assign label S to the blossom that is mated to the T-blossom.
VertexId z = vertex_mate[by->base_vertex]; VertexId y2 = by->base_vertex;
VertexId z = vertex_mate[y2];
assert(z != NO_VERTEX); assert(z != NO_VERTEX);
extend_tree_t_to_s(z);
BlossomT* bz = top_level_blossom(z);
assign_blossom_label_s(bz);
bz->tree_edge = std::make_pair(y2, z);
bz->tree_root = by->tree_root;
} }
/** /**