我想在python中构建一个算法,在线串集合中翻转线串(坐标数组),表示沿着道路的段,这样我就可以将所有坐标合并到一个坐标上升单调的数组中。
所以我的Segmentcollection看起来像这样:
segmentCollection = [['1,1', '1,3', '2,3'],
['4,3', '2,3'],
['4,3', '7,10', '5,5']]
编辑:结构是2D笛卡尔坐标元组列表的列表(例如,'1,1'是x = 1且y = 1的点,'7,10'是x = 7处的点和y = 10,依此类推)。整个问题是将所有这些列表合并到一个坐标元组列表中,这些坐标元组是在一个方向上跟随道路的意义上排序的...实际上这些是我从道路网络路由服务获得的段,但我只得到段,每个段指向它在数据库中数字化的方式,而不是指向您必须驱动的方向。我想从导航路线中获得一条折线。
所以: - 我可以假设,所有细分都是正确的顺序 - 我不能假设每个细分的坐标顺序正确 - 因此我也不能假设第一段的第一个坐标是开头 - 而且我也不能假设最后一段的最后一个坐标是结束 - (编辑)即使我知道,我的导航请求的起点和终点位于哪里,这些也不必与这些列表中的一个坐标元组相同,因为它们只需要在路由图附近的某处元件。
算法应迭代每个段,必要时将其翻转,然后将其附加到生成的数组中。对于第一个分段,挑战是找到起点(未连接到下一个分段的点)。然后,所有其他段与一个点连接到订单中的最后一个段(有向图)。
我想知道是否没有某种排序数据结构(排序树或任何东西)就是这样。你能提出一些想法吗?在用循环和数组比较搞乱一段时间之后,我的大脑被淘汰了,我只需要在正确的意义上向正确的方向踢一脚。
答案 0 :(得分:1)
如果我理解正确,你甚至不需要对事情进行排序。我刚把你的英文文本翻译成Python:
def joinSegments( s ):
if s[0][0] == s[1][0] or s[0][0] == s[1][-1]:
s[0].reverse()
c = s[0][:]
for x in s[1:]:
if x[-1] == c[-1]:
x.reverse()
c += x
return c
它仍然包含重复点,但删除它们应该很简单。
答案 1 :(得分:1)
def merge_seg(s):
index_i = 0
while index_i+1<len(s):
index_j=index_i+1
while index_j<len(s):
if c[index_i][-1] == c[index_j][0]:
c[index_i].extend(c[index_j][1:])
del c[index_j]
elif c[index_i][-1] == c[index_j][-1]:
c[index_i].extend(c[index_j].reverse()[1:])
del c[index_j]
else:
index_j+=1
index_i+=1
result = []
s.reverse()
for seg_index in range(len(s)-1):
result+=s[seg_index][:-1]#use [:-1] to delete the duplicate items
result+=s[-1]
return result
在内部while循环中,s [index_i]的每个连续段都附加到s [index_i] 然后index_i ++直到处理完每个段。 因此很容易证明在这些while循环之后,s [0] [0] == s [1] [ - 1],s [1] [0] == s [2] [ - 1]等。所以只需将列表反转并将它们组合在一起,最后您将得到结果。
注意:这是简单和直接方式,但不是最节省时间。
答案 2 :(得分:0)
你说你可以假设所有段都是正确的顺序,这意味着独立于坐标顺序,你的问题基本上是合并排序的数组。
如果没有按照正确的顺序定义片段,则必须翻转片段,但这不会对主算法产生单一影响。
简单地定义此重新排序功能:
def reorder(seg):
s1 = min(seg)
e1 = max(seg)
return (s1, e1)
和这个比较功能
def cmp(seg1, seg2):
return cmp(reorder(seg1), reorder(seg2))
你已经完成了设置,只需运行一个典型的合并算法:
http://en.wikipedia.org/wiki/Merge_algorithm
如果我不明白你的问题陈述,这是另一个想法:
使用segment tree,这是一个完全用于存储片段的结构:)