Какова правильная структура данных графа, чтобы различать узлы с одинаковыми именами? - PullRequest
0 голосов
/ 12 января 2012

Я изучаю графики (они кажутся супер полезными), и мне было интересно, смогу ли я получить совет относительно возможного способа структурирования моих графиков.

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

Моя проблема в том, что я использую networkx (python) и создаю узел 'карандаша' для вчерашнего дня, а затем еще один узел 'карандаша' для дня2, и я не могу их дифференцировать.

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

По мере того, как мои тестовые данные увеличиваются, они становятся все более и более запутанными, поэтому мне интересно, какова лучшая практика? Любые сгенерированные предложения были бы хорошими (так как networkx кажется довольно полнофункциональным, поэтому у них, вероятно, есть способ сделать это).

Заранее спасибо!

Обновление: все еще не повезло, но это может быть полезно:

import networkx as nx
G=nx.Graph()
G.add_node('pencil', day='1/1/12', colour='blue')
G.add_node('eraser', day='1/1/12', colour='rubberish colour. I know thats not a real colour')
G.add_node('pencil', day='1/2/12', colour='blue')

В результате я набираю следующую команду G.node:

{'pencil': {'colour': 'blue', 'day': '1/2/12'}, 'eraser': {'colour': 'rubberish colour. I know thats not a real colour', 'day': '1/1/12'}}

Он явно переписывает карандаш с 01.01.12 на 1/2/12, не уверен, смогу ли я сделать дальний.

Ответы [ 3 ]

2 голосов
/ 12 января 2012

Это в основном зависит от вашей цели на самом деле.То, что вы хотите проанализировать, является определяющим фактором в вашем графическом дизайне.Но, глядя на вашу структуру, общая структура будет узлами для Customers и Products, которые связаны с Days (я не знаю, поможет ли это вам лучше, но на самом деле это двудольный граф ).

Итак, ваша структура будет выглядеть примерно так:

node(Person) --- edge(Day) ---> node(Product)

Скажем, Боб покупает карандаш 01.01.12:

node(Bob) --- 1/1/12 ---> node(Pencil)

Хорошо, теперь Боб идет и покупает другой карандаш 1/2/12:

          -- 1/1/12 --
         /            \
node(Bob)              > node(Pencil)
         \            /
          -- 1/2/12 --

и так далее ...

Это на самом деле возможно с networkx.Поскольку у вас есть несколько ребер между узлами, вам придется выбирать между MultiGraph Mor MultiDiGraph в зависимости от направленности ваших ребер.

In : g = networkx.MultiDiGraph()

In : g.add_node("Bob")
In : g.add_node("Alice")

In : g.add_node("Pencil")

In : g.add_edge("Bob","Pencil",key="1/1/12")
In : g.add_edge("Bob","Pencil",key="1/2/12")

In : g.add_edge("Alice","Pencil",key="1/3/12")
In : g.add_edge("Alice","Pencil",key="1/2/12")

In : g.edges(keys=True)
Out:
[('Bob', 'Pencil', '1/2/12'),
 ('Bob', 'Pencil', '1/1/12'),
 ('Alice', 'Pencil', '1/3/12'),
 ('Alice', 'Pencil', '1/2/12')]

пока неплохо.На самом деле вы можете запросить такие вещи, как «Купила ли Алиса Карандаш 01.01.12?».

In : g.has_edge("Alice","Pencil","1/1/12")
Out: False

In : g.has_edge("Alice","Pencil","1/2/12")
Out: True

Все может ухудшиться, если вы хотите, чтобы все заказы выполнялись в определенные дни.Плохо, я имею в виду не код, а вычисления.С точки зрения кода это довольно просто:

In : [(from_node, to_node) for from_node, to_node, key in g.edges(keys=True) if key=="1/2/12"]
Out: [('Bob', 'Pencil'), ('Alice', 'Pencil')]

Но это сканирует все ребра в сети и фильтрует те, которые вы хотите.Я не думаю, что у networkx есть лучший способ.

0 голосов
/ 10 апреля 2012

Попробуйте:

Дайте каждому узлу уникальный целочисленный идентификатор.Затем создайте словарь, узлы, такие, что:

узлов ['карандаш'] = [1,4, ...] <- где все они соответствуют узлу с атрибутом карандаша.Замените «карандаш» любыми другими интересующими вас атрибутами. </p>

Просто убедитесь, что при добавлении узла с «карандашом» обновляется словарь:

узел [«карандаш»] .append (new_node_id).Аналогично с удалением узла.

0 голосов
/ 14 января 2012

Графики не лучший подход для этого. Реляционная база данных, такая как MySQL, является подходящим инструментом для хранения этих данных и выполнения таких запросов, например, кто что купил и когда.

...