Как выглядело бы Московское метро в трехмерном мире

UPD: По просьбам в комментах добавляю ссылку на вращабельную схему на Javascript
К сожалению, код javascript вставить в тело поста не удалось
Добрый день! Недавно я читал блог одного урбаниста, который рассуждал о том, какая должна быть идеальная схема метро.Схему метро можно рисовать исходя из двух принципов:

  • Схема должна быть удобной и простой для запоминания и ориентирования
  • Схема должна соответствовать географии города

Очевидно, что эти принципы взаимоисключающие и первый принцип требует существенного искажения географической реальности.

Достаточно вспомнить, как выглядит схема Московского метро с красивыми кольцами и прямыми линиями:

image

и сравнить с географически точным планом:

image

На плане видно что кольца вовсе не являются идеально ровными и концентрическими, линии изгибаются гораздо сильнее, чем в схеме, а плотность станций в центре города настолько велика, что в плане практически невозможно разобраться.

И хотя второе изображение гораздо точнее отображает реальность, видно, что пользоваться для планирования маршрута в метро удобнее первой схемой.

И тут мне в голову пришла следующая мысль: «Как выглядело бы метро, если бы критерием для построения схемы являлось время, требуемое для перемещения от одной станции к другой?». То есть если от одной станции до другой добраться быстро, то пространственно они на схеме располагались бы недалеко.

Очевидно, что в двумерном пространстве невозможно нарисовать такую схему, в которой расстояние между двумя станциями равнялось бы времени путешествия от одной к другой из-за сложной топологии графа метро.

Также есть догадка, что такое точно возможно при построении схемы в пространстве с высокой размерностью (верхняя оценка n-1, где n- число станций). Для пространства с небольшим количеством измерений такую схему можно построить лишь приближенно.

Задача построения карты метро по времени путешествия выглядит типичной задачей оптимизации.
Пусть у нас есть начальный набор координат всех станций (X,Y,Z) и целевая матрица попарных времен (расстояний). Можно сконструировать метрику «неправильность» данного набора координат и далее минимизировать ее методом градиентного спуска по каждой из координат каждой станции. В качестве метрики можно взять простую функцию среднеквадратичного отклонения расстояний.

Что же, осталось дело за малым — нужно получить данные о том, сколько времени следует затратить на путешествие от любой станции московского метро к любой другой.

Первой мыслью было проверить api яндекс метро и вытащить оттуда эти данные. К сожалению, описания api и найти не удалось. Смотреть времена вручную в приложении долго (в метро 268 станций и размер матрицы времен 268*268=71824). Поэтому я решил разобраться в исходных данных Яндекс Метро. Так как доступа к серверу нет, был скачан apk файл с приложением и обнаружены необходимые данные. Вся информация о метро замечательно структурирована и хранится в формате JSON в папке assets/metrokit/ apk-архива приложения. Все данные хранятся в self-explanotary структурах. Meta.json содержит информацию о городах, схемы которых присутствуют в приложении, а также id данных схем.

{
            "id": "sc77792237", 
            "name": {
                "en": "Nizhny Novgorod", 
                "ru": "Нижний Новгород", 
                "tr": "Nizhny Novgorod", 
                "uk": "Нижній Новгород"
            }, 
            "size": {
                "packed": 30300, 
                "unpacked": 145408
            }, 
            "tags": [
                "published"
            ], 
            "aliases": [
                "nizhny-novgorod"
            ], 
            "logoUrl": "https://avatars.mds.yandex.net/get-bunker/135516/f2f0e33d8def90c56c189cfb57a8e6403b5a441c/orig", 
            "version": "2c27fe1", 
            "geoRegion": {
                "delta": {
                    "lat": 0.168291, 
                    "lon": 0.219727
                }, 
                "center": {
                    "lat": 56.326635, 
                    "lon": 43.992153
                }
            }, 
            "countryCode": "RU", 
            "defaultAlias": "nizhny-novgorod"
        }

По id схемы находим папку с JSON, относящиеся и к Москве.

Файл data.json содержит основную информацию о графе метро, включая названия узлов графа, id узлов, географические координаты узлов, информацию о переходах с одной станции на другую (id, время перехода, тип перехода — перегон или пешком, по улицу или нет, время интересующее нас в секундах) а также много дополнительной информации о входах и выходах со станции. С этим достаточно легко разобраться. Начнем писать код для построения нашей схемы.

Импортируем необходимые библиотеки:

import numpy as np 
import json
import codecs
import networkx as nx
import matplotlib.pyplot as plt
import pandas as pd 
import itertools
import keras
import keras.backend as K
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.proj3d import proj_transform
from matplotlib.text import Annotation
import pickle

Структура словарей и списков python полностью соответствует структуре формата json, поэтому читаем иннформацию о метро и создаем объекты, соответствующие json объектам.

names = json.loads(codecs.open( "l10n.json", "r", "utf_8_sig" ).read() )
graph = json.loads(codecs.open( "data.json", "r", "utf_8_sig" ).read() )

