1

我正在尝试使用 lpSolveAPI 和 R 设置线性编程解决方案来解决调度问题。以下是一小部分数据;每个会话 ID 所需的分钟数,以及它们的“首选”顺序/权重。

id <- 1:100
min <- sample(0:500, 100)
weight <- (1:100)/sum(1:100)
data <- data.frame(id, min, weight)

我想要做的是安排/安排这些会话 ID,以便一天中有最大数量的会话,最好按它们的权重计算,并且每天的上限为 400 分钟。

这就是我目前在 R 中设置它的方式:

require(lpSolveAPI)

#Set up matrix to hold results; each row represents day
r <- 5
c <- 10
row <- 1

results <- matrix(0, nrow = r, ncol = c)
rownames(results) <- format(seq(Sys.Date(), by = "days", length.out = r), "%Y-%m-%d")

for (i in 1:r){
    for(j in 1:c){  
        lp <- make.lp(0, nrow(data)) 
        set.type(lp, 1:nrow(data), "binary")
        set.objfn(lp, rep(1, nrow(data)))
        lp.control(lp, sense = "max")
        add.constraint(lp, data$min, "<=", 400)
        set.branch.weights(lp, data$weight)

        solve(lp)
        a <- get.variables(lp)*data$id
        b <- a[a!=0]

        tryCatch(results[row, 1:length(b)] <- b, error = function(x) 0)

        if(dim(data[!data$id == a,])[1] > 0) {
            data <- data[!data$id== a,]
            row <- row + 1
        }
        break

    }
}

sum(results > 0)    

barplot(results) #View of scheduled IDs

快速查看结果矩阵告诉我,虽然设置可以最大限度地增加会话数,以便一天中的总分钟数尽可能接近 400,但设置并没有遵循给定的权重。我希望我的结果矩阵充满越来越多的会话 ID。

我尝试过分配不同的权重,以相反的顺序分配权重等,但由于某种原因,我的设置似乎没有强制执行“set.branch.weights”。

我已经阅读了“set.branch.weights”的文档,lpSolveAPI但我认为我在这里做错了。

示例 - 数据:

   id   min weight
    1   67  1
    2   72  2
    3   36  3
    4   91  4
    5   80  5
    6   44  6
    7   76  7
    8   58  8
    9   84  9
    10  96  10
    11  21  11
    12  1   12
    13  41  13
    14  66  14
    15  89  15
    16  62  16
    17  11  17
    18  42  18
    19  68  19
    20  25  20
    21  44  21
    22  90  22
    23  4   23
    24  33  24
    25  31  25

应该

    Day 1   67  72  36  91  80  44  76          
    Day 2   58  84  96  21  1   41  66  89      
    Day 3   62  11  42  68  25  44  90  4   33  31

每天的累计总和为 <= 480m。

4

2 回答 2

1

我头脑简单的方法:

df = read.table(header=T,text="
 id   min weight
  1   67  1
  2   72  2
  3   36  3
  4   91  4
  5   80  5
  6   44  6
  7   76  7
  8   58  8
  9   84  9
  10  96  10
  11  21  11
  12  1   12
  13  41  13
  14  66  14
  15  89  15
  16  62  16
  17  11  17
  18  42  18
  19  68  19
  20  25  20
  21  44  21
  22  90  22
  23  4   23
  24  33  24
  25  31  25")
# assume sorted by weight 

daynr = 1
daymax = 480
dayusd = 0
for (i in 1:nrow(df))
{
  v = df$min[i]
  dayusd = dayusd + v
  if (dayusd>daymax)
  {
    daynr = daynr + 1
    dayusd = v
  }
  df$day[[i]] = daynr
}

这将给出:

 > df
    id min weight day
 1   1  67      1   1
 2   2  72      2   1
 3   3  36      3   1
 4   4  91      4   1
 5   5  80      5   1
 6   6  44      6   1
 7   7  76      7   1
 8   8  58      8   2
 9   9  84      9   2
 10 10  96     10   2
 11 11  21     11   2
 12 12   1     12   2
 13 13  41     13   2
 14 14  66     14   2
 15 15  89     15   2
 16 16  62     16   3
 17 17  11     17   3
 18 18  42     18   3
 19 19  68     19   3
 20 20  25     20   3
 21 21  44     21   3
 22 22  90     22   3
 23 23   4     23   3
 24 24  33     24   3
 25 25  31     25   3
 >
于 2016-01-18T12:07:57.360 回答
0

我将专注于第一个解决方案。我们基本上解决了一个背包问题(目标+一个约束):

在此处输入图像描述

当我按原样运行此模型时,我得到:

> solve(lp)
[1] 0
> x <- get.variables(lp)
> weightx <- data$weight * x
> sum(x)
[1] 14
> sum(weightx)
[1] 0.5952381

现在,当我将目标更改为

在此处输入图像描述

我得到:

> solve(lp)
[1] 0
> x <- get.variables(lp)
> weightx <- data$weight * x
> sum(x)
[1] 14
> sum(weightx)
[1] 0.7428571

即计数停留在 14,但体重有所改善。

于 2016-01-14T05:37:13.547 回答