def is_solution_feasible(prob, sol, tol):

    assign_vars = prob.assign_vars
    assign_vals = dict([((i, j, k), sol[assign_vars[i, j, k]])
                        for (i, j, k) in assign_vars.keys()])

    if "Tours" in prob.options:
        threshold = prob.options["Tours"]
    else:
        threshold = 1.0 - prob.tol  # Default is only consider integer arcs

    # Get the graphs for each vehicle
    vehNodes, vehArcs = get_graphs(prob.vrp, assign_vals, threshold)

    # Loop over the vehicles that are used
    for k in prob.vrp.VEHS:

        # Extract the nodes and arcs for each vehicle to pass into get_subtour()
        if (sol[prob.use_vars[k]] > prob.tol):
            kNodes = vehNodes[k]
            kArcs = vehArcs[k]

            if len(kNodes) > 0:

                # Look for subtour in each vehicles graph from the first nod
                nodes, arcs = get_subtour(kNodes, kArcs, kNodes[0])

                # If a subtour is found then the solution is not feasible, so will generate cuts
                if (len(nodes) == len(arcs)) and (len(nodes) < len(kNodes)):
                    return False

    # Else no subtours
    return True
示例#2
0
def is_solution_feasible(prob, sol, tol):

    assign_vars = prob.assign_vars
    assign_vals = dict([((i, j, k), sol[assign_vars[i, j, k]])
                        for (i, j, k) in assign_vars.keys()])

    if "Tours" in prob.options:
        threshold = prob.options["Tours"]
    else:
        threshold = 1.0 - prob.tol  # Default is only consider integer arcs

    # Get the graphs for each vehicle
    nodes = prob.vrp.EXTLOCS[:]
    arcs = [(i, j, k) for (i, j, k) in assign_vars.keys()
            if sol[assign_vars[i, j, k]] > threshold]

    # Loop over the vehicles that are used
    for k in prob.vrp.VEHS:

        # Extract the arcs for each vehicle to pass into get_subtour()
        vehArcs = [x[:2] for x in arcs if x[2] == k]

        #   Look for subtour in each vehicles graph from the first node
        tNodes, tArcs = get_subtour(nodes, vehArcs, nodes[1])

        #   If a subtour is found then the solution is not feasible, so will generate cuts
        if (len(tNodes) == len(tArcs)) and (len(tNodes) < len(nodes)):
            # print("Solution has subtours!")
            return False

    # No subtours
    # print("Solution has no subtours!")
    return True
def generate_cuts(prob, sol):

    # No constraints added initially
    cons = []
    cons_added = 0

    # Get the assignment variables
    assign_vars = prob.assign_vars
    assign_vals = dict([((i, j, k), sol[assign_vars[i, j, k]])
                        for (i, j, k) in assign_vars.keys()])

    # Get the threshold for whether an arc should be considered
    # as part of the solution (almost = 1 by default)
    if "Tours" in prob.options:
        threshold = prob.options["Tours"]
    else:
        threshold = 1.0 - prob.tol  # Default is only consider integer arcs

    # Get the graph structure for each vehicle
    vehNodes, vehArcs = get_graphs(prob.vrp, assign_vals, threshold)

    # Loop over the vehicles that are used
    for k in prob.vrp.VEHS:

        # Extract the nodes and arcs for each vehicle
        if (sol[prob.use_vars[k]] > prob.tol):
            kNodes = vehNodes[k]
            kArcs = vehArcs[k]

            # Define the set of nodes that have not been put in a connected component
            not_connected = set(kNodes)

            # While any nodes are not in a connected component
            while not_connected:

                # Get an unconnected node
                start = not_connected.pop()

                # Find a subtour from that node
                nodes, arcs = get_subtour(kNodes, kArcs, start)

                # If it is a subtour (and not a complete tour), add a subtour elimination constraint
                if (len(nodes) == len(arcs)) and (len(nodes) < len(kNodes)):
                    cons_added += 1

                    # Option 1
                    cons.append(
                        lpSum(assign_vars[i, j, k]
                              for (i, j) in kArcs) <= len(kArcs) - 1)

                # Remove the subtour nodes as they are now connected
                not_connected -= set(nodes)

    if len(cons) > 0:
        return cons
    else:
        return None