Создаем словарь, ставящий в соответствие узлы графа и станции (это необходима для так как к именам привязаны именно станции, а не узлы графа)

Также на всякий случай сохраним координаты узлов для возможности построения географической карты (нормированы на диапазон 0-1)

nodeStdict={}
for stop in graph['stops']['items']:
    nodeStdict[stop['nodeId']]=stop['stationId']
coordDict={}
for node in graph['nodes']['items']:
    coordDict[node['id']]=(node['attributes']['geoPoint']['lon'],node['attributes']['geoPoint']['lat'])
lats=[]
longs=[]
for value in coordDict.values():
    lats.append(value[1])
    longs.append(value[0])
for k,v in coordDict.items():
    coordDict[k]=((v[0]-np.min(longs))/(np.max(longs)-np.min(longs)),(v[1]-np.min(lats))/(np.max(lats)-np.min(lats)))

Создадим граф метро со связями. Зададим веса каждой связи. Вес соответствует времени в пути. Удалим узлы, не являющиеся станциями (по-моему это выходы из метро а связи к ним нужны для яндекс карт при расчете времени, но точно не разбирался) создадим словарь id узла- реальное название на русском языке

G=nx.Graph()
for node in graph['nodes']['items']:
    G.add_node(node['id'])
#graph['links']
for link in graph['links']['items']:
    #G.add_edges_from([(link['fromNodeId'],link['toNodeId'])])
    G.add_edge(link['fromNodeId'], link['toNodeId'], length=link['attributes']['time'])
nodestoremove=[]
for node in G.nodes():
    if len(G.edges(node))<2:
        nodestoremove.append(node)
for node in nodestoremove:
    G.remove_node(node)
labels={}
for node in G.nodes():
    try:
        labels[node]=names['keysets']['generated'][nodeStdict[node]+'-name']['ru']
    except: labels[node]='error'

Определим к какой ветке (к какому id ветки) относится каждый узел (это понадобится позже для раскрашивания линий метро на схеме)

def getlines(graph, G):
    nodetoline={}
    id_from={}
    id_to={}
    for lk in graph['tracks']['items']:
        id_from[lk['id']]=lk['fromNodeId']
        id_to[lk['id']]=lk['toNodeId']
    for line in graph['linesToTracks']['items']:
        if line['trackId'] in id_from.keys():
            nodetoline[id_from[line['trackId']]]=line['lineId']
            nodetoline[id_to[line['trackId']]]=line['lineId']
    return nodetoline
lines=getlines(graph,G)

библиотека networkx позволяет найти длину кратчайшего пути от одного узла к другому при помощи функции nx.shortest_path_length(G, id1, id2, weight='length'), поэтому можно считать что с подготовкой данных закончили. Следующее, что необходимо сделать — подготовить модель, которая будет оптимизировать координаты станций.

Для этого разберемяся, что будет даваться на вход, на выход и как будем оптимизировать матрицу координат станций.

Предположим, у нас есть матрица всех координат (3x268). Умножение one-hot вектора (вектора, где везде 0, кроме одной единичной координаты на месте n) размерности 268 на данную матрицу координат даст 3 координаты, соответствующие станции n. Если мы возьмем пару one-hot векторов и умножим их на необходимую матрицу, то получим две тройки координат. Из пары координат можно расчитать евклидово расстояние между станциями. Таким образом, можно определить архитектуру нашей модели:



на вход мы подаем пару станций, на выходе получаем расстояние между ними.

После того, как мы определились с форматом данных для обучения модели, подготовим данные с использованием поиска расстояний на графе:

myIDs=list(G.nodes())
listofinputs1=[]
listofinputs2=[]
listofoutputs=[]
for pair in itertools.product(G.nodes(), repeat=2):
    vec1=np.zeros((len(myIDs)))
    vec2=np.zeros((len(myIDs)))
    vec1[myIDs.index(pair[0])]=1
    vec2[myIDs.index(pair[1])]=1
    listofinputs1.append(vec1)
    listofinputs2.append(vec2)
    #listofinputs.append([vec1,vec2])
    listofoutputs.append(nx.shortest_path_length(G, pair[0], pair[1], weight='length')/3600)
    #myDistMatrix[myIDs.index(pair[0]),myIDs.index(pair[1])]=nx.shortest_path_length(G, pair[0], pair[1], weight='length')

Оптимизируем методом градиентного спуска матрицу координат станций.

Если мы будем использовать фреймворк keras для машинного обучения, то получим следующее:

np.random.seed(0)
initweightmatrix=np.zeros((len(myIDs),3))
for i in range(len(myIDs)):
    initweightmatrix[i,:2]=coordDict[myIDs[i]]
    initweightmatrix[i,2]=np.random.randn()*0.001

def euclidean_distance(vects):
    x, y = vects
    sum_square = K.sum(K.square(x - y), axis=1, keepdims=True)
    return K.sqrt(K.maximum(sum_square, K.epsilon()))
def eucl_dist_output_shape(shapes):
    shape1, shape2 = shapes
    return (shape1[0], 1)

