示例#1
0
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]
示例#3
0
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]
示例#4
0
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]