示例#4
0
def is_solution_feasible(prob, sol, tol):

    # User callback for checking feasibility
    # Display feasibility checks if desired
    # assignments = get_assignments(prob, sol, tol)
    # prob.vrp.setSolution(assignments, tol)
    # prob.vrp.displaySolution(title="Feasibility Check", showProb=None)

    # Get the threshold for whether an arc should be considered
    # as part of the solution (almost = 1 by default)
    if "Tours" in prob.options:
        threshold = prob.options["Tours"]
    else:
        threshold = 1.0 - prob.tol  # Default is only consider integer arcs

    # Get the assignment variables
    assign_vars = prob.assign_vars
    assign_vals = dict([((i, j, k), sol[assign_vars[i, j, k]])
                        for (i, j, k) in assign_vars.keys()])

    # Get the graphs for each vehicle
    nodes = prob.vrp.EXTLOCS[:]
    arcs = [(i, j, k) for (i, j, k) in assign_vars.keys()
            if sol[assign_vars[i, j, k]] > threshold]

    # Loop over the vehicles that are used
    for k in prob.vrp.VEHS:

        # Extract the arcs for each vehicle to pass into get_subtour()
        vehArcs = [x[:2] for x in arcs if x[2] == k]

        # Define the set of nodes that have not been put in a connected component
        not_connected = set(nodes[:])

        # While any nodes are not in a connected component
        while not_connected:

            # Get an unconnected node
            start = not_connected.pop()

            # Find a subtour from that node
            tNodes, tArcs = get_subtour(nodes, vehArcs, start)
            # tNodes, tArcs = get_subtour(nodes, vehArcs, nodes[0])

            #   If a subtour is found then the solution is not feasible, so will declare it as such
            if (len(tNodes) == len(tArcs)) and (len(tNodes) < len(nodes)) and (
                    'O' not in tNodes):
                # print("Solution has subtours!")
                return False

            # Remove the subtour nodes as they are now connected
            not_connected -= set(tNodes)

    # Otherwise it is feasible
    # print("Solution has no subtours!")
    return True
示例#5
0
def generate_cuts(prob, sol):
    '''
    obj_val = 0.0
    for v in prob.objective:
      obj_val += prob.objective[v] * sol[v]
    print("In generate_cuts...")
    print("Solution value =", obj_val)
    sys.stdout.flush()

    for var in prob.variables():
      if abs(sol[var]) > prob.tol:
        print(var.name, "=", sol[var])
    '''

    cons = []
    cons_added = 0

    assign_vars = prob.assign_vars
    assign_vals = dict([((i, j, k), sol[assign_vars[i, j, k]]) for (i, j, k) in assign_vars.keys()])
    if "Tours" in prob.options:
        threshold = prob.options["Tours"]
    else:
        threshold = 1.0 - prob.tol  # Default is only consider integer arcs
    vehNodes, vehArcs = get_graphs(prob.vrp, assign_vals, threshold)
    for k in prob.vrp.VEHS:
        if (sol[prob.use_vars[k]] > prob.tol):
            kNodes = vehNodes[k]
            kArcs = vehArcs[k]
            #        print(k, kNodes, kArcs)
            not_connected = set(kNodes)
            while not_connected:
                start = not_connected.pop()
                nodes, arcs = get_subtour(kNodes, kArcs, start)
                #          print(nodes, arcs)
                #          print(len(nodes), len(arcs), len(kNodes))
                if (len(nodes) == len(arcs)) and (len(nodes) < len(kNodes)):
                    cons_added += 1
                    #            prob.vrp.setSolution(assign_vals, prob.tol)
                    #            prob.vrp.displaySolution(title="Subtour example", showProb=False)
                    cons.append(lpSum(assign_vars[i, j, k]
                                      for (i, j) in kArcs) \
                                <= len(kArcs) - 1)
                #            print("Subtour elimination!", cons[-1])
                #            return cons
                not_connected -= set(nodes)

    if len(cons) > 0:
        return cons
    else:
        return None
