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);
|
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,64 +1423,52 @@ 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_it = entry_it;
|
|
||||||
if (entry_pos % 2 == 0) {
|
|
||||||
|
|
||||||
// Walk backward to the base.
|
|
||||||
auto sub_begin = blossom->subblossoms.begin();
|
auto sub_begin = blossom->subblossoms.begin();
|
||||||
while (sub_it != sub_begin) {
|
auto sub_end = blossom->subblossoms.end();
|
||||||
// Assign label S to the next node on the path.
|
auto sub_it = entry_it;
|
||||||
--sub_it;
|
while ((sub_it != sub_begin) && (sub_it != sub_end)) {
|
||||||
extend_tree_t_to_s(sub_it->edge.first);
|
|
||||||
|
|
||||||
// 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);
|
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);
|
|
||||||
sub_blossom->tree_root = blossom->tree_root;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
// Walk two steps forward to the base.
|
||||||
// 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) ?
|
// Finally, assign label T to the base sub-blossom.
|
||||||
blossom->subblossoms.front().blossom :
|
BlossomT* base = blossom->subblossoms.front().blossom;
|
||||||
sub_it->blossom;
|
assign_blossom_label_t(base);
|
||||||
assign_blossom_label_t(sub_blossom);
|
base->tree_edge = std::make_pair(x, y);
|
||||||
sub_blossom->tree_edge = tree_edge;
|
base->tree_root = blossom->tree_root;
|
||||||
sub_blossom->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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue