def state_from_ctype(ctype_state): s = State() s.pos = ctype_state.pos s.state = int(ctype_state.state.decode(), 16) s.history = ctype_state.history s.move = ctype_state.move s.no_change_count = ctype_state.no_change_count s.depth = ctype_state.depth return s
def bfs_multiproccess(file, env, no_change_cnt, truncate): print_time = time.time() if math.ceil(env.state_len / 8) >= STATE_LEN: print(f"Increase state len to {math.ceil(env.state_len/4)}") return None queues = [] for i in range(num_proc): queues.append(Manager().Queue()) hashes = dict() lis = [] lock = Lock() init_state = env.get_init_state() init_state.history = b'' init_state.move = b'N' lis.append(ctype_state(init_state)) # push the initial state found_state = None count = 0 max_shared_block = 100000 best_depth = 200 while len(lis) > 0: act_proc = min(max(1, len(lis)), num_proc) all_list = lis lis = [] chunk_count = 0 for pos_in_all_lis in range(0, len(all_list), max_shared_block): chunk_size = math.ceil( min(max_shared_block, len(all_list)) / num_proc) chunk_count += 1 #print_lock(lock, f"Makeing shared memory at {pos_in_all_lis}-{pos_in_all_lis+max_shared_block} ({chunk_count}/{math.ceil(len(all_list)/max_shared_block)})") # print_tuple_state("copy to shared mem:",x,lock) shared_array = Array(CState, all_list[pos_in_all_lis:pos_in_all_lis + max_shared_block], lock=False) #print_lock(lock, f"making input for processes. all_size:{len(all_list)} chunk_size:{chunk_size}") input = [(i, queues[i], env, shared_array, i * chunk_size, chunk_size, lock, no_change_cnt) for i in list(range(act_proc))] #print_lock(lock, f"Starting {len(input)} jobs") pool = [] for i in input: proc = Process(target=bfs_job, args=(i, )) pool.append(proc) for p in pool: p.start() while any(pool): proc_loc = -1 while True: for p in range(len(pool)): if pool[p] and not pool[p].is_alive(): proc_loc = p if proc_loc != -1: break time.sleep(0.01) pool[proc_loc].join() #print_lock(lock, f'Pulling from process {proc_loc}') for state in queues[proc_loc].get(): if state[5] > best_depth: continue s = int(state[1].decode(), 16) state_hash = (state[0] << env.state_len) + s #if state_hash in hashes and hashes[state_hash] <= state[5]: if hashes.get(state_hash, 200) <= state[5]: continue hashes[state_hash] = state[5] lis.append(state) if s == env.goal: found_state = State() found_state.history = state[2] best_depth = state[5] #print_lock(lock, f'{s} {found_state.history}') #return DummyState(list(found_state.history)) #print_lock(lock, f'Completed pulling from process {proc_loc}') pool[proc_loc].terminate() pool[proc_loc] = None count += 1 #print(f'truncating hash {len(hashes)}') if truncate: truncate_hash(hashes, count) t = "{0:.3f}".format(time.time() - print_time) print( f'\r{t} :=======> count:{count} tree:{len(lis)} hash:{len(hashes)} found:{"true" if found_state else "false"}', end='') #print(f'{t} :=======> count:{count} tree:{len(lis)} hash:{len(hashes)}') print("\r", end='') if not found_state: print(f'"{file} solution not found !!!') return None else: print(f'{file} found solution at level {best_depth}') return DummyState([chr(x).encode() for x in found_state.history])