【问题标题】:How to plan the most efficient route for patio lights如何规划庭院灯最有效的路线
【发布时间】:2018-01-25 07:31:23
【问题描述】:

我正在尝试串起一些庭院灯。根据我问过的another question,我意识到我需要一种算法来解决Route Inspection Problem 以找出灯光应该采用的最有效路线,这样灯光覆盖的重复边缘就会最少。经过一番搜索,我意识到也许这样的东西是我最好的选择:Solving Chinese Postman algorithm with eulerization

但是,我在创建图表时遇到了问题。

这是它需要的样子:

  • 粉色圆圈代表结构中可以挂灯的地方
  • “开始”是唯一可用的电源插座
  • 黄点代表灯光应该覆盖的所有地方

这是参考这篇文章后我的图表的样子:Visualizing distance between nodes according to weights - with R:

如您所见,所有节点都在正确的位置,但边连接到了它们不应该连接的位置。这是我的代码:

library(igraph)
gg<-graph.ring(20)
ll=matrix(
  c( 0,0,    75.25,0,    150.5,0,    225.8125,0,    302.8125,0, 
     0,-87,                                          302.8125,-87,
     0,-173.8125,                                    302.8125,-173.8125,
     0,-260.9375,                                    302.8125,-260.9375,
     16,-384.3125,                                   302.8125,-384.3125,
     16,-435.9575,                                   302.8125,-435.9375,
     16,-525.1875, 75.25,-525.1875, 150.5,-525.1875, 225.8125,-525.1875, 302.8175,-525.1875),
  ncol=2,byrow=TRUE)
plot(gg,layout=ll)

我认为这与graph.ring 的性质有关,但我无法找出另一种方法来无误地定义图形的边长度。

【问题讨论】:

    标签: r algorithm igraph


    【解决方案1】:

    我认为您可以使用 graph_from_edgelist 来精确指定要连接的节点。指定以何种顺序连接哪些节点就足够了。顺便说一句,好问题!

      gg <- graph_from_edgelist(cbind(c(1:4, 6, 8, 10, 12, 14, 16:19, 1, 6, 8, 21, 12, 14, 5, 7, 9, 11, 13, 15), 
                                      c(2:5, 7, 9, 11, 13, 15, 17:20, 6, 8, 10, 12, 14, 16, 7, 9, 11, 13, 15, 20)))
      ll=matrix(
        c( 0,0,    75.25,0,    150.5,0,    225.8125,0,    302.8125,0, 
           0,-87,                                          302.8125,-87,
           0,-173.8125,                                    302.8125,-173.8125,
           0,-260.9375,                                    302.8125,-260.9375,
           16,-384.3125,                                   302.8125,-384.3125,
           16,-435.9575,                                   302.8125,-435.9375,
           16,-525.1875, 75.25,-525.1875, 150.5,-525.1875, 225.8125,-525.1875, 302.8175,-525.1875, 16, -260.9375),
        ncol=2,byrow=TRUE)
      plot(gg,layout=ll, edge.arrow.size = 0, vertex.size = c(rep(18, 20), 0),
           edge.color="orange")
    

    我添加了一个节点 (n 21) 以允许与您的方案类似的分支。这看起来或多或少是应该的?

    我查看了 Stack Overflow 上的上一篇文章(您建议的那个),尝试将其设为欧拉循环。实际上,自定义函数确实可以开箱即用,但您可能需要仔细检查是否可以使用生成的解决方案。也许,您可以在“eulerizing”电路之前尝试定义更好的连接设计。这就是我得到的。

    # load custom f(x) as in
    # https://stackoverflow.com/questions/40576910/solving-chinese-postman-algorithm-with-eulerization/40596816#40596816
    
    eulerian <- make.eulerian(gg)
    eulerian$info
    g <- eulerian$graph
    
    # set the layout as before to keep the circuit formatted according to your specs
    par(mfrow=c(1,2))
    plot(gg,layout=ll, edge.arrow.size = 0, vertex.size = c(rep(18, 20), 0),
         edge.color="orange", main = "Proposed")
    plot(g,layout=ll, edge.arrow.size = 0, vertex.size = c(rep(18, 20), 0),
         edge.color="orange", main = "Eulerized")
    

    【讨论】:

    • 是的,就是这样!谢谢!但是,我怎样才能把它变成一个图形对象,可以用于这个:eulerian.g1 &lt;- make.eulerian(g1)$graph,其中g1 是图形? (来自这篇关于解决邮递员问题的帖子:stackoverflow.com/a/40596816/1152809
    • 有趣,我没有意识到这一点。所以,你想让欧拉成为一个本身不是欧拉的循环。我会调查的。自定义 f(x) 在我手中无法开箱即用。但我明天早上会调查这个! :-)
    • 是的,我不确定为什么它不能开箱即用,但是如果您检查该问题:stackoverflow.com/a/40596816/1152809,则接受的答案会给出您可以使用的make.eulerian 替换。我基本上是复制/粘贴它,然后这样做:eulerian&lt;-make.eulerian(gg); g&lt;-eulerian$graph; par(mfrow=c(1,2)); plot(gg); plot(g)。但是,我不确定这是否是我需要的,因为它似乎没有考虑结构(所有边长)。
    猜你喜欢
    • 2018-01-25
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    • 2015-07-10
    • 1970-01-01
    相关资源
    最近更新 更多