inp1=keras.layers.Input((len(myIDs),))
inp2=keras.layers.Input((len(myIDs),))
layer1=keras.layers.Dense(3,use_bias=None, activation=None)
x1=layer1(inp1)
x2=layer1(inp2)
x=keras.layers.Lambda(euclidean_distance,
                  output_shape=eucl_dist_output_shape)([x1, x2])
out=keras.layers.Dense(1,use_bias=None,activation=None)(x)
model=keras.Model(inputs=[inp1,inp2],outputs=out)
model.layers[2].set_weights([initweightmatrix])
model.layers[2].trainable=False
model.compile(optimizer=keras.optimizers.Adam(lr=0.01), loss='mse')

заметим, что в качестве начальных координат в слое layer1 мы используем реальные географические координаты -это необходимо для того, чтобы не попасть в локальный минимум функции СКО. Третью координату инициализируем ненулевой для получения ненулевого градиента (если в начале карта будет абсолютно плоской, смещение любой станции вверх или вниз будет равнозначно, следовательно градиент равен 0 и оптимизации z не произойдет). Последний элемент нашей модели (Dense(1)) влияет на масштабирование схемы для соответствия временной шкале.

Расстояние будем измерять в часах, а не секундах, так как порядки расстояний — около 1 часа, а для более эффективного обучении модели важно, чтобы все величины (входные данные, веса, targetы) были примерно одного порядка по величине. Если эти значения близки к 1, то можно использовать стандартные значения шага при оптимизации (0.001-0.01).

Строка model.layers[2].trainable=False замораживает координаты станций и на первом этапе варьируется один параметр — масштаб. После подбора масштаба нашей схемы размораживаем координаты и оптимизируем уже их:

hist=model.fit([listofinputs1,listofinputs2],listofoutputs,batch_size=71824,epochs=200)
model.layers[2].trainable=True
model.layers[-1].trainable=False
model.compile(optimizer=keras.optimizers.Adam(lr=0.01), loss='mse')
hist2=model.fit([listofinputs1,listofinputs2],listofoutputs,batch_size=71824,epochs=200)

видим, что на вход подаем сразу все пары станций, на выходе — все расстояния и наша оптимизация- full batch gradient descent (один шаг на всех данных). Функция loss в данном случае — среднеквадратичное отклонение и можно видеть, что оно составило 0.015 в конце обучения, что значит среднеквадратичное отклонение менее чем в 1 минуты для любой пары станций. Иными словами, полученная схема позволяет точно узнать расстояние, которое требуется, чтобы добраться от одной станции к другой по расстоянию по прямой между станциями сточностью +-1 минута!

Но давайте посмотрим, как выглядит наша схема!

получим координаты станций, возьмем цветовую кодировку линий и построим 3d изображение с подписями (код для красивого отображения подписей взят отсюда):

class Annotation3D(Annotation):
    '''Annotate the point xyz with text s'''

    def __init__(self, s, xyz, *args, **kwargs):
        Annotation.__init__(self,s, xy=(0,0), *args, **kwargs)
        self._verts3d = xyz        

    def draw(self, renderer):
        xs3d, ys3d, zs3d = self._verts3d
        xs, ys, zs = proj_transform(xs3d, ys3d, zs3d, renderer.M)
        self.xy=(xs,ys)
        Annotation.draw(self, renderer)

def annotate3D(ax, s, *args, **kwargs):
    '''add anotation text s to to Axes3d ax'''

    tag = Annotation3D(s, *args, **kwargs)
    ax.add_artist(tag)

fincoords=model.layers[2].get_weights()
ccode={}
for obj in graph['services']['items']:
    ccode[obj['id']]=('\#'+obj['attributes']['color'])[1:]

xn = fincoords[0][:,0]
yn = fincoords[0][:,1]
zn = fincoords[0][:,2]
l=[labels[idi] for idi in myIDs]
colors=[ccode[lines[idi]] for idi in myIDs]
xyzn = zip(xn, yn, zn)

fig = plt.figure()
ax = fig.gca(projection='3d')
ax.scatter(xn,yn,zn, c=colors, marker='o')
for j, xyz_ in enumerate(xyzn): 
    annotate3D(ax, s=labels[myIDs[j]], xyz=xyz_, fontsize=9, xytext=(-3,3),
               textcoords='offset points', ha='right',va='bottom')    
plt.show()

Так как возникли трудности с конвертацией в интерактивный 3d формат для браузера, выкладываю гифки:



более красиво и узнаваемо выглядит версия без текста:

xn = fincoords[0][:,0]
yn = fincoords[0][:,1]
zn = fincoords[0][:,2]
l=[labels[idi] for idi in myIDs]
colors=[ccode[lines[idi]] for idi in myIDs]
xyzn = zip(xn, yn, zn)

fig = plt.figure()
ax = fig.gca(projection='3d')
ax.scatter(xn,yn,zn, c=colors, marker='o')
plt.show()



UPD: Добавим линии метро нужного цвета и создадим гифку. Черные линии — переходы между станциями:

myedges=[(myIDs.index(edge[0]),myIDs.index(edge[1]))for edge in G.edges]
xn = fincoords[0][:,0]
yn = fincoords[0][:,1]
zn = fincoords[0][:,2]
l=[labels[idi] for idi in myIDs]
c=[ccode[lines[idi]] for idi in myIDs]

fig = plt.figure()
ax = fig.gca(projection='3d')
ax.scatter(x,y,z, c=c, marker='o',s=25)
for edge in myedges:
    col='black'
    if c[edge[0]]==c[edge[1]]:
        col=c[edge[0]]
    ax.plot3D([x[edge[0]], x[edge[1]]], [y[edge[0]], y[edge[1]]], [z[edge[0]], z[edge[1]]], col)

ims = []

def rotate(angle):
    ax.view_init(azim=angle)

rot_animation = animation.FuncAnimation(fig, rotate, frames=np.arange(0, 362, 3), interval=70)
rot_animation.save('rotation2.gif', dpi=80, writer=matplotlib.animation.PillowWriter(80))



Из данной схемы можно сделать некоторые интересные выводы, которые не столь очевидны из других схем. Для некоторых веток, например зеленой, синей или фиолетовой МЦК (розовое кольцо) практически бесполезно из-за неудобных пересадок, что видно в удалении кольца от этих веток. Самые длинные по времени маршруты — от коммунарки до щелкого или пятницкого шоссе (коней красной и розовая/синяя линии) длинные маршруты так же алмаатинская-рассказовка и бунинская аллея-некрасовка. На севере Москвы, судя по плану, происходит частичное дублирование серой и салатовой ветками — они находятся рядом на схеме. Было бы итересно посмотреть на то, как новые линии (МЦД, БКЛ) и кто чаще будет пользоваться ими. В любом случае, надеюсь, подобные схемы могут быть интересным инструментам анализа, вдохновения и планирования поездок.

