Python: как создать безмасштабную сеть с предопределенными позициями узлов?

Я хочу создать безмасштабную сеть по алгоритму Барабаси-Альберта, включающему рост и предпочтительное присоединение.

Я использую следующий скрипт для создания сети:

import networkx as nx
import matplotlib.pyplot as plt

n=100 #Number of nodes
m=4 #Number of initial links
seed=100
G=nx.barabasi_albert_graph(n, m, seed)
nx.draw(G)
plt.show()

Это дает следующий результат: введите здесь описание изображения

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

введите здесь описание изображения

Я могу создать словарь позиций, который отражает мою сетку:

pos = dict( (n, n) for n in G.nodes() )
labels = dict( ((i, j), i + (n-1-j) * n ) for i, j in G.nodes() )
inds=labels.keys()
vals=labels.values()
inds.sort()
vals.sort()
pos2=dict(zip(vals,inds))

Мой вопрос: как изменить скрипт, чтобы получить график Барабаси-Альберта с позициями узлов, указанными в pos2, то есть в соответствии с моей сеткой?


person FaCoffee    schedule 18.02.2016    source источник


Ответы (2)


import networkx as nx
import matplotlib.pyplot as plt

n = 100  # Number of nodes
m = 4  # Number of initial links
seed = 100
G = nx.barabasi_albert_graph(n, m, seed)

ncols = 10
pos = {i : (i % ncols, (n-i-1) // ncols) for i in G.nodes()}
nx.draw(G, pos, with_labels=True)    
plt.show()

введите здесь описание изображения


Транспонирование модулей и операторов целочисленного деления транспонирует строки и столбцы:

pos = {i : (i // ncols, (n-i-1) % ncols) for i in G.nodes()}

урожаи

введите здесь описание изображения


Изменение значения y с (n-i-1) % ncols на ncols - (n-i-1) % ncols переворачивает изображение относительно горизонтальной оси:

pos = {i : (i // ncols, ncols - (n-i-1) % ncols) for i in G.nodes()}
person unutbu    schedule 18.02.2016
comment
Прекрасный макет — добавьте больше «нет» и посмотрите, почему ориентированный граф становится необходимостью, а не роскошью. - person Tim Seed; 18.02.2016
comment
Как изменить положение узлов, чтобы первая строка стала первым столбцом? например, имея узлы, помеченные по строкам, а не по столбцам. - person FaCoffee; 23.06.2016
comment
@CF84: поменяйте местами операторы % и //. Я добавил код выше, чтобы показать, что я имею в виду. - person unutbu; 23.06.2016
comment
Извините за повторный вопрос, но для меня это сложно, так как не совсем понятно, какой итератор для строки, а какой для столбца. Что, если я хочу, чтобы узлы 9, 19, 29, ..., 99 отображались в верхней строке, а не в нижней? Это означает отражение позиций узлов относительно горизонтальной линии, пересекающей сеть прямо между строками, начинающимися с узла 4, и строкой, начинающейся с узла 5. Спасибо. - person FaCoffee; 08.07.2016
comment
Если вы рисуете точки (x, y), где y идет от 0 до N. Затем, чтобы перевернуть график по горизонтали, чтобы точка с y-value 0 теперь находилась в N, а точка с y-value N теперь в 0, вы бы построили (x, N-y). Точно так же, если вы измените (n-i-1) % ncols на ncols - (n-i-1) % ncols, изображение будет перевернуто относительно горизонтальной оси. - person unutbu; 08.07.2016

Сколько узлов вы планируете разместить на графике? Как только вы начинаете получать более 100 — если у вас нет удивительного количества визуальной недвижимости, часто становится совершенно бессмысленным добавление дополнительных узлов.

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

* pygraph
* A Microsoft Graphing engine
* GraphDb - lots of query node power there
* IBM Products - for spacial visualisation

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

Однако интересно посмотреть, как у вас дела...

person Tim Seed    schedule 18.02.2016
comment
Я планирую добавить 20000 узлов, но визуализация меня не волнует. Итак, вы предлагаете отказаться от networkx? - person FaCoffee; 18.02.2016
comment
20к узлов!!! Эээ, я начал на днях с 80K.... отфильтровал и набросил это на визуальный график с 800 парами ключей.... это был буквально ЧЕРНЫЙ УЖАСНЫЙ БЕСПОРЯДОК!!! Когда я затем применил некоторую фильтрацию к 800 парам ключей (и сократил примерно до 250 элементов), вы могли бы различить некоторую информацию о сетевой диаграмме. Если вас не волнует визуализация, то зачем беспокоиться о том, где на графике располагаются узлы? - person Tim Seed; 18.02.2016
comment
Потому что этот скрипт работает в паре с другим скриптом, в котором выполняются вычисления, и они основаны на позициях узлов. - person FaCoffee; 18.02.2016
comment
Хорошо - это имеет смысл. Итак (при условии, что я это понял) - вы заполняете свою модель Барабаси-Альберта - и самые популярные узлы, как правило, получают больше ссылок (хорошо) ... до тех пор, пока вы можете запросить граф, чтобы узнать ребра узла I не будет беспокоиться о размещении (если узел не имеет отношения GEO). Ваш код Python для размещения узлов выглядит нормально ... Он автоматически балансирует сеть и переупорядочивает себя на узлах 20K, что будет ОЧЕНЬ интенсивно использовать ЦП. Я забыл также упомянуть graphX ​​— это тоже стоит посмотреть — Apache, Spark, bigdata и т. д. - person Tim Seed; 18.02.2016
comment
Узлы имеют отношения GEO. Но что, если я сгенерирую одну единственную безмасштабную сеть и запишу в CSV-файл ее G.edges()? Именно этот объект обладает типичными для данной сети степенными свойствами. Затем я мог бы добавить 20000 узлов на основе своих позиций, а затем добавить ребра с помощью G.add_edge() из файла csv. Может ли это быть разумным обходным путем? - person FaCoffee; 18.02.2016