【问题标题】:Circular Path algorithm圆形路径算法
【发布时间】:2015-05-02 12:52:55
【问题描述】:

我一直在开发一种循环路径算法,以创建一条出点的路径。 这是我开始的数组:

(1,1)
(1,6)
(2,2)
(2,5)
(4,1)
(4,2)
(6,5)
(6,6)

这些是坐标系中的点,我想要排序,所以我只需要相邻点之间的水平线或垂直线。所以排序后的数组需要是这样的

(1,1)        (A,H)
(1,6)        (A,B)
(6,6)        (C,B)
(6,5)        (C,D)
(2,5)        (E,D)
(2,2)        (E,F)
(4,2)        (G,F)
(4,1)        (G,H)

编辑:这些点是从不同的边缘中提取的。每条边由两个点定义。没有相互重叠的边缘。

Edge: (1,1) -> (1,6)
Edge: (1,6) -> (6,6)
Edge: (6,6) -> (6,5)
Edge: (6,5) -> (2,5)
Edge: (2,5) -> (2,2)
Edge: (2,2) -> (4,2)
Edge: (4,2) -> (4,1)
Edge: (4,1) -> (1,1)

感谢您的帮助!

【问题讨论】:

  • 这不是排序,只是某种排序。如果是排序,你可以取任意 2 分来判断哪个“更大”,哪个“更小”。在这里,下一个项目的顺序取决于上一个的顺序。
  • 据我了解,这里你尝试建立一条连接 N 个点的圆形路径,每个点的边缘必须是水平或垂直的,并且每个水平边缘都必须跟随垂直,反之亦然。如果对于任何给定的 x 或 y 坐标(如您的示例)只有 0 或 2 个点,那么只有一个这样的路径(不考虑遍历方向),如果它存在,并且可以很简单地恢复。如果对于任何给定的 x 或 y 可以有任何偶数个点,问题就会变得更难。
  • 你是对的。订购是我的问题的正确定义。我可以后退一步,我确实有由两个点定义的不同边缘,我认为使用点会更容易,但我忘记了使用同一点的两个边缘的可能性
  • 边可以相交吗?
  • 是的,它们可以相交

标签: algorithm path-finding circular-dependency


【解决方案1】:

假设,边缘必须交替(每个垂直后面跟着水平,反之亦然),算法可能如下:

P = input // collection of points
EH = []   // collection of horizontal edges
EV = []   // collection of vertical edges

sort P by x, then y         // (1,1), (1,2), (1,4), (1,6), (2,2), (2,5), ...
for (i = 0; i < P.size; i += 2) 
    if P[i].x != P[i+1].x return   // no solution
    EH.add(new edge(P[i], P[i+1]))

sort P by y, then x         // (1,1), (4,1), (2,2), (4,2), ...
for (i = 0; i < P.size; i += 2)
    if P[i].y != P[i+1].y return   // no solution
    EV.add(new edge(P[i], P[i+1]))

// After this, every point belongs to 1 horizontal egde and 1 vertical
// If exists closed path which traverses all points without overlapping, 
// such path is formed by these edges

S = []          // path
S.add(EH[0])
cp = EH[0].p2   // closing point 
p =  EH[0].p1   // current ending point
find edge e in EV where e.p1 = p or e.p2 = p
if e not found return empty path      // no solution
S.add(e)   
if p = e.p1
    p = e.p2
else
    p = e.p1
while (p != cp) {
    find edge e in EH where e.p1 = p or e.p2 = p
    if not found return empty path    // no solution
    S.add(e)
    if p = e.p1           
       p = e.p2
    else
       p = e.p1
    find edge e in EV where e.p1 = p or e.p2 = p
    if not found return empty path    // no solution
    S.add(e)
    if p = e.p1 
       p = e.p2
    else
       p = e.p1
}
return S 

为了简化边搜索,提到的集合 EVEH 可以使用哈希映射(点、点)实现,其中对于每个实际边 e(p1, p2) 应放置两个条目:p1-&gt;p2p2-&gt;p1 .每个点都属于 1 个水平和 1 个垂直边缘,因此条目不会被覆盖。因此可以简化算法的第二部分:

while (p != cp) {
    get from EH point pp by key p
    if not found return empty path    
    S.add(new edge(p, pp))
    p = pp
    get from EV point pp by key p
    if not found return empty path    
    S.add(new edge(p, pp))
    p = pp
}

【讨论】:

  • 非常感谢!我会实施并测试它并回复您!
  • @PNGamingPower 好的。现在我正试图找到打破这个算法的案例,但仍然找不到任何案例。
  • @PNGamingPower 是水平边缘和垂直边缘总是期望交替?
  • @SashaSalauyou 对于一般案例解决方案,是的,我相信是的。可能存在特定于此问题的条件,可能允许使用快捷方式。就像您的答案中的实现一样 - 这非常简洁,除了我们需要 OP 来确认假设是正确的。
  • @SashaSalauyou 非常感谢!该算法运行良好
猜你喜欢
  • 2012-05-20
  • 1970-01-01
  • 2020-09-16
  • 2017-09-12
  • 1970-01-01
  • 2017-04-07
  • 1970-01-01
  • 2012-04-27
  • 2015-04-24
相关资源
最近更新 更多