def depth_first_search(self,node=None): stack = [node] poiList_copy=self.parts[node]['poi_ids'] poiList=copy.deepcopy(poiList_copy) while stack : try: node = self.getNode(stack,self.tabuDic,stack) if genPlanConstraint.deduPoiConstraint(node,poiList,self.parts,self.pois): if self.daysConstraint(node,stack):# 如果添加node之后发现 days大于顾客需求,则停止并回溯。将之前走过的路径添加到Tabu if self.poiNotGoConstraint(node,poiList): # 判断是否有不想去的poi,有则剪枝 if genPlanConstraint.station_constraint(stack[-1],node,self.pois,self.parts): # # 判断两个part连接的交通方式是否满足要 if self.regionConstraint(node,stack,self.parts):# 判断region是否满足要求,如果不满足 剪枝 stack.append(node) poiList = self.addPoi(node=node, poiList=poiList) print("addPoi") # 判断是否结束 if node in self.endParts: indexMap = genPlanConstraint.getPathDetail(stack, self.parts, self.pois, self.schedulePois, self.places, self.schedulePlaces, self.poiTags, self.placePoisMapping, self.currencies, self.poiCalendar) print("ssss") if self.querySatisfied(indexMap, self.pois, self.parts, self.places): print("aaaaa") return stack, self.runtime if not self.days_query and len(stack) > 10: poiList = self.minsPoi(stack, poiList=poiList) self.tabuDic = self.addTabuDic(self.tabuDic, stack) print("part过长") stack = stack[0:8] if len(stack) > 0: node = stack[-1] else: self.update_node_neighbours(node, stack) else: self.update_node_neighbours(node, stack) else: self.update_node_neighbours(node,stack) else: self.tabuDic = self.addTabuDic_deduPoi(self.tabuDic, stack, node) else: self.tabuDic=self.addTabuDic_deduPoi(self.tabuDic,stack,node) self.end = time.clock() self.runtime = self.end - self.start if self.runtime>7: return [],self.runtime except: poiList = self.minsPoi(stack, poiList) self.tabuDic = self.addTabuDic(self.tabuDic, stack) self.update_node_neighbours(node,stack) stack.pop() print("except") if len(stack) > 0: node = stack[-1] self.end=time.clock() self.runtime=self.end-self.start return [],self.runtime
def querySatisfied(self, result, broadPois, broadParts, broadPlaces): """ :param result: 为了判断是否满足query :param broadPois: dict :param broadParts: dict :param broadPlaces: dict :return: Boolean """ if self.days_query: if type(self.days_query) == list: if result['days'] < self.days_query[0] or result[ "days"] > self.days_query[-1]: return False if type(self.days_query) == int: if int(result['days']) != self.days_query: return False if self.price_query: if result['price'] > self.price_query[1] or result[ 'price'] < self.price_query[0]: return False if self.pois_query: if set(self.pois_query) - set(result['poi_ids']): return False if self.regions_query: regionsMapInGenPlan = { x['region_id']: x['days'] for x in result['tour_regions'] } regionsMapInQuery = { x['region_id']: x['days'] for x in self.regions_query } if set(regionsMapInQuery.keys()) - set(regionsMapInGenPlan.keys()): return False for regionId, days in regionsMapInQuery.items(): if days and regionsMapInGenPlan[regionId] != days: return False if self.regionNotGo_query: if set(result['region_ids']) & set(self.regionNotGo_query): return False if self.poiNotGo_query: if set(result['poi_ids']) & set(self.poiNotGo_query): return False if self.availableMonths_query: if set(self.availableMonths_query) - set( result['available_months']): return False if self.departRegionId_query: if self.departRegionId_query and broadPlaces[ broadParts[result['part_ids'][-1]] ['place_id']]['region_id'] != self.departRegionId_query: return False if self.arrivalRegionId_query: if self.arrivalRegionId_query and broadPlaces[ broadParts[result['part_ids'][0]] ['place_id']]['region_id'] != self.arrivalRegionId_query: return False if self.hotelRating_query: if self.hotelRating_query and self.hotelRating_query != result[ 'average_star_rating']: return False if result['hotel_poi_number'] == 0: return False if result['rental_car_pois'] % 2 != 0: return False depuPoi = [] if len(set(result['poi_ids'])) != len(result['poi_ids']): for i in result['poi_ids']: if result['poi_ids'].count(i) > 1: depuPoi.append(i) for i in set(depuPoi): if broadPois[i]['type'] not in [ 'Pois::CarRental', 'Pois::Airport', 'Pois::Hub' ]: return False for i in range(len(result['part_ids']) - 1): if not genPlanConstraint.station_constraint( result['part_ids'][i], result['part_ids'][i + 1], broadPois, broadParts): return False return True
def BFS(self, graph, start, q): temp_path = [start] # start 开始节点 q.enqueue(temp_path) while q.IsEmpty() == False: tmp_path = q.dequeue() last_node = tmp_path[len(tmp_path) - 1] # input('Enter') try: for link_node in graph[last_node]: if link_node not in tmp_path: if genPlanConstraint.deduPoiConstraint( link_node, genPlanConstraint.getPois( tmp_path, self.parts), self.parts, self.pois): if self.daysConstraint( link_node, tmp_path ): # 如果添加node之后发现 days大于顾客需求,则停止并回溯。将之前走过的路径添加到Tabu if self.poiNotGoConstraint( link_node, genPlanConstraint.getPois( tmp_path, self.parts)): # 判断是否有不想去的poi,有则剪枝 if genPlanConstraint.station_constraint( tmp_path[-1], link_node, self.pois, self.parts ): # # 判断两个part连接的交通方式是否满足要 if self.regionConstraint( link_node, tmp_path, self.parts ): # 判断region是否满足要求,如果不满足 剪枝 new_path = [] new_path = tmp_path + [link_node] q.enqueue(new_path) if link_node in self.endParts: indexMap = genPlanConstraint.getPathDetail( new_path, self.parts, self.pois, self.schedulePois, self.places, self.schedulePlaces, self.poiTags, self.placePoisMapping, self.currencies, self.poiCalendar) if self.querySatisfied( indexMap, self.pois, self.parts, self.places): print( "VALID_PATH : ", tmp_path) return tmp_path, self.runtime else: self.update_node_neighbours( link_node, tmp_path) else: self.update_node_neighbours( link_node, tmp_path) else: self.update_node_neighbours( link_node, tmp_path) self.end = time.clock() self.runtime = self.end - self.start if self.runtime > 20: break except: pass return [], self.runtime
def querySatisfied(self, result): if days_query: if type(days_query) == list: if result['days'] not in days_query: return False if type(days_query) == int: if result['days'] != days_query: return False if price_query: if result['price'] > price_query[1] or result[ 'price'] < price_query[0]: return False if pois_query: if list(set(pois_query).intersection(set( result['poi_ids']))) != pois_query: return False if regions_query: regionsMapInGenPlan = { x['region_id']: x['days'] for x in result['tour_regions'] } regionsMapInQuery = { x['region_id']: x['day'] for x in regions_query } if set(regionsMapInQuery.keys()) - set(regionsMapInGenPlan.keys()): return False for regionId, days in regionsMapInQuery.items(): if days and regionsMapInGenPlan[regionId] != days: return False if regionNotGo_query: if set(result['region_ids']) & set(regionNotGo_query): return False if poiNotGo_query: if set(result['poi_ids']) & set(poiNotGo_query): return False if availableMonths_query: if set(availableMonths_query) - set(result['available_months']): return False if departRegionId_query: if departRegionId_query and places[parts[result['part_ids'][-1]][ 'place_id']]['region_id'] != departRegionId_query: return False if arrivalRegionId_query: if arrivalRegionId_query and places[parts[result['part_ids'][0]][ 'place_id']]['region_id'] != arrivalRegionId_query: return False if hotelRating_query: if hotelRating_query and hotelRating_query != result[ 'average_star_rating']: return False if result['hotel_poi_number'] == 0: return False if result['rental_car_pois'] % 2 != 0: return False depuPoi = [] if len(set(result['poi_ids'])) != len(result['poi_ids']): for i in result['poi_ids']: if result['poi_ids'].count(i) > 1: depuPoi.append(i) for i in set(depuPoi): if pois[i]['type'] not in [ 'Pois::CarRental', 'Pois::Airport', 'Pois::Hub' ]: return False for i in range(len(result['part_ids']) - 1): if not genPlanConstraint.station_constraint( result['part_ids'][i], result['part_ids'][i + 1], pois, parts): return False return True