Simplify expand_t_blossom()
This commit is contained in:
parent
b5ccbdeda4
commit
1e6f2a11c4
109
cpp/mwmatching.h
109
cpp/mwmatching.h
|
@ -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,64 +1423,52 @@ 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_it = entry_it;
|
||||
if (entry_pos % 2 == 0) {
|
||||
|
||||
// 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.
|
||||
--sub_it;
|
||||
extend_tree_t_to_s(sub_it->edge.first);
|
||||
auto sub_end = blossom->subblossoms.end();
|
||||
auto sub_it = entry_it;
|
||||
while ((sub_it != sub_begin) && (sub_it != sub_end)) {
|
||||
|
||||
// Assign label T 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;
|
||||
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;
|
||||
}
|
||||
|
||||
// Get the edge from S-sub-blossom to next sub-blossom.
|
||||
std::tie(y, x) = sub_it->edge;
|
||||
} 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);
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue