def buildGraph(mapEntries): g = Digraph() nodelist = [] #createing nodelist and adding nodes for eachEntry in mapEntries: eachEntrySource = eachEntry[0] eachEntryDest = eachEntry[1] if eachEntrySource not in nodelist: #making sure the node is unique nodelist.append(eachEntrySource) g.add_node(Node(eachEntrySource)) if eachEntryDest not in nodelist: nodelist.append(eachEntryDest) g.add_node(Node(eachEntryDest)) #creating edges for eachEntry in mapEntries: src = Node(eachEntry[0]) #eachEntrySource Node dest = Node(eachEntry[1]) #"eachEntryDest" tD = eachEntry[2] #eachEntryTotalDistance oD = eachEntry[3] #eachEntryOutdoorDistance g.add_edge(WeightedEdge(src, dest, tD, oD)) #Adding the weighted edge kind return g
def load_map(map_filename): """ Parses the map file and constructs a directed graph Parameters: map_filename : name of the map file Assumes: Each entry in the map file consists of the following four positive integers, separated by a blank space: From To TotalDistance DistanceOutdoors e.g. 32 76 54 23 This entry would become an edge from 32 to 76. Returns: a Digraph representing the map """ g = Digraph() with open(map_filename) as f: data = f.read().strip() dataList = data.split('\n') for mapEdge in dataList: edgeList = mapEdge.split(' ') # from to TD, DO fromN = Node(edgeList[0]) toN = Node(edgeList[1]) if not g.has_node(fromN): g.add_node(fromN) if not g.has_node(toN): g.add_node(toN) g.add_edge(WeightedEdge(fromN, toN, edgeList[2], edgeList[3])) return g
def jaccards_coefficient(self, source, target): nodes1 = self.database.one_to_many_nodes(source) nodes2 = self.database.one_to_many_nodes(target) n1 = set([Node(n).id for n in nodes1]) n2 = set([Node(n).id for n in nodes2]) score = len(n1.intersection(n2)) / len(n1.union(n2)) return score
def load_map(map_filename): """ Parses the map file and constructs a directed graph Parameters: map_filename : name of the map file Assumes: Each entry in the map file consists of the following four positive integers, separated by a blank space: From To TotalDistance DistanceOutdoors e.g. 32 76 54 23 This entry would become an edge from 32 to 76. Returns: a Digraph representing the map """ print("Loading map from file...") g = Digraph() with open(map_filename, "r") as file: for line in file: (src, dst, tot_dist, outdoor_dist) = line.split(' ') tot_dist = int(tot_dist) outdoor_dist = int(outdoor_dist) if not g.has_node(Node(src)): g.add_node(Node(src)) if not g.has_node(Node(dst)): g.add_node(Node(dst)) g.add_edge(WeightedEdge(src, dst, tot_dist, outdoor_dist)) return g
def load_map(map_filename): """ Parses the map file and constructs a directed graph Parameters: map_filename : name of the map file Assumes: Each entry in the map file consists of the following four positive integers, separated by a blank space: From To TotalDistance DistanceOutdoors e.g. 32 76 54 23 This entry would become an edge from 32 to 76. Returns: a Digraph representing the map """ # TODO # print("Loading map from file...") file = open(map_filename, 'r') # open the file g = Digraph() for line in file: # read each line of the file line = line.strip('\n') # remove the \n character line = line.split(' ') for i in range(0, 2): nod = Node(line[i]) if not g.has_node(nod): g.add_node(nod) wei_edge = WeightedEdge(Node(line[0]), Node(line[1]), int(line[2]), int(line[3])) g.add_edge(wei_edge) file.close() return g
def test_shortest_path_dijkstra_2(): g = Graph() a = Node('A') b = Node('B') g.node_list.append(a) g.node_list.append(b) assert g.shortest_path_dijkstra(a, b) is None
def load_map(map_filename): """ Parses the map file and constructs a directed graph Parameters: map_filename : name of the map file Assumes: Each entry in the map file consists of the following four positive integers, separated by a blank space: From To TotalDistance DistanceOutdoors e.g. 32 76 54 23 This entry would become an edge from 32 to 76. Returns: a Digraph representing the map """ print("Loading map from file...") inFile = open(map_filename, 'r') digraph = Digraph() for line in inFile: mapEntry = line.split() #mapEntry(list) src = Node(mapEntry[0]) dest = Node(mapEntry[1]) total_distance = int(mapEntry[2]) outdoor_distance = int(mapEntry[3]) edge = WeightedEdge(src, dest, total_distance, outdoor_distance) if not digraph.has_node(src): digraph.add_node(src) if not digraph.has_node(dest): digraph.add_node(dest) digraph.add_edge(edge) return digraph
def load_map(map_filename): """ Parses the map file and constructs a directed graph Parameters: map_filename : name of the map file Assumes: Each entry in the map file consists of the following four positive integers, separated by a blank space: From To TotalDistance DistanceOutdoors e.g. 32 76 54 23 This entry would become an edge from 32 to 76. Returns: a Digraph representing the map """ print("Loading map from file...") # MY_CODE map_graph = Digraph() with open(map_filename, 'r') as f: for line in f: src, dest, total_dist, outdoor_dist = line.split(' ') src = Node(src) dest = Node(dest) if not map_graph.has_node(src): map_graph.add_node(src) if not map_graph.has_node(dest): map_graph.add_node(dest) edge = WeightedEdge(src, dest, int(total_dist), int(outdoor_dist)) map_graph.add_edge(edge) return map_graph
def graph(): graph = Graph() graph.adjacency_list.append(Node('a')) graph.adjacency_list.append(Node('b')) graph.addEdge('a', 'b', 1) graph.addEdge('b', 'a', 2) return graph
def load_map(map_filename): """ Parses the map file and constructs a directed graph Parameters: map_filename : name of the map file Assumes: Each entry in the map file consists of the following four positive integers, separated by a blank space: From To TotalDistance DistanceOutdoors e.g. 32 76 54 23 This entry would become an edge from 32 to 76. Returns: a Digraph representing the map """ g = Digraph() # Create a digraph object print("Loading map from file...") with open(map_filename, "r") as f: for passage in f: # For each entry, store four info From, To, TotalD, OutD = passage.split() node_src, node_dest = Node(From), Node(To) if not g.has_node(node_src): g.add_node(node_src) if not g.has_node(node_dest): g.add_node(node_dest) g.add_edge( WeightedEdge(node_src, node_dest, int(TotalD), int(OutD))) return g
def get_best_path(digraph, start, end, path, max_dist_outdoors, best_dist, best_path): """ Finds the shortest path between buildings subject to constraints. Parameters: digraph: Digraph instance The graph on which to carry out the search start: string Building number at which to start end: string Building number at which to end path: list composed of [[list of strings], int, int] Represents the current path of nodes being traversed. Contains a list of node names, total distance traveled, and total distance outdoors. max_dist_outdoors: int Maximum distance spent outdoors on a path best_dist: int The smallest distance between the original start and end node for the initial problem that you are trying to solve best_path: list of strings The shortest path found so far between the original start and end node. Returns: A tuple with the shortest-path from start to end, represented by a list of building numbers (in strings), [n_1, n_2, ..., n_k], where there exists an edge from n_i to n_(i+1) in digraph, for all 1 <= i < k and the distance of that path. If there exists no path that satisfies max_total_dist and max_dist_outdoors constraints, then return None. """ start_node = Node(start) # 转换为Node对象 end_node = Node(end) # 转换为Node对象 if not digraph.has_node(start_node) or not digraph.has_node(end_node): raise ValueError('Node not exist') elif start == end: # 递归到end时,直接返回当前路径及其总长度 return path[0], path[1] else: for edge in digraph.edges[start_node]: # 加入下一个节点(当前起点的邻接点),构造出一个新路径,作为path参数进行递归 next_node = edge.get_destination().get_name() next_path_nodes = path[0] + [next_node] # 新路径经过的节点列表 next_path_total_dist = path[1] + edge.get_total_distance() # 新路径的总长度 next_path_outdoor_dist = path[2] + edge.get_outdoor_distance() # 新路径的室外长度 next_path = [next_path_nodes, next_path_total_dist, next_path_outdoor_dist] # 新的path参数 if (next_node not in path[0]) and (next_path[2] <= max_dist_outdoors) and (next_path[1] < best_dist): # 递归 new_best_path = get_best_path(digraph, next_node, end, next_path, max_dist_outdoors, best_dist, best_path) # 更新 if new_best_path is not None and new_best_path[1] < best_dist: best_dist = new_best_path[1] # 新的最短路径的长度 best_path = new_best_path[0] # 新的最短路径的节点列表 if best_path: # 列表非空,返回元组 return best_path, best_dist else: # 列表为空,返回None return None
def load_map(map_filename): """ Parses the map file and constructs a directed graph Parameters: map_filename : name of the map file Assumes: Each entry in the map file consists of the following four positive integers, separated by a blank space: From To TotalDistance DistanceOutdoors e.g. 32 76 54 23 This entry would become an edge from 32 to 76. Returns: a Digraph representing the map """ print("Loading map from file...") graph = Digraph() # 创建空图 with open(map_filename) as file: for line in file: elements = line.split() # 按空格分割成list src = Node(elements[0]) dest = Node(elements[1]) total_distance = int(elements[2]) # 数字类型 outdoor_distance = int(elements[3]) # 数字类型 if not graph.has_node(src): graph.add_node(src) if not graph.has_node(dest): graph.add_node(dest) graph.add_edge(WeightedEdge(src, dest, total_distance, outdoor_distance)) return graph
def simulated_annealing_full(graph, start, goal, rand, schedule=exp_schedule()): """ This version returns all the states encountered in reaching the goal state.""" states = [] start_node = Node(start, None) current = Node(start, None) for t in range(sys.maxsize): states.append(current.name) T = schedule(t) if T == 0: path = [] while current != start_node: path.append(current.name + ': ' + str(current.f)) current = current.parent path.append(start_node.name + ': ' + str(start_node.f)) # Return reversed path return path[::-1] #return states neighbors = graph.get(current.name) if not neighbors: return current.name next_choice = Node(choose(list(neighbors), rand), current) # Calculates path cost with realistic components current.f = components.componentAdjustments( rand, heuristicFunction(str(current.name), goal)) next_choice.f = components.componentAdjustments( rand, heuristicFunction(str(next_choice.name), goal)) # calcualtes delta e with the path costs delta_e = current.f - next_choice.f if delta_e > 0 or probability(np.exp(delta_e / T)): current = next_choice
def load_map(map_filename): """ Parses the map file and constructs a directed graph Parameters: map_filename : name of the map file Assumes: Each entry in the map file consists of the following four positive integers, separated by a blank space: From To TotalDistance DistanceOutdoors e.g. 32 76 54 23 This entry would become an edge from 32 to 76. Returns: a Digraph representing the map """ print("Loading map from file...") mit_map = Digraph() with open(map_filename, "r") as file: for line in file: content = line.split() src = Node(content[0]) dest = Node(content[1]) edge = WeightedEdge(src, dest, int(content[2]), int(content[3])) if not mit_map.has_node(src): mit_map.add_node(src) if not mit_map.has_node(dest): mit_map.add_node(dest) mit_map.add_edge(edge) return mit_map
def test_add_edge(): _graph = Graph() _node1 = Node(4) _node2 = Node(5) _graph.add_edges(_node1, _node2, 1) assert _graph.graph == {'n0': {'n1': 1}, 'n1': {'n0': 1}}
def directed_dfs(digraph, start, end, max_total_dist, max_dist_outdoors): """ Finds the shortest path from start to end using a directed depth-first search. The total distance traveled on the path must not exceed max_total_dist, and the distance spent outdoors on this path must not exceed max_dist_outdoors. Parameters: digraph: Digraph instance The graph on which to carry out the search start: string Building number at which to start end: string Building number at which to end max_total_dist: int Maximum total distance on a path max_dist_outdoors: int Maximum distance spent outdoors on a path Returns: The shortest-path from start to end, represented by a list of building numbers (in strings), [n_1, n_2, ..., n_k], where there exists an edge from n_i to n_(i+1) in digraph, for all 1 <= i < k If there exists no path that satisfies max_total_dist and max_dist_outdoors constraints, then raises a ValueError. """ # MY_CODE ret = get_best_path(digraph, Node(start), Node(end), [[start], 0, 0], max_dist_outdoors, max_total_dist, None) if ret[0] is None: raise ValueError("Problem shouldn't be impossible!") else: return ret[0]
def test_has_node(): _graph = Graph() _node1 = Node(4) _node2 = Node(5) _graph.add_node(_node1) assert _graph.had_node(_node1) == True assert _graph.had_node(_node2) == False
def _construct_graph( customers: Mapping[int, CustomerDemand], review_demands: Dict[int, int], num_of_products: int) -> Tuple[FlowGraph, Node, Node, dict]: source = Node("source") sink = Node("sink") graph = FlowGraph() product_nodes = {} for product in range(1, num_of_products + 1): product_node = Node("P" + str(product)) product_nodes[product] = product_node graph.create_edge(product_node, sink, review_demands[product], inf) assignment_edges = {} for customer in customers.values(): customer_node = Node("C" + str(customer.i)) graph.create_edge(source, customer_node, customer.low, customer.upper) for product in customer.products: edge = graph.create_edge(customer_node, product_nodes[product], 0, 1) assignment_edges[(customer.i, product)] = edge return graph, source, sink, assignment_edges
def test_find_all_paths(): """ you should test with graphs that have 0, 1, 3 paths """ g = Graph() node_1 = Node({'A': ['B', 'C']}) g.add(node_1) node_2 = Node({'B': ['C', 'D']}) g.add(node_2) node_3 = Node({'C': ['D']}) g.add(node_3) node_4 = Node({'D': ['C']}) g.add(node_4) node_5 = Node({'E': ['C']}) g.add(node_5) # zero path between node_1 and node_5 paths_0 = g.find_all_paths(node_1, node_5) assert len(paths_0) == 0 # only one path between node_5 and node_4 paths_1 = g.find_all_paths(node_5, node_4) assert len(paths_1) == 1 assert [node.name for node in paths_1[0]] == [node_5.name, node_3.name, node_4.name] # three paths between node_1 and node_3, verify all the three paths are returned paths_3 = g.find_all_paths(node_1, node_3) assert len(paths_3) == 3 for path in paths_3: assert [ node.name for node in path ] == [ node_1.name, node_2.name, node_3.name ] or \ [ node.name for node in path ] == [ node_1.name, node_2.name, node_4.name, node_3.name ] or \ [ node.name for node in path ] == [ node_1.name, node_3.name ]
def test_edge_init(): e = Edge(Node(1), Node(2)) assert e is not None assert e.n1 is not None assert e.n1.value == 1 assert e.n2 is not None assert e.n2.value == 2
def test_find_shortest_path(): """ you should test with graphs that have 0, 1, 3 paths """ g = Graph() node_1 = Node({'A': ['B', 'C']}) g.add(node_1) node_2 = Node({'B': ['C', 'D']}) g.add(node_2) node_3 = Node({'C': ['D']}) g.add(node_3) node_4 = Node({'D': ['C']}) g.add(node_4) node_5 = Node({'E': ['C']}) g.add(node_5) # zero path between node_1 and node_5 path_0 = g.find_shortest_path(node_1, node_5) assert path_0 == None # only one path between node_5 and node_4 path_1 = g.find_shortest_path(node_5, node_4) assert [node.name for node in path_1] == [node_5.name, node_3.name, node_4.name] # three paths between node_1 and node_3, verify the shortest one is returned path_3 = g.find_shortest_path(node_1, node_3) assert [node.name for node in path_3] == [node_1.name, node_3.name]
def common_neighbors(self, source, target): nodes1 = self.database.one_to_many_nodes(source) nodes2 = self.database.one_to_many_nodes(target) n1 = set([Node(n).id for n in nodes1]) n2 = set([Node(n).id for n in nodes2]) score = len(n1.intersection(n2)) return score
def directed_dfs(digraph, start, end, max_total_dist, max_dist_outdoors): """ Finds the shortest path from start to end using a directed depth-first search. The total distance traveled on the path must not exceed max_total_dist, and the distance spent outdoors on this path must not exceed max_dist_outdoors. Parameters: digraph: Digraph instance The graph on which to carry out the search start: string Building number at which to start end: string Building number at which to end max_total_dist: int Maximum total distance on a path max_dist_outdoors: int Maximum distance spent outdoors on a path Returns: The shortest-path from start to end, represented by a list of building numbers (in strings), [n_1, n_2, ..., n_k], where there exists an edge from n_i to n_(i+1) in digraph, for all 1 <= i < k If there exists no path that satisfies max_total_dist and max_dist_outdoors constraints, then raises a ValueError. """ start=Node(start) end=Node(end) best_path=get_best_path(digraph,start,end,[],max_total_dist,max_dist_outdoors,None) if best_path==None: raise ValueError('NO best path exists') return [node.get_name() for node in best_path]
def preferential_attachment(self, source, target): nodes1 = self.database.one_to_many_nodes(source) nodes2 = self.database.one_to_many_nodes(target) n1 = set([Node(n).id for n in nodes1]) n2 = set([Node(n).id for n in nodes2]) score = len(n1) * len(n2) return score
def load_map(mapFname): #TODO print "Loading map from file..." dataFile = open(mapFname, 'r') #open mit_map.txt in read-only mode, assign it to dataFile variable travel_map = WD() #create empty weighted directed graph node_dic = {} edge_list = [] for line in dataFile: if len(line) == 0 or line[0] == '#': #skip null or comment lines continue src, dest, distance, outside_distance = line.split() #pull relevant data from line if src not in node_dic: node_dic[src] = Node(src) if dest not in node_dic: node_dic[dest] = Node(dest) edge_list.append((src, dest, distance, outside_distance)) for node in node_dic.values(): travel_map.addNode(node) for edge in edge_list: start = node_dic[edge[0]] end = node_dic[edge[1]] WEdge = WE(start, end, edge[2], edge[3]) travel_map.addEdge(WEdge) dataFile.close() return travel_map
def load_map(map_filename): """ Parses the map file and constructs a directed graph Parameters: map_filename : name of the map file Assumes: Each entry in the map file consists of the following four positive integers, separated by a blank space: From To TotalDistance DistanceOutdoors e.g. 32 76 54 23 This entry would become an edge from 32 to 76. Returns: a Digraph representing the map """ print("Loading map from file...") openfile = open(map_filename, 'r') gph = Digraph() for line in openfile: NewLine = line.strip('\n').split(" ") a, b, c, d = NewLine a, b = Node(a), Node(b) c, d = int(c), int(d) if a not in gph.nodes: gph.add_node(a) if b not in gph.nodes: gph.add_node(b) DirEdge = WeightedEdge(a, b, c, d) gph.add_edge(DirEdge) openfile.close() return gph
def load_map(map_filename): """ Parses the map file and constructs a directed graph Parameters: map_filename : name of the map file Assumes: Each entry in the map file consists of the following four positive integers, separated by a blank space: From To TotalDistance DistanceOutdoors e.g. 32 76 54 23 This entry would become an edge from 32 to 76. Returns: a Digraph representing the map """ # print("Loading map from file...") inFile = open(map_filename, 'r') graph = Digraph() for line in inFile: linedata = line.split(' ') scr = Node(linedata[0]) des = Node(linedata[1]) graph.nodes.add(scr) graph.nodes.add(des) if not scr in graph.edges: graph.add_node(scr) if not des in graph.edges: graph.add_node(des) edge = WeightedEdge(scr, des, int(linedata[2]), int(linedata[3])) graph.add_edge(edge) return graph
def create_graph(name, num_mid=200): ''' Create a graph instance for use with Mnist. @type name: str @param name: The name of the graph. @type num_mid: int @param num_mid: The number of nodes in the middle hidden layer. ''' # Create the net graph, first the nodes ins = [ Node(node_type=NodeType.IN) for i in range(Mnist._IMG_SIZE_FLAT) ] mids = [Node() for i in range(int(num_mid))] outs = [Node(node_type=NodeType.OUT) for i in range(Mnist._N_CLASSES)] # Connect them up for r in ins: for n in mids: n.add_referee(r) for r in mids: for n in outs: n.add_referee(r) # Put them into the graph graph = Graph(name, ins, outs) for n in mids: graph.add_node(n) assert graph.is_connected() # And give it back return graph
def get_best_path(digraph, start, end, path, max_dist_outdoors, best_dist, best_path): """ Finds the shortest path between buildings subject to constraints. Parameters: digraph: Digraph instance The graph on which to carry out the search start: string Building number at which to start end: string Building number at which to end path: list composed of [[list of strings], int, int] Represents the current path of nodes being traversed. Contains a list of node names, total distance traveled, and total distance outdoors. max_dist_outdoors: int Maximum distance spent outdoors on a path best_dist: int The smallest distance between the original start and end node for the initial problem that you are trying to solve best_path: list of strings The shortest path found so far between the original start and end node. Returns: A tuple with the shortest-path from start to end, represented by a list of building numbers (in strings), [n_1, n_2, ..., n_k], where there exists an edge from n_i to n_(i+1) in digraph, for all 1 <= i < k and the distance of that path. If there exists no path that satisfies max_total_dist and max_dist_outdoors constraints, then return None. """ # sanity checks start_node, end_node = Node(start), Node(end) if not digraph.has_node(start_node) or not digraph.has_node(end_node): raise ValueError('Start or end node do not exist in digraph') # base case: update best path, best dist elif start_node == end_node: best_path, best_dist = path[0], path[1] for edge in digraph.get_edges_for_node( start_node): # for each outgoing edge current_node = edge.get_destination() # get the dest node if current_node.get_name() not in path[0]: # no loops current_path = path[0] + [current_node.get_name() ] # add onto current path total_outdoor_dist = edge.get_outdoor_distance() + path[2] total_dist = edge.get_total_distance() + path[1] if total_outdoor_dist <= max_dist_outdoors and ( best_dist == None or total_dist <= best_dist): updatedPath = [current_path, total_dist, total_outdoor_dist] newPath = get_best_path(digraph, current_node, end, updatedPath, max_dist_outdoors, best_dist, best_path) if newPath != None: best_path, best_dist = newPath return (best_path, best_dist) if best_path != None else None
def get_best_path(digraph, start, end, path, max_dist_outdoors, best_dist, best_path): """ Finds the shortest path between buildings subject to constraints. Parameters: digraph: Digraph instance The graph on which to carry out the search start: string Building number at which to start end: string Building number at which to end path: list composed of [[list of strings], int, int] Represents the current path of nodes being traversed. Contains a list of node names, total distance traveled, and total distance outdoors. max_dist_outdoors: int Maximum distance spent outdoors on a path best_dist: int The smallest distance between the original start and end node for the initial problem that you are trying to solve best_path: list of strings The shortest path found so far between the original start and end node. Returns: A tuple with the shortest-path from start to end, represented by a list of building numbers (in strings), [n_1, n_2, ..., n_k], where there exists an edge from n_i to n_(i+1) in digraph, for all 1 <= i < k and the distance of that path. If there exists no path that satisfies max_total_dist and max_dist_outdoors constraints, then return None. """ path[0] = path[0] + [start] if not (digraph.has_node(Node(start)) and digraph.has_node(Node(end))): raise ValueError("Graph doesn't have the node") if start == end: return (path[0], path[1]) for edge in digraph.get_edges_for_node(Node(start)): #避免回路 if str(edge.get_destination()) not in path[0]: #要符合室外距离之和小于max_dist_outdoors if edge.get_outdoor_distance()+path[2]<=max_dist_outdoors: #判断是否需要更新路径,即判断路径是否为空或者有更短的路径 if best_path == None or path[1]+edge.get_total_distance()<best_dist: #更新总距离和室外距离 tem_path=[path[0].copy(), path[1]+edge.get_total_distance(), path[2]+edge.get_outdoor_distance()] #对更新了总距离和室外距离的路径递归调用函数,注意返回值是元组 new_path,new_dist = get_best_path(digraph, str(edge.get_destination()), end, tem_path, max_dist_outdoors, best_dist, best_path) #如果找到了就更新最佳路径和最佳距离 if new_path != None: best_path = new_path best_dist = new_dist return (best_path, best_dist)