R中的动态编程--仓库位置之间距离的算法

问题描述 投票:1回答:1

我试图利用一篇学术论文中的算法计算rStudio中仓库位置之间的距离。该公式考虑了位置的宽度、深度和过道的侧面。当计算有多个交叉过道的最短距离时,增加了复杂性。这一切都基于这个 纸张.

这是从鸟瞰图来看的。

enter image description here

我有静态值α=48 ß=96 ϒ=108 Ω=75 S=22.

然后,我有一个数据框,其中i为键表示位置号,X表示过道号,y表示断面号,z表示侧面号,Cross Aisle是一个布尔值(0=不是交叉过道,1=是交叉过道)。下面是一个例子。

 i     X     Y     Z     Cross Aisle
 1     1     1     1     0
 2     1     2     1     0
 ....
 357   12    20    2     0     

如果仓库没有交叉过道,是一个矩形网格,那么这些就是i和j位置之间的公式。

物品在同一条过道上(xi=xj)。

 dij = |yi - yj| * ß + |zi - zj| * ϒ

如果物品在不同的过道上,有三种不同的情况:

 dij = {|xi - xj| * (2α + ϒ) + v}      if zi = zj
 dij = {(xj - xi) * (2α + ϒ) + ϒ + v}  if zi = 1, zj = 2
 dij = {(xj - xi) * (2α + ϒ) - ϒ + v}  if zi = 2, zj = 1

其中v是 "垂直 "距离(鸟瞰、上下通道)。

 v = min(ß * (2 * S - yi - yj), ß * (yi + yj)) + 2Ω

(*注:学术论文中v的公式有一个错别字。它在第一个位子上写的是2 - yi - yj,但我找到了另一个原始资料,它正确的是2 * S-yi - yj)。)

公式中的这部分并不复杂。它是一个相当简单的ifthen函数在R中计算。然而,接下来这段与横道的内容让我。

这是学术论文中的内容。

enter image description here

作者基本上是这样说的: 有两个位置 p1和p2. 有两个相邻的交叉通道,a1和a2。一个在p1之上,另一个在p1之下。另外,还发现有横道b1和b2,它们与p2相邻,并向左引导。p1和p2之间的距离如下。

 d(p1,p2) = min{d(p1,ai) + d(ai,bj) + d(bj,p2),i,j ∈ {1,2}}

我不知道如何将这个算法应用于我的数据集 并构建必要的循环和矩阵来寻找仓库位置之间的距离。我真的需要一些帮助来理解它。

以下是我的实际情况 数据集.

下面是我仓库的图片,让你了解一下布局。X "的位置是交叉通道。

enter image description here

在没有交叉通道的情况下,我能够得到一个可行的循环。

 whse.data <- read.xlsx("data set.xlsx", sheet = 1) %>%
                as.data.frame()

 ### CREATE COMBINATION OF LOCATIONS

 require(tools)
 cmbn.loc <- combinations(n = max(whse.data$i), r = 2, v = whse.data$i, 
 repeats.allowed = FALSE) %>%
            as.data.frame()

 ### CALCULATE DISTANCE BETWEEN LOCATIONS

 LocDst <- function(dc, wc, wa, tr, s, df, comb){
   # Creates a distance between various locations
   #
   # Args:
   #   dc: Depth of cell (alpha)
   #   wc: Width of cell (beta)
   #   wa: Width of aisle (y)
   #   tr: turning radius (omega)
   #    s: number of sections (S)
   #   df: Data Frame with location i, x, y, z, Cross.Aisle data
   # comb: Combination of locations to compare
   #
   # Returns: 
   #   Data frame with distances between each location combination
   #
   dist.df_total <- data.frame()

   for (n in 1:nrow(comb)){
     i  <- comb[n,1]
     j  <- comb[n,2]
     xi <- df[df$i == i,2]
     yi <- df[df$i == i,3]
     zi <- df[df$i == i,4]
     xj <- df[df$i == j,2]
     yj <- df[df$i == j,3]
     zj <- df[df$i == j,4]
     v  <- min(wc * (2 * s - yi - yj), wc * (yi + yj)) + 2 * tr


     if(xi == xj){
       dij <- abs(yi - yj) * wc + abs(zi - zj) * wa
     } else if (zi == zj){
       dij <- (abs(xi - xj) * (2 * dc + wa) + v)
     } else if (zi == 1 & zj == 2){
       dij <- ((xj - xi) * (2 * dc + wa) + wa + v)
     } else {
       dij <- ((xj - xi) * (2 * dc * wa) - wa + v)
     }

     dist.df       <- data.frame(`i` = i, `j` = j, dist = dij)
     dist.df_total <- rbind.data.frame(dist.df_total, dist.df)

   } 
   return(dist.df_total)
 }

 dist <- LocDst(48, 96, 108, 75, 18, whse.data, cmbn.loc)

我需要一个可行的for循环或者其他的东西来运行上面的算法1,谢谢。

r dynamic-programming
1个回答
0
投票

我能够得到一些工作。如果有人有更直接的方法,我洗耳恭听。也许这将是有帮助的人在那里!我不得不使用Excel来计算的位置宽度,深度和侧面的尺寸。

我不得不用Excel来计算交叉通道之间的距离。可能有一个代码,但对我来说,现在还没有增值。下面是该数据的一个样本。

 V1    V2    Dist
 7     18    672
 7     19    780
 7     33    204
 ....
 341   342   108

其中V1代表第一个位置号 V2代表所有交叉通道组合的第二个位置号。

其他的都应该在代码内计算(除了上面放的内容)。

require(dplyr)
require(openxlsx)
require(tools)

whse.data <- read.xlsx("data set.xlsx", sheet = 1) %>%
               as.data.frame()

 ### CREATE COMBINATION OF LOCATIONS
