Example #1
0
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)
Example #2
0
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
Example #3
0
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")
Example #5
0
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
Example #6
0
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)