def init_partition(circuit, block_ids=None) -> Data: """ randomly partition the nodes equally, if the block_ids is not specified. :return: data container for the current partition """ pmax = get_pmax(circuit) nets_size = circuit.get_nets_size() n = circuit.get_cells_size() if block_ids is None: random_cids = random.sample(range(n), n) block_ids = [cid % 2 for i, cid in enumerate(random_cids)] # initialize a data container for the current partition data = Data(pmax, nets_size, block_ids) # update the nets distribution in the current partition update_distribution(circuit, data) # update the gain for each node in the current partition calculate_gains(circuit, data) # update the cutsize of the current partition data.cutsize = calculate_cutsize(circuit, data) logging.info("initial cutsize = {}".format(data.cutsize)) # intialize best partition, and prev mincut data.store_best_cut() data.prev_mincut = data.mincut return data
def kl_inner_loop(circuit: Circuit, data: Data, app=None, genetic=False): """ perform the inner loop of the Kernighan-Lin Partition algorithm """ # select the max gain node from blocks max_gain_node = select_max_gain_node(data) # move the max gain node to another block # - update the gain for each node # - update the nets distribution # - update the cutsize move_node_another_block(max_gain_node, data) # if cutsize is the minimum for this pass, store the cut if data.cutsize < data.mincut: data.store_best_cut() data.print_blocks_size() if app is None or app.quick: if data.has_unlocked_nodes(): kl_inner_loop(circuit, data, app, genetic) else: kl_inner_stop(circuit, data, app, genetic) else: app.update_canvas(data) # inner loop stop until no unlocked nodes remains if data.has_unlocked_nodes(): app.root.after(1, kl_inner_loop, circuit, data, app, genetic) else: # inner loop exit app.root.after(1000, kl_inner_stop, circuit, data, app, genetic)