P.S. 3D не обязательно, для 2D варианта достаточно чуть-чуть исправить код. Но в случае 2d схемы добиться подобной точности расстояний невозможно.

Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 87

    +8
    Интересно читать с точки зрения визуализации данных на python.
    Но по метро уже есть 3d схема, которую можно повертеть:схема метро
      +10
      Это не та 3d схема про которую вы подумали, это граф по времени между станциями
        +1
        хм, там же написано большими буквами «Модель Московского метро в 3D» :D
      +17
      Вы, как автор, понимаете какая ось что значает. Было бы здорово, если бы читатель тоже понимал.
        +11
        в нормальных институтах сразу 2 ставили за отсутствие единиц измерений в формулах и отсутствие названия и единиц измерений у координат на графиках.
          +4

          Единицы измерения в этом пространстве — часы. Расстояние между любой парой станций по прямой равно времени, которое нужно затратить на поездку с учётом пересадок (в часах)

            0
            А оси что значат?
              +8
              Оси не имеют физического смысла. На картинке отрисован граф, не схема. Расстояние между двумя любыми точками (например, на разных линиях) — это время поездки.
                +1
                Ошибся уровнем, вопрос топикстартеру Sakhar.
                Ну а пользоваться как? Куда вбить два названия станций, и увидеть время и маршрут? Или вбить одно название и время, и увидеть, куда можно за это время доехать? Подозреваемый Х сел в метро на станции С, где он может выйти через 10 минут?

                А по названию статьи я подумал, что вы глубину залегания станций на схеме отразили, в центре должно было бы интересное макраме визуализироваться…
          0
          del
            +1
            скажите, а русский — ваш родной язык? про Питон не спрашиваю, он точно родной, владеете вы им превосходно
              +6

              Тогда к чему вопрос? Как не может у человека быть двух Родин, так не может быть и двух родных языков.

                –2
                а) может (гуглить по слову «билингвы»)
                б) научитесь понимать юмор и сарказм. Сложно, но у вас получится
                  +27
                  научитесь понимать юмор и сарказм
                  сказал человек, не распознавший сарказм
                    +4

                    Автрры тупых шуток любят говорить "учись понимать юмор". Учиться делать вид, что смешна каждая тупизна — вредно.

                      0

                      На любую шутку найдется тот, кто не поймет. Но потом обязательно скажет, что это не потому, что он не понял, а потому, что "тупизна"

                        0
                        Нужно просто дошучивать в позитив, как будто бы понял шутку, и улучшить её
                          +3
                          Только на хабре можно найти людей так серьезно разбирающих юмор.
                            0
                            На реддите еще можно
                    +3

                    Я бы сказал, что родной язык автора математика, что встречается реже, чем Питон.
                    P.S. За красивое и приятное оформление кода автору респект. Это важнее, чем использование всех возможностей языка

                      0
                      Родной язык не означает что априори можешь говорить/писать идеально и правильно.
                        –2
                        идите от обратного: если язык НЕ родной, то это дает индульгенцию. А если родной, то писать так косноязычно как автор — позор.

                        Было бы итересно посмотреть на то, как новые линии (МЦД, БКЛ) и кто чаще будет пользоваться ими.
                      0

                      Можно ли скачать граф с названием станций в каком-то общедоступным в формате чтобы покрутить на досуге? Те, что в статье крутятся так быстро, ничего не понятно

                        0
                        Я немного опасаюсь того, что взял информацию из apk-файла яндекс метро для андроида, поэтому не знаю, можно ли выложить граф, полученный из него. Граф можно сохранить, выполнив следующий код
                        names = json.loads(codecs.open( "l10n.json", "r", "utf_8_sig" ).read() )
                        graph = json.loads(codecs.open( "data.json", "r", "utf_8_sig" ).read() )
                        G=nx.Graph()
                        for node in graph['nodes']['items']:
                            G.add_node(node['id'])
                        #graph['links']
                        for link in graph['links']['items']:
                            #G.add_edges_from([(link['fromNodeId'],link['toNodeId'])])
                            G.add_edge(link['fromNodeId'], link['toNodeId'], length=link['attributes']['time'])
                        nodestoremove=[]
                        for node in G.nodes():
                            if len(G.edges(node))<2:
                                nodestoremove.append(node)
                        for node in nodestoremove:
                            G.remove_node(node)
                        labels={}
                        for node in G.nodes():
                            try:
                                labels[node]=names['keysets']['generated'][nodeStdict[node]+'-name']['ru']
                            except: labels[node]='error'
                        G = nx.relabel_nodes(G, labels)
                        nx.write_gml(G, "path_where_graph_should_be_saved.gml")
                        

                        Файлы с JSON из приложения должны находиться в той же папке что и код. В результате генерируется граф в формате gml с названиями, связями и временами в пути.
                          0
                          Большое спасибо, но я имел ввиду лишь 3D модель: вращающиеся штуки в статье ужасны в отличие от прекрасного кода
                            0

                            Ссылка на схему на javascript в шапке, дублирую тут https://alexankharin.github.io/
                            Здесь можно и самому схему покрутить

                              0
                              Класс, спасибо, слона-то я и не заметил шапку то-проглядел
                        0
                        Присоединяюсь к комментарию выше, допилите конвертацию для браузера и выложите, очень интересный анализ.

                        Кстати, для полного обоснования утверждения вроде «На севере москвы, судя по плану, происходит частичное дублирование Серой и салатовой ветками — они находятся рядом в пространстве времен путешествий» в схему все же надо вводить еще одну точку — многоэтажку, где живет пользователь, тогда все встает на свои места.
                          0
                          добавил ссылку на схему метро на js Добавить js скрипт непосредственно в html поста не получилось — похоже на хабре это запрещено из соображений безопасности.
                          0
                          Интересное исследование! Думаю, что метро не помешали хорды в некоторых местах, а не еще одно кольцо.
                            0
                            Нельзя планировать без учёта пригородных электричек и наземного транспорта, метро строилось очень интересно и поначалу дублировало автобусные линии. Да, пройти ногами от «Библиотеки Ленина» до «Третьяковской» быстрее, что подтверждается и этой публикацией, но вот на Юге Москвы от красной до рыжей веток очень удобно добираться наземкой, «парковщиков», отъедающих по две полосы, куда-нибудь деть, и никакая хорда не понадобится. А с фиолетовой-восточной никуда по земле толком не уедешь, зато там есть автовокзал, в итоге по утрам она вмёртвую стопорится.
                            0
                            Любопытно было бы взглянуть и сравнить варианты с МЦК и без МЦК. По идее ветки должны были с вводом МЦК как-то стянуться.
                              0

                              Расстояние между точками — время поездки именно на метро, без другого транспорта?
                              Тогда две близкие на земле линии будут настолько удалены на схеме, как далеко пересадка между ними.

                                +1

                                Круто, спасибо за вашу работу. Впечатляет длина чёрных линий. Я предполагал, что переход занимает много времени, но чтобы настолько...

                                  0
                                  Занятно если есть такие маршруты, где быстрее проехать больше станций, чем идти по переходу.
                                    0
                                    Всегда пользуюсь эмпирическим правилом: время в пути равно (число перегонов + 2 x число пересадок) x 3 минуты. Понятно, что между разными станциями расстояния существенно разные, но на практике всё хорошо усредняется, и при поездках через пол-города формула даёт точность не хуже пяти минут.
                                      0
                                      На практике, в той части города, где есть выбор пересадок, различия перегонов пренебрежимо малы.
                                      Спасибо за формулу.
                                        +1
                                        Перегон в московском метро 1,5-4 минуты, чаще всего 3. А пересадку при условии отсутствия толп и очередей достаточно точно можно закладывать в 5 минут.
                                        ЗЫ извините за занудство, просто когда-то развлекался гонками на метро.
                                          0

                                          Странно, откуда у вас получился такой разброс? По моим измерениям, которые я проводил в течение 10 лет, стандартное расстояние между 2 станциями составляет 2 мин 30 сек, включая простой поезда на самой станции. Т. е. последний перегон может быть чуть короче, за счет того, что выходишь из поезда, и время его остановки уже не нужно учитывать.

                                            0
                                            Вот схема от 2006го с указанием времени на перегонах. С момента «двери закрылись» до «двери открылись» действительно может пройти 4 минуты, например, на Юге зелёной ветки.
                                              0
                                              А может и поболее. На западе Арбатско-Покровской.
                                                0

                                                На западе голубой ветки не наблюдаю никаких аномалий. Разве что среднее время перегона чуть меньше моей оценки в 2,5 минуты.

                                                  0
                                                  Арбатско-Покровская — это синяя, а не голубая. Посмотрите между Крылатским и Строгино.
                                                    0

                                                    Я потому так и написал, потому что арбатско-покровскую линию перекроили, и на карте 2006-года, которую мы в этой ветке обсуждаем Строгино вообще нет.


                                                    Яндекс.метро показывает 7 мин. Вполне возможно. Там река, поэтому перегон длиннее других.

                                                0

                                                Точность этой схемы слишком низкая. На ней шкала измерений 1 минута. Если верить этой же схеме, то для перегона Чистые пруды — Лубянка относительная погрешность составляет 100%.


                                                Впрочем, на больших расстояниях эта схема подтверждает мои данные.


                                                Серпуховская — Бульвар Дмитрия Донского: средняя длина перегона 2 мин 27 сек
                                                Октябрьская — Битцевский парк: 2 мин 33 сек
                                                Парк Культуры — Юго-Западная: ровно 2 мин 30 сек


                                                Как я уже написал, в 2,5 минуты на перегон входит также пребывание поезда на станции. Если перегон занимает 2 минуты, то поезд будет стоять на станциях 30 секунд. Причем этот интервал может быть заполнен ожиданием с разных концов перегона и может зависеть от направления движения. Скажем, при движении от Лубянки к Чистым прудам, поезд задержится на Чистых прудах, а в обратную сторону — на Лубянке.


                                                На юге зеленой ветки это правило, очевидно, не соблюдается. Подозреваю, что есть некий фиксированный интервал, который используют для составления расписаний, и время в пути вместе с временем остановки кратно этому интервалу. Например, перегон Спортивная-Университет всегда был точно равен двум стандартным перегонам. Когда между ними появилась станция Воробьевы горы, общее время в пути на красной линии не изменилось. Думаю, на зеленой ветке из-за промзоны и Москва-реки перегоны сделаны с несколькими пропусками станций, но с тем же шагом.

                                                  0
                                                  Вот что пишет метроэльф на эту тему: на рыжей ветке интервал 1,40, на посадку-высадку пассажиров 15-25 сек (в идеале 20, но всегда найдётся баран, придерживающий двери и срывающий график).
                                                    0

                                                    Интервал 1,40 (100 сек, видимо), это, скорее всего, между поездами. Он должен еще в течение суток изменяться.


                                                    Если "баран" задержал отправление, то поезд будет ехать чуть быстрее и тормозить чуть резче. Я же наблюдал неоднократно другую картину, как раз на центральных станциях, где перегоны очень короткие. Никто двери не держит, а поезд стоит те самые 25 секунд, или подъезжает к станции медленно как улитка, или просто в тоннеле стоит. И в итоге всегда среднее время в пути составляло 2,5 мин на перегон везде, где я ездил.

                                                      0
                                                      Хорошо, как будет время, я покатаюсь с секундомером мимо Автозаводской :) А интервал между поездами, да. Поезд не всегда может ехать быстрее/тормозить резче, там свои правила движения, если задержка на станции превышает заложенный запас, то интервал растёт.
                                                        0

                                                        Хорошо бы взглянуть на расписание, а еще лучше на методику его составления.

                                                          0
                                                          Вот чего у меня нет, того и нет. Всё-таки метро интересовался, но там не работал.
                                        +3

                                        А я то было подумал, что тут будет схема, как линии метро в пространстве под землёй расположены.

                                          0
                                          На такую выше в комментах ссылку давали.
                                          +5
                                          Добавление третьего измерения к имеющейся схеме, ассоциируется с нырянием высот станций по вертикали, но никак ни с временнЫм исчислением времени в пути. ИМХО, вышел крайне неудачный концепт отображения. Неспроста же нигде в мире не приняты индикации подобных схем, применимо конкретно к станциям метрополитена.
                                            0

                                            Этот граф очень удачный для своей цели — показать расстояние в часах между двумя любыми разными точками. Он никак не связан с географическим графом расположения станций, он совсем для другого.

                                              0
                                              Да это понятно, что для времени. Да, я статью читал. Но тем не менее, график не ассоциируется со временем, так как построен по ранее уже занятому принципу отображения по оси Z, именно высоты, в качестве третьей координаты. Ну ни разу не воспринимается график как повременный, потому что очень похож именно как на высотный. Было бы оптимальнее выбрать какой-нить иной способ отображения, что не подвергаться ассоциативной путанице с высотами.
                                            0

                                            Интересно было бы узнать, насколько в среднем мцк ускоряет время поездки. А то езжу по всей Москве, а как маршрут строю — все время яндекс.метро предлагает через центр ехать, а не по мцк

                                              0
                                              Насколько знаю, я.метро не любит МЦК за 9тиминутные интервалы между поездами, и скорее всего закладывает максимальное ожидание в маршрут. МЦК очень удобно на маршрутах область-центр и область-центр-область: можно не доезжать до конечных станций.
                                                +3
                                                Чисто по геометрическим соображениям: МЦК может быть выгодно при движении по нему не более чем на треть окружности, а может быть — не более, чем на четверть.
                                                  0

                                                  МЦК — имеет свою специфику. В отличие от обычного метро, там можно возить велосипеды, не разбирая. Некоторые станции находятся там, где вообще никакого транспорта больше нет, скажем, какая-нибудь Белокаменная или Зорге. Поэтому оно не просто выгодно, но и иногда просто незаменимо.

                                                    0
                                                    Белокаменная — это станция Яуза Ярославского направления, а ещё там от остановок автобусов идти 10 минут, 3 номера ходят. Зорге тоже не в чистом поле стоит :)
                                                      0

                                                      Конечно-конечно. Всего 2,5 километра пешком по автодороге до станции Яуза. И всего 700 метров до остановки автобуса, который аж 3 раза в час иногда появляется. И доехать на этом автобусе можно только до другой станции МЦК Бульвар Рокоссовского. Да и Яуза не станция, а платформа, где далеко не все электрички останавливаются, и до кассы через мост идти надо, а потом назад. Если рассматривать всерьез пересадку с Белокаменной, то нужно закладывать минимум час. Лучше до Ростокино доехать и там на нормальную станцию Северянин перейти.


                                                      Станция Белокаменная находится в центре лесного массива, в стороне даже от тропинок, где гуляют отдыхающие. Один из выходов расположен просто в лесу между заброшенными жд-колеями, другой — в тупике яузской аллеи, куда автобусы не заходят, потому что там нет места для разворота. И вот для того чтобы в эту глушь забраться, эта станция очень даже подойдет.


                                                      А так-то да, в Москве в любой точке в радиусе 3 км можно найти что угодно.

                                                        0
                                                        Моё понимание «недалеко» — примерно 1,5км, 20 минут пешком. С этой точки зрения с Белокаменной не всё так плохо, я через неё иногда на работу езжу, когда в электричках перерыв. До платформы 2.1 км. У автобусов интервал 15-20 минут, полкило до остановки, но на одном из маршрутов можно доехать до м.Сокольники, а на другом до Рокоссовского Сокольнической ветки. Вот другой выход, вглубь Лосиного острова да, вилы, оттуда никак иначе не уедешь.
                                                        Но всё равно воспринималось издевательством, когда в электричке объявляли «Платформа Яуза, пересадка на станцию МЦК Ростокино», до которой 1.9 км дворами. Сейчас, к счастью, перестали.
                                                          0

                                                          Ну тогда вы согласитесь, что эти 1.5-2 км не приспособлены для пешеходов. Это автодорога без тротуара и без нормальной обочины. Если вам нужно метро, тогда лучше выйти на Рокоссовского, если электричка, то в Ростокино. Вы, наверное, на велосипеде там катаетесь, как и я. Для велосипедистов Белокаменная очень хорошо подходит.

                                                            0
                                                            Соглашусь, спасает только то, что дорога не разбитая и машин почти нет. Я там пешком хожу, правда, обычно от Яузы — в НИИ Туберкулёза сейчас работаю.
                                                  0

                                                  С учётом очень "удобных" пересадок с него на половину линий метро, им целесообразно пользоваться если:


                                                  1. Начало или конец маршрута находится вблизи станции мцк
                                                  2. Начало и конец маршрута находятся вблизи северных концов линий метро. Но при этом не соседних. Например: Речной Вокзал — Медведково — есть смысл. Алтуфьево — Медведково — быстрее будет на автобусе.
                                                    На юге выгоды не будет.
                                                  3. Если хочется ехать в чуть меньшей давке, чем под землёй, даже с учётом небольшой потери времени.
                                                  4. Для жителей области: если на вашем направлении жд уже построили удобную пересадку и ехать надо на другой конец города, но не строго противоположный. Например, с Рижского направления на Юго-Западную или с Савёловского в Измайлово. И то, во многих случаях тут больше работает п.3
                                                    0
                                                    вы упустили мой сценарий: автобус-МЦК-автобус
                                                  –2

                                                  Автор красавчик! Классная визуализация!

                                                    0

                                                    Лет 20 назад была бесплатная программа под винду (кажется, называлась pMetro). Там была очень крутая 3д схема метро, и всё можно было вращать и масштабировать. Но главная фишка — это то, что все станции были тоже 3д, со всеми эскалаторами, переходами и выходами с обозначением улиц.

                                                      0
                                                      кажется, нечто очень похожее есть в Гугл.Плее под названием aMetro
                                                      +1
                                                      А было бы классно сделать реальную схему метро в 3D. Глубины заложения станций известны. Расстояния между ними — тоже. И координаты есть.
                                                        +1
                                                        И ссылка в комментариях на неё есть.
                                                          0
                                                          там глубины не верно отображаются. было бы клево увидеть самую глубокую станцию прям на картинке
                                                            0
                                                            О, точно! )
                                                          +5
                                                          В нашем благословенном двумерном мире, заголовок «Как выглядело бы Московское метро в трехмерном мире» лишён всякого смысла!

                                                          Хотя некоторые утверждают что оно выглядело бы примерно так:
                                                          image
                                                            0
                                                            да, разница между трехмерным миром математики и фотографии сразу бросается в глаза!
                                                            0
                                                            забавна разница в подходах к поиску информации ))
                                                            вы дергали инфу из приложения, хотя все те же данные есть на офиц. сайте в одном из файлов: mosmetro.ru bitrix/templates/sh1/app.js
                                                              0
                                                              Было бы занятно найти данные о времени поездки в зависимости от времени суток и анимировать граф по этому параметру )
                                                                0
                                                                Я.Метро.Пробки?
                                                                  0
                                                                  Я.Граф.Метро

                                                                  (По идее, можно, наверно, опрашивать Яндекс.Карты на эту тему)

                                                                  Как уж тут не вспомнить «Лист Мёбиуса»
                                                                0
                                                                По какой причине нельзя сделать расстояние между станциями равным времени в пути в 2D виде? Расстояние вектор определённой длинны, в чём проблема перенести эту длину в виде увеличения/уменьшения расстояния между станциями?
                                                                  0
                                                                  Это сделать можно, и скорее всего сработало бы, если учитывались бы времена только между соседними станциями; Время тогда можно было бы считать просто как сумму длин ребер графа пути от одной станции к другой. В двумерном пространстве даже такая задача не всегда решается. Пример — 4 станции, каждая связана с каждой и есть 4 времени перехода. В 2д случае такая задача не решается в общем виде, в 3d она решается при некоторых ограничениях на соотношения длин (комент снизу). В случае, когда оптимизация идет по всем парам станций, нарисовать адекватный граф в 2d еще труднее, и нужно больше степеней свободы для более точного построения для точного графа. Поэтому выбрано 3d пространство. Но никто не мешает запустить алгоритм с гораздо худшими результатами на 2д схеме (результат оптимизации 2д — последняя картинка в посте)
                                                                  +3

                                                                  В случае Евклидовых расстояний высокая размерность не поможет точно вложить схему. Например, в метро всего 4 станции, одна соединена со всеми остальными, остальные друг с другом не соединены (звезда). При этом время на путешествие между центральной станцией и граничной равно 1. Тогда время пути между тремя граничными станциями равно 2 (время на пересадку пока игнорируем), и при вложении схемы в евклидово пространство они образуют треугольник со стороной 2. Никакая дополнительная размерность не поможет поставить четвёртую станцию так, что расстояние между ней и остальными будет равно 1.


                                                                  Пространства, в которые можно вложить любое конечное пространство существуют, например, https://en.m.wikipedia.org/wiki/L-infinity, и там ограничение на размерность совпадает с вашей интуицией

                                                                    0
                                                                    Спасибо большое за ценное замечание! Действительно, для евклидовых пространств утверждение, что «для любого графа существует такое пространство, что можно таким образом расставить точки, чтобы расстояние между любыми двумя ними было равно указанным длинам ребер графа» неверно. Нужно либо вводить дополнительные ограничение, чтобы удовлетворялось неравенство треугольника для любой тройки точек либо еще какое-то или смотреть на другие пространства с другими метриками.
                                                                    +2
                                                                    Есть немного другая, но похожая визуализация — реалтаймовая карта движения поездов Токио
                                                                    nagix.github.io/mini-tokyo-3d
                                                                      0
                                                                      Очевидно, что в двумерном пространстве невозможно нарисовать такую схему, в которой расстояние между двумя станциями равнялось бы времени путешествия от одной к другой из-за сложной топологии графа метро.


                                                                      Совершенно не очевидно.
                                                                        0
                                                                        На мой взгляд градиентный спуск тут излишен, и более того, если перемудрить то он может сойтись куда-нибудь в локальный минимум. Задача (если я правильно понял) — линейная, так что если у вас уже есть матрица связности графа (квадратная), то PCA (Principal Component Analysis) решает именно то что вам надо. Находим Eigen вектора (mean-subtracted) матрицы связности, выбираем 3 вектора с максимальным Eigen значением, которые собственно и будут соответствовать искомым координатам в 3Д пространстве.

                                                                        К сожалению не могу проверить это в Питоне, но если кто захочет заимплементить — с удовольствием гляну/подскажу
                                                                          0
                                                                          Для некоторых веток, например зеленой, синей или фиолетовой МЦК (розовое кольцо) практически бесполезно из-за неудобных пересадок, что видно в удалении кольца от этих веток.


                                                                          Что бесполезно?

                                                                          Only users with full accounts can post comments. Log in, please.