def solve_planes(planes_problem, algo, allsolns, variableHeuristic='fixed', silent=False, trace=False): #Your implementation for Question 6 goes here. # #Do not but do not change the functions signature #(the autograder will twig out if you do). #If the silent parameter is set to True #you must ensure that you do not execute any print statements #in this function. #(else the output of the autograder will become confusing). #So if you have any debugging print statements make sure you #only execute them "if not silent". (The autograder will call #this function with silent=True, plane_scheduling.py will call #this function with silent=False) #You can optionally ignore the trace parameter #If you implemented tracing in your FC and GAC implementations #you can set this argument to True for debugging. # #Once you have implemented this function you should be able to #run plane_scheduling.py to solve the test problems (or the autograder). # # '''This function takes a planes_problem (an instance of PlaneProblem class) as input. It constructs a CSP, solves the CSP with bt_search (using the options passed to it), and then from the set of CSP solutions it constructs a list of lists specifying a schedule for each plane and returns that list of lists The required format is the list of lists is: For each plane P the list of lists contains a list L. L[0] == P (i.e., the first item of the list is the plane) and L[1], ..., L[k] (i.e., L[1:]) is the sequence of flights assigned to P. The returned list of lists should contain a list for every plane. ''' #BUILD your CSP here and store it in the varable csp allVariables = [] allConstraints = [] increment = 1 answer = [] noneFlights = 1 flights = planes_problem.flights maintenanceFlights = planes_problem.maintenance_flights mFrequency = planes_problem.min_maintenance_frequency ''' ''' constraintNameString = "C" planes = planes_problem.planes for i in range(len(planes)): currPlane = planes[i] canFlyPlanes = planes_problem.can_fly(currPlane) numFlights = len(canFlyPlanes) for j in range(numFlights): name = str(currPlane) + "." + str(noneFlights) if j > 0: currDomain = list(canFlyPlanes) else: currDomain = list(planes_problem.can_start( currPlane)) # domain is only the "can_start" flights valString = "none." + str(noneFlights) currDomain = currDomain + [valString] var = Variable(name, currDomain) allVariables.append(var) noneFlights = noneFlights + 1 diffCounter = 1 allConstraints.extend([ AllDiffConstraint(constraintNameString + str(diffCounter), allVariables) ]) diffCounter = diffCounter + increment allConstraints.extend([ NValuesConstraint(constraintNameString + str(diffCounter), allVariables, flights, len(flights), np.inf) ]) diffCounter = diffCounter + increment noneString = "none" + "." for i in range(len(planes)): foundVariables = [] for var in allVariables: if planes[i] in var.name(): foundVariables.append(var) for variable_index in range(len(foundVariables[:-1])): first = foundVariables[variable_index] second = foundVariables[variable_index + 1] cnstrBatch = [] noneA = noneString + first.name().split('.')[1] noneB = noneString + second.name().split('.')[1] listOfCo = [] if variable_index == 0: firstdomain = planes_problem.can_start(planes[i]) else: firstdomain = first.domain() for flight in firstdomain: for follow in planes_problem.can_follow: if flight == follow[0]: listOfCo.append(follow) for k in range(len(listOfCo)): nextDomain = second.domain() if listOfCo[k][1] in nextDomain: cnstrBatch.append([listOfCo[k][0], listOfCo[k][1]]) for flight in firstdomain: cnstrBatch.append([flight, noneB]) if variable_index == 0: cnstrBatch.append([noneA, noneB]) scope = [first, second] allConstraints.extend([ TableConstraint(constraintNameString + str(diffCounter), scope, cnstrBatch) ]) if len(foundVariables) == 1: cnstrBatch = [] first = foundVariables[0] firstDomain = first.domain() for flight in firstDomain: cnstrBatch.append([flight]) scope = [first] allConstraints.extend([ TableConstraint(constraintNameString + str(diffCounter), scope, cnstrBatch) ]) diffCounter = diffCounter + increment for i in range(len(planes)): foundVariables = [] for var_index in range(len(allVariables)): if planes[i] in allVariables[var_index].name(): foundVariables.append(allVariables[var_index]) subSequences = map( list, zip(*(foundVariables[i:] for i in range(mFrequency)))) if len(foundVariables) < mFrequency: continue for index in subSequences: planesWithNone = [] for var in index: intermediateLst = var.name().split(".") formattedString = "none." + str(intermediateLst[1]) planesWithNone.append(formattedString) currSequence = index allConstraints = allConstraints + [ NValuesConstraint( constraintNameString + str(diffCounter), currSequence, maintenanceFlights + planesWithNone, 1, np.inf) ] diffCounter = diffCounter + increment csp = CSP("Planes", allVariables, allConstraints) solutions, num_nodes = bt_search(algo, csp, variableHeuristic, allsolns, trace) for i in range(len(solutions)): temp = [] final = [] for plane in planes: foundVariables = [] for var in solutions[i]: if var[0].name().split(".")[0] == plane: foundVariables.append(var) nextVal = [x[1] for x in foundVariables] temp += [plane] temp += nextVal temp = [y for y in temp if (not "none" in y)] final += [temp] temp = [] answer += [final] #print("---------------------------") #for lst in answer: #print(lst) return answer
def solve_planes(planes_problem, algo, allsolns, variableHeuristic='mrv', silent=False, trace=False): # Your implementation for Question 6 goes here. # # Do not but do not change the functions signature # (the autograder will twig out if you do). # If the silent parameter is set to True # you must ensure that you do not execute any print statements # in this function. # (else the output of the autograder will become confusing). # So if you have any debugging print statements make sure you # only execute them "if not silent". (The autograder will call # this function with silent=True, plane_scheduling.py will call # this function with silent=False) # You can optionally ignore the trace parameter # If you implemented tracing in your FC and GAC implementations # you can set this argument to True for debugging. # # Once you have implemented this function you should be able to # run plane_scheduling.py to solve the test problems (or the autograder). # # """This function takes a planes_problem (an instance of PlaneProblem class) as input. It constructs a CSP, solves the CSP with bt_search (using the options passed to it), and then from the set of CSP solutions it constructs a list of lists specifying a schedule for each plane and returns that list of lists The required format is the list of lists is: For each plane P the list of lists contains a list L. L[0] == P (i.e., the first item of the list is the plane) and L[1], ..., L[k] (i.e., L[1:]) is the sequence of flights assigned to P. The returned list of lists should contain a list for every plane. """ # BUILD your CSP here and store it in the varable csp plane_var_table = dict() all_vars = [] for plane in planes_problem.planes: plane_var = [] dom = planes_problem.can_start(plane) + ['None'] var = Variable("Plane:{}_{}".format(plane, 1), dom) plane_var.append(var) i = 1 while i < len(planes_problem.can_fly(plane)): dom = planes_problem.can_fly(plane) + ['None'] var = Variable("Plane:{}_{}".format(plane, i + 1), dom) plane_var.append(var) i = i + 1 all_vars.extend(plane_var) plane_var_table[plane] = plane_var # Set up the constraints # row constraints constraint_list = [] # Constrain A: fight schedule (with NValuesConstraint) # Each flight must be scheduled (be part of some plane's sequence of flights). And no flight can be scheduled more than once. for flight in planes_problem.flights: constraint_list.append( NValuesConstraint("SingleFlight_{}".format(flight), all_vars, [flight], 1, 1)) # Constrain B: feasible flight sequences (with TableConstraint) # The sequence of flights flown by every plane must be feasible. for plane in planes_problem.planes: plane_vars = plane_var_table[plane] feasible_set = [] for f1, f2 in planes_problem.can_follow: if f1 in planes_problem.can_fly( plane) and f2 in planes_problem.can_fly(plane): feasible_set.append([f1, f2]) for flight in planes_problem.can_fly(plane): feasible_set.append([flight, 'None']) feasible_set.append(['None', 'None']) for i in range(len(plane_vars) - 1): scope = [plane_vars[i], plane_vars[i + 1]] constraint_list.append( TableConstraint("FeasibleSeq_{}".format(i), scope, feasible_set)) # Constrain C: maintenance (with NValuesConstraint) # All planes must be serviced with a certain minimum frequency. for plane in planes_problem.planes: plane_maintenance = ['None'] plane_vars = plane_var_table[plane] for flight in planes_problem.maintenance_flights: if flight in planes_problem.can_fly(plane): plane_maintenance.append(flight) for i in range( 0, len(plane_vars) + 1 - planes_problem.min_maintenance_frequency, 1): scope = plane_vars[i:i + planes_problem.min_maintenance_frequency] constraint_list.append( NValuesConstraint( "planeMaintenanceConstrain_{}{}".format(flight, i), scope, plane_maintenance, 1, planes_problem.min_maintenance_frequency)) csp = CSP("PlaneScheduling", all_vars, constraint_list) # invoke search with the passed parameters solutions, num_nodes = bt_search(algo, csp, variableHeuristic, allsolns, trace) # Convert each solution into a list of lists specifying a schedule # for each plane in the format described above. if len(solutions) == 0: print "No solutions to {} found".format(csp.name()) solution = [] for soln in solutions: curr_soln = [] all_solns = dict() for plane in planes_problem.planes: all_solns[plane] = [] for var, val in soln: name = var.name() plane = (name.split(':')[1]).split('_')[0] number = int((name.split(':')[1]).split('_')[1]) all_solns[plane].append((number, val)) for plane in planes_problem.planes: all_solns[plane].sort() plane_soln = [plane] for var, val in all_solns[plane]: if val != 'None': plane_soln.append(val) curr_soln.append(plane_soln) solution.append(curr_soln) # then return a list containing all converted solutions # (i.e., a list of lists of lists) return solution