Algorithm 根据成对数据确定父项、子项
我需要从一些不寻常的数据中确定父/子关系 航班号是营销创意,而且是奇数。航空公司X的航班22可能指X和Y之间的单程航班。同一航空公司的航班44实际上可能指城市对之间的多个航班。例如:Algorithm 根据成对数据确定父项、子项,algorithm,Algorithm,我需要从一些不寻常的数据中确定父/子关系 航班号是营销创意,而且是奇数。航空公司X的航班22可能指X和Y之间的单程航班。同一航空公司的航班44实际上可能指城市对之间的多个航班。例如: Flight 44: Dallas - Paris Flight 44: Dallas - Chicago Flight 44: Chicago - New York Flight 44: New York - Paris Flight 44: Chicago - Paris Flight 44: Da
Flight 44: Dallas - Paris
Flight 44: Dallas - Chicago
Flight 44: Chicago - New York
Flight 44: New York - Paris
Flight 44: Chicago - Paris
Flight 44: Dallas - New York
现实——这就是他们的工作方式。当我从“航班号和城市对大列表”中提取数据时,我得到了44航班的6种组合。我有每个乘客的数量,所以如果有10人飞往达拉斯-巴黎,我需要把这10名乘客,并添加到达尔吉,CH-NY和纽约- PAR段。p>
从所有航段的列表中,我需要算出“啊,这是一架从达拉斯到巴黎的航班”——然后当我看到乘客量时,我可以相应地增加城市到城市的实际载客量,如下所示:
- Value associated with AD -- > increment segments AB, BC, CD
- value associated with AC --> increment only segments AB, BC
- value associated with AB --> increment only segment AB
etc.
假设我得到了一张44航班的数值列表,没有顺序,如下所示:(DAL-CHI,CHI-NYC,NYC-PAR,DAL-NYC,DAL-PAR,CHI-PAR)。如何比较这6种组合中的这4个值,找出父子结构?您是否考虑过使用带有列表存储的
字典基本上是一个哈希表,您可以存储一个键(begging和end point ex,AD)和一个值(它需要经过[AB,BC,CD]的段)。好的,第二步:这是一个函数,它将接受您提供的字符串,并根据维基百科文章对其进行拓扑排序
import re
import itertools
def create_nodes(segments):
remaining_segments = re.findall(r'(\w*?)-(\w*?)[,)]', segments)
nodes = []
while len(remaining_segments) > 1:
outgoing, incoming = zip(*remaining_segments)
point = next(node for node in outgoing if node not in incoming)
nodes.append(point)
remaining_segments = [segment for segment in remaining_segments if segment[0] != point]
last_segment = remaining_segments.pop()
nodes.extend(last_segment)
return nodes
测试:
请注意,这并不是一个完美的拓扑排序函数;但是,对于多站单程旅行的特定用例,它应该是有效的。注意:这是一个常识分析,但请参见Timothy Shields solution,他将该问题确定为拓扑排序问题,因此已知计算复杂性和已知唯一性条件 我将试着从你的答案中提取问题的核心,以便正式地描述它 在上面的示例中,实际上有四个节点(城市),为了简洁起见,表示为D、p、C和NY。您有一组有序对(x,y),它们被解释为“在该航班上,节点x先于节点y”。将其写成
xFormulation
让a_i->b_i
成为44航班配对列表中的第i
项,i=1..M
让V
成为所有唯一a_i
和b_i
值的集合:
V = {a_i | i = 1..M} U {b_i | i = 1..M}
让E
成为所有对的集合(a_i,b_i)
:
然后G=(V,E)
是a,其中顶点V
是城市,有向边E
对应于列表中的条目a_i->b_i
算法
您要查找的是图G
中的一段。链接的Wikipedia页面具有此算法的伪代码
这将为您提供城市的线性排序(在您的示例中:[Dallas,Chicago,New York,Paris]
),该排序与初始列表中的所有排序约束一致。如果您的初始列表包含少于|V |选择2个对(这意味着没有完整的约束集),那么您的集合中可能存在多个城市的一致拓扑顺序V
构建一个从航班列表出发或目的地的所有城市的列表。这是四个
城市:
再次迭代航班列表并计算每个目的地城市的发生次数:
0 Dallas
3 Paris
1 Chicago
2 New York
按目的地计数对列表进行排序,即可获得路线:
Dallas -> Chicago -> New York -> Paris
注:如果目的地计数从零开始不连续(如0、1、2、3…),则表明该航班的出发/目的地列表不一致或不完整。我不理解什么是“聚合”,因此我不明白为什么与AD-->增量段AB、BC相关的-值,CD
等。这是因为有一条从a到D的路径由这些段组成吗?是否保证这是唯一的途径?还有,什么是孩子,什么是家长。很公平,ondav——上面还有更多内容要补充,谢谢。@ToddCurry一定要看看我的答案——这是现有算法中的一个常见问题,您可以使用。你不需要在这里发明任何新的东西。llb,谢谢你的提交,我表示歉意,但是A,B,C,D的确切顺序是未知的。从字母组合列表中,我想计算出实际的a、B、C、d顺序。请看看我上面的编辑,也许你会看到一个解决方案,我很抱歉我不能。最好的办法是,你可以随时提出修改标签的建议(顺便说一句,我刚做了)。@PhilipKendall谢谢,我从答案中删除了这个建议。如果提供的列表是:(1)达拉斯->芝加哥(2)芝加哥->纽约(3)纽约->巴黎,这将不起作用——这似乎是一个可以合理预期作为输入的案例。有关更稳定的解决方案,请参阅我的答案。@TimothyShields缺少链接是任何算法的问题。假设芝加哥->纽约链接丢失。可以确定起点/终点,但不能确定到达目的地的路线。达拉斯->纽约,然后纽约->芝加哥或达拉斯->芝加哥,然后芝加哥->纽约都可以选择。是的,但拓扑排序总是一致的。如果最终目标是列出与某个航班号相关的城市,那么一致的排序就是目标(即使有多个一致的排序)。因此,NealB,这是我开始尝试的一种方法,有点不同。我需要一些时间来欣赏蒂莫西的精彩记录,这是一个单独的评论。我创建了8个列表:从A、B、C、D开始的航班和在A、B、C、D结束的航班。然后,当我遇到每个seg时,不管顺序如何,我都会填充每个列表。最终目的地始终是零项开始的航班列表;最终始发地始终是以t结尾的航班列表
V = {a_i | i = 1..M} U {b_i | i = 1..M}
E = {(a_i, b_i) | i = 1..M}
Dallas
Paris
Chicago
New York
0 Dallas
3 Paris
1 Chicago
2 New York
Dallas -> Chicago -> New York -> Paris