条件 which.min 函数
conditional which.min function
我有两组数据,一组是机器坐标,一组是最近的维修店坐标。
我有一个工作模型,已将每台机器分配到最近的商店。然而,一个商店只有 1 台机器,而另一家商店分配了 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)
所以我想要的是每个组的最小计数为 2,最大计数为 4,我尝试在最近的中心变量中添加一个 if else 语句,但它甚至没有接近计算就像我想的那样。我在网上四处寻找,但找不到任何方法来向 which.min 语句添加计数条件。
注:我的实际数据集有几千台机器,100多家店铺。
如果 M
是一个 11 x 3 零一矩阵,其中 M[i,j] = 1 如果机器 i 被分配存储 j,否则为 0 那么 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
我有两组数据,一组是机器坐标,一组是最近的维修店坐标。
我有一个工作模型,已将每台机器分配到最近的商店。然而,一个商店只有 1 台机器,而另一家商店分配了 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)
所以我想要的是每个组的最小计数为 2,最大计数为 4,我尝试在最近的中心变量中添加一个 if else 语句,但它甚至没有接近计算就像我想的那样。我在网上四处寻找,但找不到任何方法来向 which.min 语句添加计数条件。
注:我的实际数据集有几千台机器,100多家店铺。
如果 M
是一个 11 x 3 零一矩阵,其中 M[i,j] = 1 如果机器 i 被分配存储 j,否则为 0 那么 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