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
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