为 allocation/assignment 问题设置线性规划
Setting up linear program for allocation/assignment problem
关于我已经解决并使用 excel 的线性程序,我遇到了一些麻烦,但现在我想在 r/python 中进行,因为我已经达到 excels 并且求解器限制.因此,我就此特定主题寻求帮助。
我通过更改 lp.assign 函数尝试了 lPsovle 包,但我无法提出解决方案。
问题如下:
假设我是商品的送货员。
我有不同的仓库,服务于不同的地区。必须满足这些地区的需求。
另一方面,我的仓库对他们可以处理和交付的容量有限制。
一个站点可以服务多个区域,但一个区域只能由一个站点服务。
我有 distance/cost 站点和区域之间的连接矩阵以及该区域的需求。
此解决方案的 objective 应该以尽可能少的努力为这些区域提供服务。
假设 cost/distance 矩阵看起来像这样:
assign.costs <- matrix (c(2, 7, 7, 2, 7, 7, 3, 2, 7, 2, 8, 10, 1, 9, 8, 2,7,8,9,10), 4, 10)
所以这创建了我的矩阵,costumers/areas 在第一个 row/header 中,仓库在第一个 column/row 名称中。
现在areas/customers的需求是:
assign.demand <- matrix (c(1,2,3,4,5,6,7,8,9,10), 1, 10)
容量限制,depos 可以服务的数量是:
assign.capacity <- matrix (c(15,15,15,15), 4, 1)
所以现在我希望这个问题可以通过 lp 来解决,以生成分配,根据这些限制,哪个仓库应该服务于哪个区域。
结果应如下所示:
assign.solution <- matrix (c(1,0,0,0 ,0,1,0,0, 1,0,0,0, 1,0,0,0 ,0,0,0,1), 4, 10)
至于限制,这意味着每列最多只能有一个。
我用 lpSolve 的 lpsolve 和 lp.assign 函数进行了尝试,但我不知道如何实现我所拥有的那种确切的限制,我已经尝试过改变 lp.assign 函数而不用成功。
如果有帮助,我还可以为 lp 制定方程式。
谢谢大家的帮助,我现在真的卡住了:D
BR
步骤 1. 开发数学模型
数学模型可以如下所示:
蓝色条目表示数据,红色条目表示决策变量。 i 是仓库,j 是客户。 Ship 表示我们是否从 i 运送到 j (它是一个二进制变量)。第一个约束表示从仓库 i 发货的总量不应超过其容量。第二个约束条件是每个客户 j 必须恰好有一个供应商 i。
第 2 步。实施
现在这只是一个精确的问题。我尽可能地遵循上一节中的模型。
library(dplyr)
library(tidyr)
library(ROI)
library(ROI.plugin.symphony)
library(ompr)
library(ompr.roi)
num_depots <- 4
num_cust <- 10
cost <- matrix(c(2, 7, 7, 2, 7, 7, 3, 2, 7, 2, 8, 10, 1, 9, 8, 2,7,8,9,10), num_depots, num_cust)
demand <- c(1,2,3,4,5,6,7,8,9,10)
capacity <- c(15,15,15,15)
m <- MIPModel() %>%
add_variable(ship[i,j], i=1:num_depots, j=1:num_cust, type="binary") %>%
add_constraint(sum_expr(demand[j]*ship[i,j], j=1:num_cust) <= capacity[i], i=1:num_depots) %>%
add_constraint(sum_expr(ship[i,j], i=1:num_depots) == 1, j=1:num_cust) %>%
set_objective(sum_expr(cost[i,j]*ship[i,j], i=1:num_depots, j=1:num_cust),"min") %>%
solve_model(with_ROI(solver = "symphony", verbosity=1))
cat("Status:",solver_status(m),"\n")
cat("Objective:",objective_value(m),"\n")
get_solution(m,ship[i, j]) %>%
filter(value > 0)
我们看到首先写下数学模型是多么重要。它比一堆代码更紧凑,更容易推理。直接编写代码通常会导致各种问题。就像建造没有蓝图的房子。即使对于这个小例子,写下数学模型也是一个有用的练习。
对于实现,我使用了 OMPR 而不是 LpSolve 包,因为 OMPR 允许我更接近数学模型。 LpSolve 有一个矩阵接口,除了非常结构化的模型外,它很难使用。
第 3 步:解决问题
Status: optimal
Objective: 32
variable i j value
1 ship 1 1 1
2 ship 4 2 1
3 ship 2 3 1
4 ship 1 4 1
5 ship 3 5 1
6 ship 4 6 1
7 ship 4 7 1
8 ship 2 8 1
9 ship 1 9 1
10 ship 3 10 1
我相信这是正确的解决方案。
关于我已经解决并使用 excel 的线性程序,我遇到了一些麻烦,但现在我想在 r/python 中进行,因为我已经达到 excels 并且求解器限制.因此,我就此特定主题寻求帮助。
我通过更改 lp.assign 函数尝试了 lPsovle 包,但我无法提出解决方案。
问题如下:
假设我是商品的送货员。
我有不同的仓库,服务于不同的地区。必须满足这些地区的需求。 另一方面,我的仓库对他们可以处理和交付的容量有限制。 一个站点可以服务多个区域,但一个区域只能由一个站点服务。
我有 distance/cost 站点和区域之间的连接矩阵以及该区域的需求。
此解决方案的 objective 应该以尽可能少的努力为这些区域提供服务。
假设 cost/distance 矩阵看起来像这样:
assign.costs <- matrix (c(2, 7, 7, 2, 7, 7, 3, 2, 7, 2, 8, 10, 1, 9, 8, 2,7,8,9,10), 4, 10)
所以这创建了我的矩阵,costumers/areas 在第一个 row/header 中,仓库在第一个 column/row 名称中。
现在areas/customers的需求是:
assign.demand <- matrix (c(1,2,3,4,5,6,7,8,9,10), 1, 10)
容量限制,depos 可以服务的数量是:
assign.capacity <- matrix (c(15,15,15,15), 4, 1)
所以现在我希望这个问题可以通过 lp 来解决,以生成分配,根据这些限制,哪个仓库应该服务于哪个区域。
结果应如下所示:
assign.solution <- matrix (c(1,0,0,0 ,0,1,0,0, 1,0,0,0, 1,0,0,0 ,0,0,0,1), 4, 10)
至于限制,这意味着每列最多只能有一个。
我用 lpSolve 的 lpsolve 和 lp.assign 函数进行了尝试,但我不知道如何实现我所拥有的那种确切的限制,我已经尝试过改变 lp.assign 函数而不用成功。 如果有帮助,我还可以为 lp 制定方程式。
谢谢大家的帮助,我现在真的卡住了:D
BR
步骤 1. 开发数学模型
数学模型可以如下所示:
蓝色条目表示数据,红色条目表示决策变量。 i 是仓库,j 是客户。 Ship 表示我们是否从 i 运送到 j (它是一个二进制变量)。第一个约束表示从仓库 i 发货的总量不应超过其容量。第二个约束条件是每个客户 j 必须恰好有一个供应商 i。
第 2 步。实施
现在这只是一个精确的问题。我尽可能地遵循上一节中的模型。
library(dplyr)
library(tidyr)
library(ROI)
library(ROI.plugin.symphony)
library(ompr)
library(ompr.roi)
num_depots <- 4
num_cust <- 10
cost <- matrix(c(2, 7, 7, 2, 7, 7, 3, 2, 7, 2, 8, 10, 1, 9, 8, 2,7,8,9,10), num_depots, num_cust)
demand <- c(1,2,3,4,5,6,7,8,9,10)
capacity <- c(15,15,15,15)
m <- MIPModel() %>%
add_variable(ship[i,j], i=1:num_depots, j=1:num_cust, type="binary") %>%
add_constraint(sum_expr(demand[j]*ship[i,j], j=1:num_cust) <= capacity[i], i=1:num_depots) %>%
add_constraint(sum_expr(ship[i,j], i=1:num_depots) == 1, j=1:num_cust) %>%
set_objective(sum_expr(cost[i,j]*ship[i,j], i=1:num_depots, j=1:num_cust),"min") %>%
solve_model(with_ROI(solver = "symphony", verbosity=1))
cat("Status:",solver_status(m),"\n")
cat("Objective:",objective_value(m),"\n")
get_solution(m,ship[i, j]) %>%
filter(value > 0)
我们看到首先写下数学模型是多么重要。它比一堆代码更紧凑,更容易推理。直接编写代码通常会导致各种问题。就像建造没有蓝图的房子。即使对于这个小例子,写下数学模型也是一个有用的练习。
对于实现,我使用了 OMPR 而不是 LpSolve 包,因为 OMPR 允许我更接近数学模型。 LpSolve 有一个矩阵接口,除了非常结构化的模型外,它很难使用。
第 3 步:解决问题
Status: optimal
Objective: 32
variable i j value
1 ship 1 1 1
2 ship 4 2 1
3 ship 2 3 1
4 ship 1 4 1
5 ship 3 5 1
6 ship 4 6 1
7 ship 4 7 1
8 ship 2 8 1
9 ship 1 9 1
10 ship 3 10 1
我相信这是正确的解决方案。