def drawGraph(G): coords = xmlparser.getNodesCoords() fig = plt.gcf() fig.set_size_inches(24, 24, forward=True) i = 0 for node in G: (node_lat, node_lon) = coords[node] node_lat = float(node_lat) node_lon = float(node_lon) for adj_node in G[node]: (adj_node_lat, adj_node_lon) = coords[adj_node] adj_node_lat = float(adj_node_lat) adj_node_lon = float(adj_node_lon) plt.plot([node_lat, adj_node_lat], [node_lon, adj_node_lon], 'black') i = i + 1 print(i) fig.savefig('Tomsk.png', dpi=100)
def Find_Centers(clusters, G): # return centers of clusters res = [] coords = xmlparser.getNodesCoords() for cluster in clusters: sum_lat = 0. sum_lon = 0. for node in cluster: sum_lat += float(coords[node][0]) sum_lon += float(coords[node][1]) obj_coords = (sum_lat / len(cluster), sum_lon / len(cluster)) result = '-' min_dist = float('inf') for node in G: node_coords = coords[node] distance = 1000000 * ((float(node_coords[0]) - obj_coords[0])**2 + (float(node_coords[1]) - obj_coords[1])**2) if (distance < min_dist): min_dist = distance result = node res.append(result) return res
def getGraphList(): print('Строим граф...') streets = xmlparser.getRoads() graph_list = {} coords = xmlparser.getNodesCoords() for street in streets: # проверка на одностороннее движение oneway = False if 'oneway' in street.keys(): if (street['oneway'] == 'yes') or (street['oneway'] == 'true') or (street['oneway'] == '1'): oneway = True if 'junction' in street.keys(): if (street['junction'] == 'roundabout'): oneway = True if (street['highway'] == 'motorway') or (street['highway'] == 'motorway_link'): oneway = True # пустой список смежности refs = street['refs'] for node in refs: if (not node in graph_list.keys()): graph_list[node] = {} # ребра for i in range(len(refs)): if (i < len(refs) - 1): node1_coords = coords[refs[i]] node2_coords = coords[refs[i + 1]] distance = geodesic(node1_coords, node2_coords).m * (random.random() + 1) graph_list[refs[i]][refs[i + 1]] = distance if (not oneway): graph_list[refs[i + 1]][refs[i]] = distance print('Граф построен') return graph_list
def calc_basics_demo(recalc=False): if (recalc): buildings = xmlparser.getBuildings() firestations = xmlparser.getFireStations() roads = xmlparser.getRoads() coords = xmlparser.getNodesCoords() weights = {} for building in buildings: weights[building['id']] = 1. for firestation in firestations: weights[firestation['id']] = random.random() + 1 sl.save_obj(firestations, "firestations") sl.save_obj(buildings, "buildings") sl.save_obj(roads, "roads") sl.save_obj(coords, "coords") sl.save_obj(weights, "weights") print("demo files recalculated") G = graph.GetGraphListWithRead() sl.save_obj(G, "adj_list_demo")
def GetGraphList(): graph_list = {} roads = xmlparser.getRoads() coords = xmlparser.getNodesCoords() buildings = xmlparser.getBuildings() + xmlparser.getFireStations() print('phase1') for road in roads: oneway = False if 'oneway' in road.keys(): if road['oneway'] == 'yes': oneway = True nodes = road['nodes'] for node in nodes: if node not in graph_list.keys(): graph_list[node] = [] for i in range(len(nodes)): if (i < len(nodes) - 1): node1_coords = coords[nodes[i]] node2_coords = coords[nodes[i + 1]] distance = round(1000000*((float(node1_coords[0])-float(node2_coords[0]))**2 + (float(node1_coords[1])-float(node2_coords[1]))**2), 4) graph_list[nodes[i]].append((nodes[i+1],distance)) if not oneway: graph_list[nodes[i+1]].append((nodes[i],distance)) print('phase2') road_list = graph_list.copy() for building in buildings: graph_list[building['id']] = [] node1_coords = coords[building['id']] nearest_node = '-' min_dist = float('inf') for node in road_list: node2_coords = coords[node] distance = 1000000*((float(node1_coords[0])-float(node2_coords[0]))**2 + (float(node1_coords[1])-float(node2_coords[1]))**2) if (distance < min_dist): min_dist = distance nearest_node = node min_dist = round(min_dist, 4) graph_list[building['id']].append((nearest_node,min_dist)) graph_list[nearest_node].append((building['id'], min_dist)) build_nodes = [ building['id'] for building in buildings] print('phase3') # delete vertexes for v in road_list.keys(): if len(graph_list[v]) <=2: connect = False for vert in graph_list[v]: if vert[0] in build_nodes: connect = True break if connect == False: # oneway if len(graph_list[v]) == 1: vert_in = [] vert_out = [ vert[0] for vert in graph_list[v]] for vert in graph_list.keys(): if v in [ v_out[0] for v_out in graph_list[vert]]: vert_in.append(vert) if len(vert_in) == len(vert_out) and set(vert_in) != set(vert_out): l = [ v_out[0] for v_out in graph_list[vert_in[0]]] index = l.index(v) vert_del = graph_list[vert_in[0]][index] node1_coords = coords[vert_in[0]] node2_coords = coords[vert_out[0]] distance = round(1000000*((float(node1_coords[0])-float(node2_coords[0]))**2 + (float(node1_coords[1])-float(node2_coords[1]))**2), 4) graph_list[vert_in[0]].append((vert_out[0], distance)) while vert_del in graph_list[vert_in[0]]: graph_list[vert_in[0]].remove(vert_del) del graph_list[v] # twoways elif len(graph_list[v]) == 2: vert_in = [] vert_out = [ vert[0] for vert in graph_list[v]] for vert in graph_list.keys(): if v in [ v_out[0] for v_out in graph_list[vert]]: vert_in.append(vert) if len(vert_in) == len(vert_out) and set(vert_in) == set(vert_out): v1 = vert_in[0] v2 = vert_in[1] l1 = [ v_out[0] for v_out in graph_list[v1]] l2 = [ v_out[0] for v_out in graph_list[v2]] index1 = l1.index(v) index2 = l2.index(v) vert_del1 = graph_list[v1][index1] vert_del2 = graph_list[v2][index2] node1_coords = coords[v1] node2_coords = coords[v2] distance = round(1000000*((float(node1_coords[0])-float(node2_coords[0]))**2 + (float(node1_coords[1])-float(node2_coords[1]))**2), 4) graph_list[v1].append((v2, distance)) graph_list[v2].append((v1, distance)) while vert_del1 in graph_list[v1]: graph_list[v1].remove(vert_del1) while vert_del2 in graph_list[v2]: graph_list[v2].remove(vert_del2) del graph_list[v] print('graph is builded') return graph_list
def main(): # ============================= Генерация графа ============================== # g = graph.getGraphList() # ============================ Запись графа в файл ============================ # with open('graph.csv', 'w') as csv_file: # writer = csv.writer(csv_file, delimiter = ',') # for node in g: # line_csv = [] # line_csv.append(node) # for adj_node in g[node]: # line_csv.append(adj_node) # line_csv.append(g[node][adj_node]) # writer.writerow(line_csv) # ============================ Чтение графа из файла ========================== g = {} file_name = 'graph.csv' f = open(file_name, 'r') for line in f.readlines(): dates = line.split(',') dates[len(dates) - 1] = dates[len(dates) - 1][:len(dates[len(dates) - 1]) - 1] g[dates[0]] = {} r = int((len(dates) - 1) / 2) for i in range(r): g[dates[0]][dates[2 * i + 1]] = float(dates[2 * i + 2]) del g[''] f.close() # ================================== КРАТЧАЙШИЕ ПУТИ ==================================== buildings_list = xmlparser.getBuildingsNodes() hospitals_list = xmlparser.getHospitalsNodes() N = 10 M = 100 buildings = [] hospitals = [] coords = xmlparser.getNodesCoords() for i in range(N): hospitals.append(graph.NearestNode(g, coords, hospitals_list[i])) while (len(buildings) < M): buildings.append( graph.NearestNode(g, coords, random.choice(buildings_list))) all_ways_exist = False while (not all_ways_exist): building_trees = {} hospital_trees = {} for node in hospitals: hospital_trees[node] = graph.Dijkstra(g, node) for node in buildings: building_trees[node] = graph.Dijkstra(g, node) buildings_to_hospitals = {} hospitals_to_buildings = {} for node_b in buildings: buildings_to_hospitals[node_b] = {} for node_h in hospitals: (D, Parent) = building_trees[node_b] buildings_to_hospitals[node_b][node_h] = D[node_h] for node_h in hospitals: hospitals_to_buildings[node_h] = {} for node_b in buildings: (D, Parent) = hospital_trees[node_h] hospitals_to_buildings[node_h][node_b] = D[node_b] isolated_building = '' for node_b in buildings: for node_h in buildings_to_hospitals[node_b]: if (buildings_to_hospitals[node_b][node_h] == math.inf): isolated_building = node_b if (isolated_building != ''): buildings.remove(isolated_building) buildings.append( graph.NearestNode(g, coords, random.choice(buildings_list))) continue all_ways_exist = True # ============================= Запись деревьев в csv =========================== # for i in range(len(buildings)): # tree = pd.DataFrame(building_trees[buildings[i]]) # tree.to_csv('trees/buildings/building_'+str(i)+'.csv') # for i in range(len(hospitals)): # tree = pd.DataFrame(hospital_trees[hospitals[i]]) # tree.to_csv('trees/hospitals/hospital_'+str(i)+'.csv') # ============================= 1.1 ===================================== print('Задание 1.1') building_nearest_objects = {} for node_b in buildings: building_nearest_objects[node_b] = {} min_dist = math.inf nearest_from = '' for node_h in hospitals: if buildings_to_hospitals[node_b][node_h] < min_dist: nearest_from = node_h min_dist = buildings_to_hospitals[node_b][node_h] building_nearest_objects[node_b]['from'] = nearest_from min_dist = math.inf nearest_to = '' for node_h in hospitals: if hospitals_to_buildings[node_h][node_b] < min_dist: nearest_to = node_h min_dist = hospitals_to_buildings[node_h][node_b] building_nearest_objects[node_b]['to'] = nearest_to min_dist = math.inf nearest_fromto = '' for node_h in hospitals: if buildings_to_hospitals[node_b][node_h] + hospitals_to_buildings[ node_h][node_b] < min_dist: nearest_fromto = node_h min_dist = buildings_to_hospitals[node_b][ node_h] + hospitals_to_buildings[node_h][node_b] building_nearest_objects[node_b]['fromto'] = nearest_fromto print('Ближайшие больницы для каждого дома: ') print(building_nearest_objects) # ============================= 1.2 ===================================== print( 'Задание 1.2. Определить, какой из объектов расположен так, что время/расстояние между ним и самым дальним домом минимально' ) object_furthest_buildings = {} for node_h in hospitals: object_furthest_buildings[node_h] = {} max_dist = 0 furthest_from = '' for node_b in buildings: if hospitals_to_buildings[node_h][node_b] > max_dist: furthest_from = node_b max_dist = hospitals_to_buildings[node_h][node_b] object_furthest_buildings[node_h]['from'] = furthest_from max_dist = 0 furthest_to = '' for node_b in buildings: if buildings_to_hospitals[node_b][node_h] > max_dist: furthest_to = node_b max_dist = buildings_to_hospitals[node_b][node_h] object_furthest_buildings[node_h]['to'] = furthest_to max_dist = 0 furthest_fromto = '' for node_b in buildings: if hospitals_to_buildings[node_h][node_b] + buildings_to_hospitals[ node_b][node_h] > max_dist: furthest_fromto = node_b max_dist = hospitals_to_buildings[node_h][ node_b] + buildings_to_hospitals[node_b][node_h] object_furthest_buildings[node_h]['fromto'] = furthest_fromto print('Туда: ') min_max = math.inf ans = '' for node_h in hospitals: if (hospitals_to_buildings[node_h][object_furthest_buildings[node_h] ['from']] <= min_max): min_max = hospitals_to_buildings[node_h][ object_furthest_buildings[node_h]['from']] ans = node_h print('Ответ: ', ans) print('Расстояние до дома с номером ', object_furthest_buildings[ans]['from'], ' равно: ', min_max) print('Обратно: ') min_max = math.inf ans = '' for node_h in hospitals: if (hospitals_to_buildings[node_h][object_furthest_buildings[node_h] ['to']] <= min_max): min_max = hospitals_to_buildings[node_h][ object_furthest_buildings[node_h]['to']] ans = node_h print('Ответ: ', ans) print('Расстояние от дома с номером ', object_furthest_buildings[ans]['to'], ' равно: ', min_max) print('Туда и обратно: ') min_max = math.inf ans = '' for node_h in hospitals: if (hospitals_to_buildings[node_h][object_furthest_buildings[node_h] ['fromto']] + buildings_to_hospitals[object_furthest_buildings[node_h] ['fromto']][node_h] <= min_max): min_max = hospitals_to_buildings[node_h][object_furthest_buildings[ node_h]['fromto']] + buildings_to_hospitals[ object_furthest_buildings[node_h]['fromto']][node_h] ans = node_h print('Ответ: ', ans) print('Расстояние до+от дома с номером ', object_furthest_buildings[ans]['fromto'], ' равно: ', min_max) # ============================= 1.3 ===================================== print( 'Задание 1.3. Для какого объекта инфраструктуры сумма кратчайших расстояний от него до всех домов минимальна.' ) ans = '' min_sum = math.inf for node_h in hospitals: sum = 0 for node_b in buildings: sum = sum + hospitals_to_buildings[node_h][node_b] if (sum < min_sum): ans = node_h min_sum = sum print('Ответ: ', ans) print('Сумма: ', min_sum) # ============================= 1.4 ===================================== print( 'Задание 1.4. Для какого объекта инфраструктуры построенное дерево кратчайших путей имеет минимальный вес.' ) min_weight = math.inf ans = '' for node_h in hospitals: (D, Parent) = hospital_trees[node_h] subtree_edges = graph.getSubtreeEdges(Parent, node_h, buildings) subtree_weight = graph.getSubtreeWeight(subtree_edges, g) if (subtree_weight < min_weight): min_weight = subtree_weight ans = node_h print('Ответ: ', ans) print('Вес дерева: ', min_weight) # ============================== Интерфейс ======================================= # while(True): # print('Просмотреть информацию о больницах? Y/N ') # if (input() == 'Y'): # print('Номера N узлов-больниц: ') # for i in hospitals: # print(i) # print('Введите номер узла-больницы: ') # node_h = str(input()) # print('Ближайший дом: ') # min_dist = math.inf # nearest_building = '' # for node_b in buildings: # if hospitals_to_buildings[node_h][node_b] < min_dist: # nearest_building = node_b # min_dist = hospitals_to_buildings[node_h][node_b] # print(nearest_building) # print('Расстояние до него: ') # print(min_dist) # print('Путь до него: ') # (D, Parent) = hospital_trees[node_h] # print(graph.getWayInTree(Parent, node_h, nearest_building)) # else: # break # print('Просмотреть информацию о домах? Y/N ') # if (input() == 'Y'): # print('Номера M узлов-домов: ') # for i in buildings: # print(i) # print('Введите номер узла-дома: ') # node_b = str(input()) # print('Ближайшая больница: ') # min_dist = math.inf # nearest_hospital = '' # for node_h in hospitals: # if buildings_to_hospitals[node_b][node_h] < min_dist: # nearest_hospital = node_h # min_dist = buildings_to_hospitals[node_b][node_h] # print(nearest_hospital) # print('Расстояние до неё: ') # print(min_dist) # print('Путь до неё: ') # (D, Parent) = building_trees[node_b] # print(graph.getWayInTree(Parent, node_b, nearest_hospital)) # else: # break # ================================= 2 задание ====================================== print('Задание 2') hospital = hospitals[0] (D, Parent) = hospital_trees[hospital] subtree_edges = graph.getSubtreeEdges(Parent, hospital, buildings) weight = graph.getSubtreeWeight(subtree_edges, g) sum_w = 0 for node_b in buildings: sum_w = sum_w + D[node_b] print('Длина дерева:', weight) print('Сумма расстояний:', sum_w) for n in [2, 3, 5]: print(n, 'кластеров: ') clusters = cluster.Clustering(buildings, g, n) centers = cluster.FindCenters(clusters, g, coords) subtree_edges_obj = graph.getSubtreeEdges(Parent, hospital, centers) sum_w = 0 subtree_edges = subtree_edges_obj.copy() for i in range(len(clusters)): sum_w = sum_w + D[centers[i]] (D_cluster, Parent_cluster) = graph.Dijkstra(g, centers[i]) subtree_edges_cluster = graph.getSubtreeEdges( Parent_cluster, centers[i], clusters[i]) subtree_edges.update(subtree_edges_cluster) for node in clusters[i]: sum_w = sum_w + D_cluster[node] weight = graph.getSubtreeWeight(subtree_edges, g) print('Длина дерева:', weight) print('Сумма расстояний:', sum_w) visualisation.drawClusters(buildings, clusters, n, g, coords)