示例#6
0
def is_solution_feasible(prob, sol, tol):
    '''
    obj_val = 0.0
    for v in prob.objective:
      obj_val += prob.objective[v] * sol[v]
    print("In is_solution_feasible...")
    print("Solution value =", obj_val)
    sys.stdout.flush()
    
    for var in prob.variables():
      if abs(sol[var]) > prob.tol:
        print(var.name, "=", sol[var])
    '''

    assign_vars = prob.assign_vars
    '''
    # Display the current node solution
    prob.vrp.setSolution(assign_vars, sol, prob.tol)
    prob.vrp.displaySolution()
    '''
    assign_vals = dict([((i, j, k), sol[assign_vars[i, j, k]])
                        for (i, j, k) in assign_vars.keys()])
    if "Tours" in prob.options:
        threshold = prob.options["Tours"]
    else:
        threshold = 1.0 - prob.tol  # Default is only consider integer arcs
    vehNodes, vehArcs = get_graphs(prob.vrp, assign_vals, threshold)
    for k in prob.vrp.VEHS:
        if (sol[prob.use_vars[k]] > prob.tol):
            kNodes = vehNodes[k]
            kArcs = vehArcs[k]
            #        print(k, kNodes, kArcs)
            if len(kNodes) > 0:
                nodes, arcs = get_subtour(kNodes, kArcs, kNodes[0])
                #          print(nodes, arcs)
                if (len(nodes) == len(arcs)) and (len(nodes) < len(kNodes)):
                    #            print("Solution has subtours!")
                    return False

    #    print("Solution has no subtours!")
    return True
示例#7
0
def generate_cuts(prob, sol):

    # No constraints added
    cons = []
    cons_added = 0

    # Get the assignment variables and values
    assign_vars = prob.assign_vars
    assign_vals = dict([((i, j, k), sol[assign_vars[i, j, k]])
                        for (i, j, k) in assign_vars.keys()])

    # Get the threshold for whether an arc should be considered
    # as part of the solution (almost = 1 by default)
    if "Tours" in prob.options:
        threshold = prob.options["Tours"]
    else:
        threshold = 1.0 - prob.tol  # Default is only consider integer arcs

    # Get the graphs for each vehicle
    nodes = prob.vrp.EXTLOCS[:]
    arcs = [(i, j, k) for (i, j, k) in assign_vars.keys()
            if sol[assign_vars[i, j, k]] > threshold]

    # Loop over the vehicles that are used
    for k in prob.vrp.VEHS:

        # Extract the arcs for each vehicle
        vehArcs = [x[:2] for x in arcs if x[2] == k]

        # Define the set of nodes that have not been put in a connected component
        not_connected = set(nodes[:])

        # While any nodes are not in a connected component
        while not_connected:

            # Get an unconnected node
            start = not_connected.pop()

            # Find a subtour from that starting node
            tNodes, tArcs = get_subtour(nodes, vehArcs, start)

            # If it is a subtour (and not a complete tour), add a subtour elimination constraint provided that
            # the depot is not included in the subtour,
            if len(tNodes) == len(tArcs) and len(tNodes) < len(nodes) and (
                    'O' not in tNodes):
                cons_added += 1

                # If a subtour is found then that graph must be banned

                # Option 1
                cons.append(
                    lpSum(assign_vars[i, j, k]
                          for (i, j) in tArcs) <= len(tArcs) - 1)

                # Option 2
                # cons.append(lpSum(assign_vars[i, j, k]
                #                   for i in tNodes
                #                   for j in set(nodes).difference(tNodes)) +
                #             lpSum(assign_vars[j, i, k]
                #                   for i in tNodes
                #                   for j in set(nodes).difference(tNodes))
                #             >= 2)

                # print("Subtour elimination!", cons[-1])

                # Return one subtour elimination constraint at a time
                if cons_added == 1:
                    return cons

            # Remove the subtour nodes as they are now connected
            not_connected -= set(tNodes)

    if len(cons) > 0:
        return cons
    else:
        return None