def split_upper_ranks(partition: RankedPartition, block: _Block):
    """Split the blocks whose `rank` is **greater** than `block.rank` using
    `block` as *splitter*.

    :param partition: The current partition.
    :param block: The splitter block.
    """

    block_counterimage = build_block_counterimage(block)

    modified_blocks = []

    for vertex in block_counterimage:
        # if this is an upper-rank node with respect to the collapsed block, we
        # need to split. the split is not needed if the block is a singoletto.
        if vertex.rank > block.rank and not (
                vertex.qblock.split_helper_block is None
                and vertex.qblock.size <= 1):
            # if needed, create the aux block to help during the splitting
            # phase
            if vertex.qblock.split_helper_block is None:
                vertex.qblock.initialize_split_helper_block()
                modified_blocks.append(vertex.qblock)

            new_vertex_block = vertex.qblock.split_helper_block

            # remove the vertex in the counterimage from its current block
            vertex.qblock.remove_vertex(vertex)
            # put the vertex in the counterimage in the aux block
            new_vertex_block.append_vertex(vertex)

    # insert the new blocks in the partition, and then reset aux block for each
    # modified block.
    for mod_block in modified_blocks:
        # we use the rank of aux block because we're sure it's not None
        partition.append_at_rank(
            block=mod_block.split_helper_block,
            rank=mod_block.split_helper_block.rank,
        )
        mod_block.split_helper_block = None
Exemple #2
0
def test_append_at_rank():
    vertexes, _ = decorate_nx_graph(nx.balanced_tree(2, 3))
    partition = RankedPartition(vertexes)
    block = _QBlock([], None)
    partition.append_at_rank(block, 1)
    assert partition[2][-1] == block