cmbn.loc <- combinations(n = max(whse.data$i), r = 2, v = whse.data$i, 
                         repeats.allowed = FALSE) %>%
            as.data.frame()

# CROSS-AISLES IN EACH SHELF
ca.shelf <- cross.aisles %>%
              group_by(Shelf) %>%
              summarise(No.Cross.Aisles = sum(Cross.Aisle)) %>%
              as.data.frame()

# DISTANCE BETWEEN CROSS AISLES
cmbn.cross.aisle <- combinations(n = nrow(cross.aisles), 
                                 r = 2, 
                                 v = cross.aisles$i, 
                                 repeats.allowed = FALSE) %>%
                      as.data.frame()

dist.cross.aisle <- read.xlsx("Combination of Cross-Aisles v3.xlsx", sheet = 1) %>%
                     as.data.frame()

# CROSS AISLE FUNCTION
CrsAisDst <- function(dc, wc, wa, tr, s, no.sh, df, comb, ca.m, d.m){
  # Creates a distance between various locations
  #
  #  Args:
  #    dc: Depth of cell (alpha)
  #    wc: Width of cell (beta)
  #    wa: Width of aisle (y)
  #    tr: turning radius (omega)
  #     s: number of sections (S)
  # no.sh: number of shelves
  #    df: Data Frame with location i, x, y, z, Cross.Aisle data
  #  comb: Combination of locations to compare
  #  ca.m: Cross-aisles matrix
  #   d.m: Distances between cross-aisles
  #
  # Returns: 
  #   Data frame with distances between each location combination
  #
  dist.df_total <- data.frame()


  for (n in 1:nrow(comb)){
    i   <- comb[n,1]
    j   <- comb[n,2]
    xi  <- df[df$i == i,2]
    yi  <- df[df$i == i,3]
    zi  <- df[df$i == i,4]
    xj  <- df[df$i == j,2]
    yj  <- df[df$i == j,3]
    zj  <- df[df$i == j,4]
    v   <- min(wc * (2 * s - yi - yj), wc * (yi + yj)) + 2 * tr


    if(xi == xj){
       min.dij <- abs(yi - yj) * wc + abs(zi - zj) * wa
     } else {
      shi <- df[df$i == i,6]
      shj <- df[df$i == j,6]

      ### CROSS-AISLES
      ca.i <- #ca.m[ca.m$Shelf == shi,1]
        data.frame(`i` = ca.m[ca.m$Shelf == shi,1])
      ca.j <- #ca.m[ca.m$Shelf == shj,1]
        data.frame(`j` = ca.m[ca.m$Shelf == shj,1])

      ## JOIN DISTANCES
      dist.df_total.i <- data.frame()
      dist.df_total.j <- data.frame()
      # 
     for (m in 1:nrow(ca.i)){
       i.i   <- i
       j.i   <- ca.i[m,]
       xi.i  <- df[df$i == i.i,2]
       yi.i  <- df[df$i == i.i,3]
       zi.i  <- df[df$i == i.i,4]
       xj.i  <- df[df$i == j.i,2]
       yj.i  <- df[df$i == j.i,3]
       zj.i  <- df[df$i == j.i,4]

       dij.i <- abs(yi.i - yj.i) * wc + abs(zi.i - zj.i) * wa

       dist.df.i       <- data.frame(`i` = i.i, `j` = j.i, dist = dij.i)
       dist.df_total.i <- rbind.data.frame(dist.df_total.i, dist.df.i)

     }

     for (l in 1:nrow(ca.j)){
       i.j   <- j
       j.j   <- ca.j[l,]
       xi.j  <- df[df$i == i.j,2]
       yi.j  <- df[df$i == i.j,3]
       zi.j  <- df[df$i == i.j,4]
       xj.j  <- df[df$i == j.j,2]
       yj.j  <- df[df$i == j.j,3]
       zj.j  <- df[df$i == j.j,4]

       dij.j <- abs(yi.j - yj.j) * wc + abs(zi.j - zj.j) * wa

       dist.df.j       <- data.frame(`i` = i.j, `j` = j.j, dist = dij.j)
       dist.df_total.j <- rbind.data.frame(dist.df_total.j, dist.df.j)

     }

     min.i <- dist.df_total.i %>% slice(which.min(dist))
     min.j <- dist.df_total.j %>% slice(which.min(dist))

     aisle <- data.frame(V1=min.i$j,V2=min.j$j)

     dist.aisle <- semi_join(d.m, aisle, by = c("V1", "V2"))

     # CALCULATING DISTANCE WITHOUT CROSS-AISLES
     if (zi == zj){
       dij <- (abs(xi - xj) * (2 * dc + wa) + v)
    } else if (zi == 1 & zj == 2){
      dij <- ((xj - xi) * (2 * dc + wa) + wa + v)
    } else {
       dij <- ((xj - xi) * (2 * dc * wa) - wa + v)
    }
     min.dij <- min(dij, (min.i$dist + min.j$dist + dist.aisle$Dist))
   }

    dist.df       <- data.frame(`i` = i, `j` = j, dist = min.dij)
    dist.df_total <- rbind.data.frame(dist.df_total, dist.df)

   } 

  return(dist.df_total)
 }

aisle.dist <- CrsAisDst(48, 96, 108, 75, 18, 23, whse.data, cmbn.loc, cross.aisles, 
                        dist.cross.aisle)

输出的结果是这样的。

i    j    dist
7    18   672
7    19   780
7    33   204
....
341  342  108

(注意:我最后运行的这个相同的只是在交叉通道中,这就是为什么数字看起来是一样的。) 不过我已经测试过了,如果距离较小的话,会使用常规公式)。)

© www.soinside.com 2019 - 2024. All rights reserved.