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_stop(circuit: Circuit, data: Data, app=None, genetic=False): """ it is the end of the current pass, restore the best cut of this pass; terminates the outer loop if mincut doesn't improve or it reaches 6 iterations """ data.restore_best_cut() # restore block data structures # update the distribution for the restored best cut update_distribution(circuit, data) # update the gains for the restored best cut calculate_gains(circuit, data) if genetic: return logging.info("iteration {}: best mincut = {}".format( data.iteration, data.cutsize)) if app is not None: app.update_canvas(data) data.iteration += 1 # continue for up to 6 iterations or until mincut stops improving if data.iteration <= 6 and data.mincut != data.prev_mincut: data.prev_mincut = data.mincut if app is not None: app.root.after(1000, kl_inner_loop, circuit, data, app) elif app is not None: app.update_partition_button(True)