def topologic_sort(G): if G is None: return [] S = Stack() for vertice in G.get_nodes(): if G.get_nodes()[vertice].get_in_degree() == 0: S.add_stack(vertice) t = 0 s = [] while(S.isEmpty() != True): v = S.pop_stack() G.get_nodes()[v].insert_sort(t) t = t + 1 s.append(G.get_nodes()[v].get_content()) for neighbor in G.get_nodes()[v].get_neighbors(): G.get_nodes()[neighbor].pop_in_degree(1) if G.get_nodes()[neighbor].get_in_degree() == 0: S.add_stack(neighbor) return s
def branch_and_bound_knapsack(capacity, weights, profits): stack = Stack() weights, profits, profit_per_weight, root = init_solution( capacity, weights, profits) stack.add_stack(root) solution = None while not stack.isEmpty(): root = stack.pop_stack() if solution and root.relaxation < solution.relaxation: continue elif root.id == (len(profits) - 1): continue Node = NodeTree(root.id + 1, root.capacity, root.objective, root.variables) if Node.capacity >= 0: Node.relaxation = bound(Node, weights, profits, profit_per_weight) stack.add_stack(Node) if Node.objective == Node.relaxation: if solution and Node.objective > solution.objective: solution = Node elif solution is None: solution = Node Node = NodeTree(root.id + 1) Node.capacity = root.capacity - int( root.capacity / weights[Node.id]) * weights[Node.id] if Node.capacity >= 0: Node.objective = root.objective + int( root.capacity / weights[Node.id]) * profits[Node.id] Node.variables = list(root.variables) Node.variables[Node.id] = int(root.capacity / weights[Node.id]) Node.relaxation = bound(Node, weights, profits, profit_per_weight) stack.add_stack(Node) if Node.objective == Node.relaxation: if solution and Node.objective > solution.objective: solution = Node elif solution is None: solution = Node variables = [0] * len(profits) for index, element in enumerate(profit_per_weight): variables[element[0]] = solution.variables[index] return [solution.objective, variables]
def branch_and_bound_knapsack(capacity, weights, profits): stack = Stack() weights, profits, profit_per_weight, root = init_solution( capacity, weights, profits) print(root.relaxation) stack.add_stack(root) solution = None while not stack.isEmpty(): root = stack.pop_stack() if solution and root.relaxation < solution.relaxation: continue elif root.id == (len(profits) - 1): continue Node = NodeTree(root.id + 1, root.capacity, root.objective, root.variables) if valid_space(Node.capacity): Node.relaxation = bound(Node, weights, profits, profit_per_weight) stack.add_stack(Node) print('Tira ', Node.relaxation) if Node.objective == Node.relaxation: if solution and Node.objective > solution.objective: solution = Node elif solution is None: solution = Node Node = NodeTree(root.id + 1, root.capacity) node_id = Node.id node_capacity = list(Node.capacity) min_get_itens = 1 Node.capacity[0] -= min_get_itens * weights[0][Node.id] Node.capacity[1] -= min_get_itens * weights[1][Node.id] Node.capacity[2] -= min_get_itens * weights[2][Node.id] if valid_space(Node.capacity) and min_get_itens > 0: print('min_get_itens: ', min_get_itens) print('capacits dentro: ', Node.capacity) Node.objective = root.objective + min_get_itens * profits[Node.id] Node.variables = list(root.variables) Node.variables[Node.id] = min_get_itens Node.relaxation = bound(Node, weights, profits, profit_per_weight) stack.add_stack(Node) print('Bota ', Node.relaxation) if Node.objective == Node.relaxation: if solution and Node.objective > solution.objective: solution = Node elif solution is None: solution = Node if solution != None: variables = [0] * len(profits) for index, element in enumerate(profit_per_weight): variables[element[0]] = solution.variables[index] if solution != None: return [solution.objective, variables]
def branch_and_bound(W=None, k=None, v=None): solution = -1 solution_variables = [] solutions_buffer = [] #Set variables simplex method c, A, b, bounds = setConfigVariables(W, k, v) tol = 1e-11 #resolve simplex result = linprog(c, method='simplex', A_ub=A, b_ub=b, bounds=bounds, options={'tol': tol}) if(result.success == False): return [solution, solution_variables] #First upper bound problem = Problem(c, A, b, bounds) problem.value_solution = result.fun * -1 problem.variables = result.x #First lower bound integer relaxation, new_variables = getLowerBound(problem, v) solution = relaxation solution_variables = new_variables #Stack init stack = Stack() stack.add_stack(problem) while(not stack.isEmpty()): problem_stack = stack.pop_stack() #Rules for pruning if problem_stack.value_solution == None: continue if problem_stack.value_solution < solution: continue if isReadySolved(solutions_buffer, problem_stack.value_solution): continue if not existFractionary(problem_stack.variables): break solutions_buffer.append(problem_stack.value_solution) print(problem_stack.value_solution) print('Solution: ', solution) #print(problem_stack.variables) print(stack.get_size()) #Variable choice to branch j = -1 min_interval = None for var in range(len(problem_stack.variables)): f, i = math.modf(problem_stack.variables[var]) if f != 0: dif_floor = problem_stack.variables[var] - math.floor(problem_stack.variables[var]) dif_ceil = math.ceil(problem_stack.variables[var]) - problem_stack.variables[var] if min_interval == None: min_interval = dif_ceil - dif_floor j = var else: if min_interval > (dif_ceil - dif_floor): min_interval = dif_ceil - dif_floor j = var if j == -1: continue #Branching for f in range(1): # LEFT resolve - Upper bound fractionary problem_left = Problem(c, A, b) problem_left.bounds = appendRestrict(problem_stack.bounds, (j, '<=', math.floor(problem_stack.variables[j]))) result = linprog(problem_left.c, method='simplex', A_ub=problem_left.A, b_ub=problem_left.b, bounds=problem_left.bounds, options={'tol': tol}) if result.success == True: problem_left.value_solution = result.fun * -1 problem_left.variables = result.x # RIGHT resolve - Upper bound fractionary problem_right = Problem(c, A, b) problem_right.bounds = appendRestrict(problem_stack.bounds, (j, '>=', math.ceil(problem_stack.variables[j]))) result = linprog(problem_right.c, method='simplex', A_ub=problem_right.A, b_ub=problem_right.b, bounds=problem_right.bounds, options={'tol': tol}) if result.success == True: problem_right.value_solution = result.fun * -1 problem_right.variables = result.x # Lower bound LEFT integer NEW_RELAXATION, NEW_VARIABLES = getLowerBound(problem_left, v) if NEW_RELAXATION != None and NEW_RELAXATION > solution: solution = NEW_RELAXATION solution_variables = NEW_VARIABLES # Lower bound RIGHT integer NEW_RELAXATION, NEW_VARIABLES = getLowerBound(problem_right, v) if NEW_RELAXATION != None and NEW_RELAXATION > solution: solution = NEW_RELAXATION solution_variables = NEW_VARIABLES if problem_right.value_solution != None and problem_right.value_solution > solution: stack.add_stack(problem_right) #Branching right if problem_left.value_solution != None and problem_left.value_solution > solution: stack.add_stack(problem_left) #Branching left #break return [solution, solution_variables]