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
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
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
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
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
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