条件which.min函数

时间:2018-01-09 22:21:50

标签: r geospatial which geosphere

我有两组数据,一组是机器的坐标,一组是最近的维修店的坐标。

我有一个工作模型,已将每台机器分配到最近的商店。但是,一个商店只有一台机器,另一个商店分配了7台机器。

我想要的是添加条件,以便为每个商店分配至少2台机器但不超过4台。

library(geosphere)
library(ggplot2)
#machine Locations
machine.x <- c(-122.37, -111.72,    -111.87,    -112.05,    -87.17, -86.57, -86.54, -88.04, -86.61, -88.04, -86.61)
machine.y <- c(37.56,   35.23,  33.38,  33.57,  30.36,  30.75,  30.46,  30.68,  30.42,  30.68,  30.42)
machines <- data.frame(machine.x, machine.y)
#store locations
store.x <- c(-121.98, -112.17, -86.57)
store.y <- c(37.56, 33.59, 30.75)
stores <- data.frame(store.x, store.y)


centers<-data.frame(x=stores$store.x, y=stores$store.y)
pts<-data.frame(x=(machines$machine.x), y=(machines$machine.y))

#allocate space
distance<-matrix(-1, nrow = length(pts$x), ncol= length(centers$x))
#calculate the dist matrix - the define centers to each point
#columns represent centers and the rows are the data points
dm<-apply(data.frame(1:length(centers$x)), 1, function(x){ replace(distance[,x], 1:length(pts$x), distGeo(centers[x,], pts))})

#find the column with the smallest distance
closestcenter<-apply(dm, 1, which.min)


#color code the original data for verification
colors<-c(stores)
#create a scatter plot of assets color coded by which fe they belong to
plot(pts, col=closestcenter, pch=9)

enter image description here

所以我想要的是每个组的最小数量为2,最大数量为4,我尝试在最接近的中心变量中添加if else语句但是它甚至没有接近计算我认为它的方式。我已经在线查看但无法找到任何方法在which.min语句中添加计数条件。

注意:我的实际数据集有数千台机器和100多个商店。任何想法或想法都非常感激。

1 个答案:

答案 0 :(得分:3)

如果M是一个11 x 3的零一矩阵,其中如果机器i被分配给存储j则M [i,j] = 1,否则M的行必须是每个总和到1并且列必须总和为2到4(包括两者),我们希望选择这样的M,这样可以最小化距离sum(M * dm)的总和。这将为我们提供如下所示的0-1线性程序。 A下方的A %*% c(M)rowSums(M)相同。同样B使B %*% c(M)colSums(M)相同。

library(lpSolve)

k <- 3
n <- 11

dir <- "min"
objective.in <- c(dm)
A <- t(rep(1, k)) %x% diag(n)
B <- diag(k) %x% t(rep(1, n))
const.mat <- rbind(A, B, B)
const.dir <- c(rep("==", n), rep(">=", 3), rep("<=", 3))
const.rhs <- c(rep(1, n), rep(2, k), rep(4, k))
res <- lp(dir, objective.in, const.mat, const.dir, const.rhs, all.bin = TRUE)

res
## Success: the objective function is 9025807 

soln <- matrix(res$solution, n, k)

和这个解决方案:

> soln
      [,1] [,2] [,3]
 [1,]    1    0    0
 [2,]    1    0    0
 [3,]    0    1    0
 [4,]    0    1    0
 [5,]    0    1    0
 [6,]    0    0    1
 [7,]    0    0    1
 [8,]    1    0    0
 [9,]    0    0    1
[10,]    0    1    0
[11,]    0    0    1

或就分配给每台机器的商店编号向量而言:

c(soln %*% (1:k))
## [1] 1 1 2 2 2 3 3 1 3 2 3