繁体   English   中英

用于区分具有相同名称的节点的正确图形数据结构是什么?

[英]What is the correct graph data structure to differentiate between nodes with the same name?

我正在学习图形(它们看起来非常有用),并且想知道我是否可以就构建图形的可能方法获得一些建议。

简单来说,让我们说我每天都会得到采购订单数据,有些日子与前一天相同,而其他日子则不同。 例如,昨天我订购了铅笔和橡皮擦,我创建了两个节点来代表它们,然后今天我收到了橡皮擦和标记的订单,依此类推。 在每一天之后,我的程序还会看到谁订购了什么,如果Bob昨天订购了一支铅笔,然后今天订购了一支橡皮,它就会产生一个有针对性的优势。 我的逻辑是,我可以看到谁在每天购买了什么,我可以跟踪Bob的购买行为(也许可以用它来推断自己或其他用户的模式)。

我的问题是,我正在使用networkx(python)并为昨天创建节点'pencil',然后为day2创建另一个节点'pencil',我无法区分它们。

我想(并且已经)将它命名为day2-pencil,然后扫描整个图形并剥离'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'}}

它明显覆盖了1/1/12的铅笔与1/2/12一支,不知道我是否可以制造一个。

这主要取决于你的目标。 您想要分析的是图表设计中的决定性因素。 但是,看一下你的结构,一般结构就是CustomersProducts节点,它们是按Days连接的(我不知道这对你有什么帮助,但实际上这是一个二分图 )。

所以你的结构将是这样的:

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

比方说,鲍勃在2012年1月1日买了一支铅笔:

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

好的,现在Bob在1/2/12买了另一支铅笔:

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

等......

这实际上可以通过networkx 由于节点之间有多条边,因此您必须在MultiGraph Mor MultiDiGraph之间进行选择,具体取决于边缘的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')]

到目前为止,还不错。 你实际上可以查询“爱丽丝是否在1/1/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有更好的方法。

尝试这个:

为每个节点提供唯一的整数ID。 然后,创建一个字典,节点,这样:

nodes ['pencil'] = [1,4,...] < - 其中所有这些都对应于具有铅笔属性的节点。 将'铅笔'替换为您感兴趣的其他任何属性。

只需确保当您使用'pencil'添加节点时,您将更新字典:

节点[ '铅笔']。追加(new_node_id)。 同样节点删除。

图表不是最佳方法。 像MySQL这样的关系数据库是存储这些数据并执行诸如何时购买的数据的正确工具。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM