def BB_FIFO(weights,k): ## First recover problem parameters from the weights: transitions_nb = np.shape(weights)[-1] states_nb = np.shape(weights)[0] N = transitions_nb+1 d = states_nb ## Now come up with a heuristic solution: minpath,mincost = min_greedy_path(weights,0) ## Initialize the root node: root = Node_path([],d,N) ## Initialize problem parameters: B = mincost # Upper bound on solutions ## Now we will search the tree using BB_k: node_list = deque([root]) node_solution = [] while len(node_list): ## Get the active node node_active = node_list.popleft() ## Branch on that node nodes_eval = branch_path(node_active) ## Evaluate each child node bounds = [bound_path(node_eval,weights,k) for node_eval in nodes_eval] ## Evaluate if a solution was reached, and add those child nodes that satisfy the bound. for child_nb,bound in enumerate(bounds): if bound[0] <= B: node_list.append(nodes_eval[child_nb]) ## If the solution is as good as a previously found one, add it, if it is better replace the other. if bound[1] == 1: if B == bound[0]: node_solution.append((nodes_eval[child_nb],bound)) else: B = bound[0] node_solution = [(nodes_eval[child_nb],bound)] return node_solution
def test_bound_path_halt(): ''' To check that BB_k returns expected behavior w.r.t recognizing that it has found a solution. ''' test_weights, costs = extend_trap(10) # generates a graph of length 15 for N in range(17): test_node = Node_path([0 for n in range(N)], 2, 15) cost, solution = bound_path(test_node, test_weights, 5) if N < 16: assert solution == 0 else: assert solution == 1
def test_bound_path_accuracy(): ''' To check that BB_k returns expected behavior across a large collection of k- more specifically, asserts that BB_k performs as expected as a function of k (expected transition from apparent greedy behavior to apparent optimal behavior on a small dataset). ''' test_weights, costs = extend_trap(10) # generates a graph of length 20 test_node = Node_path([0], 2, 15) for k in range(15): cost, solution = bound_path(test_node, test_weights, k) if k < 11: assert cost == costs[0] else: assert cost == costs[1]
def test_bound_path_time(): ''' To check that longer expansions are taking more time, as we would expect. ''' test_weights, costs = extend_trap(10) # generates a graph of length 20 test_node = Node_path([0], 2, 15) durations = [] for k in range(15): start = time.time() cost, solution = bound_path(test_node, test_weights, k) end = time.time() durations.append(end - start) for i in range(len(durations) - 1): assert durations[i + 1] > durations[i]
def BB_Q(weights,k): ## First recover problem parameters from the weights: transitions_nb = np.shape(weights)[-1] states_nb = np.shape(weights)[0] N = transitions_nb+1 d = states_nb ## Now come up with a heuristic solution: minpath,mincost = min_greedy_path(weights,0) ## Initialize the root node: root = Node_path([],d,N) ## Initialize problem parameters: B = mincost # Upper bound on solutions ## Now we will search the tree using BB_k: node_list = [] heappush(node_list,(B,0,root)) node_solutions = [] entry_count = 0 while len(node_list): ## Get the active node parent_bound,parent_sol,node_active = heappop(node_list) # In this case reaching a solution should be good enough (?) if parent_sol == 1: B = parent_bound node_solution = (node_active,[parent_bound,parent_sol]) return node_solution ## Branch on that node nodes_eval = branch_path(node_active) ## Evaluate each child node bounds = [bound_path(node_eval,weights,k) for node_eval in nodes_eval] ## Evaluate if a solution was reached, and add those child nodes that satisfy the bound. for child_nb,bound in enumerate(bounds): entry_count+=1 if bound[1] == 1: solution_penalty = d**N else: solution_penalty = 0 heappush(node_list,(bound[0],entry_count+solution_penalty,nodes_eval[child_nb]))
def test_children(): node_ex = Node_path([],4,10) children = node_ex.children() for child in children: assert type(node_ex) == type(child) return None
def test_parentsigs_path(): node_ex = Node_path([0,1,2,0],4,10) parent = node_ex.parent() assert node_ex.signature[:-1] == parent.signature
def test_childsigs_path(): node_ex = Node_path([0,1,2,0],4,10) children = node_ex.children() for child in children: assert node_ex.signature == child.signature[:-1]