【问题标题】:How to plan the most efficient route for patio lights Part 2如何规划庭院灯最有效的路线第 2 部分
【发布时间】:2018-01-25 09:44:30
【问题描述】:

这是我之前提出的一些问题的延续,How to plan the most efficient route for patio lightsChristmas Light Route Efficiency (CS),关于我试图尽可能有效地用庭院灯覆盖屏蔽结构。

规则如下:

  • 尽量减少光线重叠
  • 每个灯串长 234 英寸(这很重要,因为除非它位于另一个分支的末端,否则我无法启动新的灯分支)。
  • 把这些想象成圣诞灯,你有男性和女性的一面:

    start (male) end (female) =[}~~~o~~~o~~~o~~~o~~~o~~~o~~~o~~~{=] <- to outlet to other lights ->

    因此,只要有一个雌性供雄性插入,多股就可以菊花链,如下所示:

  • 一个母插头必须通过一个公插头为下一个灯串供电,一个公插头不能给另一个公插头供电。

  • 这是我的结构图:

  • 粉红色圆圈 = 挂灯的地方(不,在 10、11 和 12 的交叉点没有挂灯的地方 - 这不是错误)。 p>

  • “开始” = 唯一可用的电源插座。
  • 黄点 = 我想要让灯光沿着结构运行的部分。

根据我之前的问题,我开始研究“路由效率问题”算法。我使用这篇文章 Solving Chinese Postman algorithm with eulerization 开始使用,它引导我找到这段代码(感谢 @DamianoFantini 在我之前的文章中帮助我正确设置图表):

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)

# SOURCE: https://stackoverflow.com/q/40576910/1152809
make.eulerian <- function(graph){
  # Carl Hierholzer (1873) had explained how eulirian cycles exist for graphs that are
  # 1) connected, and 2) contain only vertecies with even degrees. Based on this proof
  # the posibility of an eulerian cycle existing in a graph can be tested by testing
  # on these two conditions.
  #
  # This function assumes a connected graph.
  # It adds edges to a graph to ensure that all nodes eventuall has an even numbered. It
  # tries to maintain the structure of the graph by primarily adding duplicates of already
  # existing edges, but can also add "structurally new" edges if the structure of the
  # graph does not allow.

  # save output
  info <- c("broken" = FALSE, "Added" = 0, "Successfull" = TRUE)

  # Is a number even
  is.even <- function(x){ x %% 2 == 0 }

  # Graphs with an even number of verticies with uneven degree will more easily converge
  # as eulerian.
  # Should we even out the number of unevenly degreed verticies?
  search.for.even.neighbor <- !is.even(sum(!is.even(degree(graph))))

  # Loop to add edges but never to change nodes that have been set to have even degree
  for(i in V(graph)){
    set.j <- NULL

    #neighbors of i with uneven number of edges are good candidates for new edges
    uneven.neighbors <- !is.even(degree(graph, neighbors(graph,i)))

    if(!is.even(degree(graph,i))){
      # This node needs a new connection. That edge e(i,j) needs an appropriate j:

      if(sum(uneven.neighbors) == 0){
        # There is no neighbor of i that has uneven degree. We will
        # have to break the graph structure and connect nodes that
        # were not connected before:

        if(sum(!is.even(degree(graph))) > 0){
          # Only break the structure if it's absolutely nessecary
          # to force the graph into a structure where an euclidian
          # cycle exists:
          info["Broken"] <- TRUE

          # Find candidates for j amongst any unevenly degreed nodes
          uneven.candidates <- !is.even(degree(graph, V(graph)))

          # Sugest a new edge between i and any node with uneven degree
          if(sum(uneven.candidates) != 0){
            set.j <- V(graph)[uneven.candidates][[1]]
          }else{
            # No candidate with uneven degree exists!

            # If all edges except the last have even degrees, thith
            # function will fail to make the graph eulerian:
            info["Successfull"] <- FALSE
          }
        }

      }else{
        # A "structurally duplicated" edge may be formed between i one of
        # the nodes of uneven degree that is already connected to it.

        # Sugest a new edge between i and its first neighbor with uneven degree
        set.j <- neighbors(graph, i)[uneven.neighbors][[1]]
      }
    }else if(search.for.even.neighbor == TRUE & is.null(set.j)){
      # This only happens once (probably) in the beginning of the loop of
      # treating graphs that have an uneven number of verticies with uneven
      # degree. It creates a duplicate between a node and one of its evenly
      # degreed neighbors (if possible)
      info["Added"] <- info["Added"] + 1

      set.j <- neighbors(graph, i)[ !uneven.neighbors ][[1]]
      # Never do this again if a j is correctly set
      if(!is.null(set.j)){search.for.even.neighbor <- FALSE}
    }

    # Add that a new edge to alter degrees in the desired direction
    # OBS: as.numeric() since set.j might be NULL
    if(!is.null(set.j)){
      # i may not link to j
      if(i != set.j){
        graph <- add_edges(graph, edges=c(i, set.j))
        info["Added"] <- info["Added"] + 1
      }
    }
  }

  # return the graph
  (list("graph" = graph, "info" = info))
}

# Look at what we did
eulerian <- make.eulerian(gg)
g <- eulerian$graph

par(mfrow=c(1,2))
plot(gg)
plot(g)

这是代码的结果:

我认为可以翻译成这个(但我是一个图形/算法菜鸟,如果我错了,请纠正我):

显然,这里有一些问题:

  1. 我不知道每束灯的终点/起点应该在哪里(我认为算法也不知道)
  2. 节点 1 正在独立供电。这在现实中是行不通的。所有电源都必须来自“开始”位置。
  3. 似乎没有考虑距离和结构。

有没有办法将这些约束添加到算法中?有没有我可以使用的另一种算法使这更容易?

【问题讨论】:

    标签: r algorithm igraph chinese-postman


    【解决方案1】:

    https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm

    您可以使用不同的边缘数据来实现 Dijkstra 的算法,以获取路径的不同指标,例如光线重叠,或者例如,每个边缘处灯光的总照度。我认为您可能需要在深角落使用更高密度的光...

    因此,目标可以是最广泛的弱光区域,也可以是感知到的障碍物可见度,或者是产生均匀环境光的路径。不管它是如何调整的,尽管我相信 Dijkstra 的算法是找到这些东西的一个非常标准的 goto。

    更新: 在创建最广泛覆盖的光区域的情况下,您需要生成树而不是最佳路径算法。这可能更符合您的想法:

    https://en.wikipedia.org/wiki/Prim%27s_algorithm

    【讨论】:

    • 谢谢,感谢您的帮助。光密度与其说是最小重叠更重要,不如说是考虑到每条线的长度(它开始/结束的地方,以便它可以向其他线发送能量)。我检查了 Prim 的算法,这似乎涉及权重 - 我认为这不是我需要的,因为只需要覆盖所有边缘。
    • 权重是成本的抽象一般概念。权重可以代表许多指标,例如电线长度,或为光路供电的成本,或以牛顿为单位的支撑件的应变。这个想法是,您必须使用要跨越的单位的权重来创建地图。
    猜你喜欢
    • 2018-01-25
    • 2015-03-13
    • 2019-02-16
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多