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);
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);
}
@ -1423,65 +1423,53 @@ public:
// that ran through this blossom by linking some of the sub-blossoms
// into the tree.
// Find the sub-blossom that was attached to the parent node
// in the alternating tree.
// Find the sub-blossom through which the expanding blossom was
// attached to the alternating tree.
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.
auto subblossom_loc = blossom->find_subblossom(entry);
VertexId entry_pos = subblossom_loc.first;
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.
auto sub_begin = blossom->subblossoms.begin();
auto sub_end = blossom->subblossoms.end();
auto sub_it = entry_it;
if (entry_pos % 2 == 0) {
while ((sub_it != sub_begin) && (sub_it != sub_end)) {
// Walk backward to the base.
auto sub_begin = blossom->subblossoms.begin();
while (sub_it != sub_begin) {
// Assign label S to the next node on the path.
// Assign label T to the current sub-blossom on the path.
// This also assigns label S to the next sub-blossom.
extend_tree_s_to_t(x, y);
if (entry_pos % 2 == 0) {
// Walk two steps backward to the base.
--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);
--sub_it;
BlossomT* sub_blossom = sub_it->blossom;
assign_blossom_label_t(sub_blossom);
sub_blossom->tree_edge = flip_vertex_pair(sub_it->edge);
sub_blossom->tree_root = blossom->tree_root;
}
} 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);
// Get the edge from S-sub-blossom to next sub-blossom.
std::tie(y, x) = sub_it->edge;
} else {
// Walk two steps forward to the base.
++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);
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;
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.
nontrivial_blossom.erase(blossom->this_blossom_iterator);
}
@ -1655,34 +1643,6 @@ public:
/* ********** 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".
*
@ -1708,9 +1668,14 @@ public:
by->tree_root = bx->tree_root;
// 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);
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;
}
/**