首页 > 解决方案 > 如何在R中的GA中指定决策变量的等式约束?

问题描述

目标和数据

我有非高峰时段和高峰时段的百分比损失值,如下所示。我想优化percent每小时的值,以使负效用的总和(显示在带有x前缀 eg的列中x0506am_td)是最小值。

## Off-Peak hours
TD_OffPeak2 <- structure(list(percent = c(
  0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06,
  0.07, 0.08, 0.09
), x0506am_td = c(
  0, 6579, 13159, 19738, 26317,
  32896, 39476, 46055, 52634, 59213
), x0607am_td = c(
  272800, 277632,
  282464, 287298, 292132, 296967, 301803, 306639, 311477, 316314
), x0708am_td = c(
  6202903, 6208203, 6213504, 6218807, 6224111,
  6229417, 6234724, 6240033, 6245344, 6250656
), x0910am_td = c(
  4061151,
  4064495, 4067840, 4071185, 4074530, 4077876, 4081222, 4084568,
  4087915, 4091262
), x1011am_td = c(
  599364, 604822, 610281, 615743,
  621206, 626671, 632139, 637608, 643079, 648552
), x1112am_td = c(
  500565,
  507908, 515252, 522597, 529943, 537291, 544640, 551989, 559340,
  566693
)), row.names = c(NA, -10L), class = c(
  "tbl_df", "tbl",
  "data.frame"
))



## Peak Hour
TD_Peak2 <- structure(list(percent = c(
  0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06,
  0.07, 0.08, 0.09, 0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17,
  0.18, 0.19, 0.2, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28,
  0.29, 0.3, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39,
  0.4, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.5,
  0.51, 0.52, 0.53, 0.54
), x0809am_td = c(
  26838281, 26829566, 26820854,
  26812145, 26803439, 26794735, 26786034, 26777336, 26768641, 26759949,
  26751260, 26742573, 26733889, 26725208, 26716530, 26707855, 26699183,
  26690513, 26681846, 26673182, 26664521, 26655862, 26647207, 26638554,
  26629904, 26621257, 26612612, 26603971, 26595332, 26586696, 26578063,
  26569433, 26560805, 26552180, 26543558, 26534939, 26526323, 26517709,
  26509099, 26500491, 26491885, 26483283, 26474683, 26466087, 26457493,
  26448902, 26440313, 26431727, 26423145, 26414565, 26405987, 26397413,
  26388841, 26380272, 26371706
)), row.names = c(NA, -55L), class = c(
  "tbl_df",
  "tbl", "data.frame"
))

约束

除 0809am 以外的每个小时的percent值总和应等于mdp

尝试使用 GA 包解决方案

我使用了GA具有如下所示的适应度函数的包来优化percent每小时的值。

# Load Libraries
library(GA)
library(dplyr)

## Fitness Function
fitness_func <- function(offpeak_data,
                               peak_data,
                               mdp,
                               h56p,
                               h67p,
                               h78p,
                               h910p,
                               h1011p,
                               h1112p ){




  mdp <- round(mdp,2)
  h56p <- round(h56p,2)
  h67p <- round(h67p,2)
  h78p <- round(h78p,2)
  h910p <- round(h910p,2)
  h1011p <- round(h1011p, 2)
  h1112p <- round(h1112p, 2)
  h89p <- mdp

## using the constraint 
  if ((h56p + h67p + h78p + h910p + h1011p + h1112p) - mdp <= 0.0001) {



  uval_56 <- offpeak_data$x0506am_td[which(offpeak_data$percent == h56p)]

  uval_67 <-offpeak_data$x0607am_td[which(offpeak_data$percent == h67p)]

  uval_78 <-offpeak_data$x0708am_td[which(offpeak_data$percent == h78p)]

  uval_910 <-offpeak_data$x0910am_td[which(offpeak_data$percent == h910p)]

  uval_1011 <-offpeak_data$x1011am_td[which(offpeak_data$percent == h1011p)]

  uval_1112 <-offpeak_data$x1112am_td[which(offpeak_data$percent == h1112p)]

  uval_89 <-peak_data$x0809am_td[which(peak_data$percent == h89p)]


  total_utility <- uval_56 + uval_67 + uval_78 + uval_910 + uval_1011 + uval_1112 + uval_89

  } else {

    total_utility <- 10000000
  }




  total_utility
}



## Using the GA package:
ga_result2 <- ga(
  type = "real-valued",
  fitness = function(offpeak_data,
                     peak_data,
                     x) {
    total_utility <- -fitness_func(
      offpeak_data,
      peak_data,
      x[1], # mdp,
      x[2], # h56p,
      x[3], # h67p,
      x[4], # h78p,
      x[5], # h910p,
      x[6], # h1011p,
      x[7] # h1112p
    )

    total_utility
  },
  offpeak_data = TD_OffPeak2,
  peak_data = TD_Peak2,
  lower = c(0, 0, 0, 0, 0, 0, 0),
  upper = c(0.54, 0.09, 0.09, 0.09, 0.09, 0.09, 0.09),
  popSize = 50, maxiter = 100,
  monitor = TRUE
)

GA | iter = 1 | Mean = -26971157 | Best = -10000000
GA | iter = 2 | Mean = -17364812 | Best = -10000000
GA | iter = 3 | Mean = -11135468 | Best = -10000000
GA | iter = 4 | Mean = -10567804 | Best = -10000000
GA | iter = 5 | Mean = -10568223 | Best = -10000000
GA | iter = 6 | Mean = -11130456 | Best = -10000000
GA | iter = 7 | Mean = -1e+07 | Best = -1e+07
GA | iter = 8 | Mean = -1e+07 | Best = -1e+07
GA | iter = 9 | Mean = -1e+07 | Best = -1e+07
GA | iter = 10 | Mean = -10563539 | Best = -10000000
GA | iter = 11 | Mean = -11129491 | Best = -10000000
GA | iter = 12 | Mean = -1e+07 | Best = -1e+07
GA | iter = 13 | Mean = -10565386 | Best = -10000000
GA | iter = 14 | Mean = -10564288 | Best = -10000000
GA | iter = 15 | Mean = -1e+07 | Best = -1e+07
GA | iter = 16 | Mean = -1e+07 | Best = -1e+07
GA | iter = 17 | Mean = -1e+07 | Best = -1e+07
GA | iter = 18 | Mean = -11129238 | Best = -10000000
GA | iter = 19 | Mean = -1e+07 | Best = -1e+07
GA | iter = 20 | Mean = -10566658 | Best = -10000000
GA | iter = 21 | Mean = -10566871 | Best = -10000000
GA | iter = 22 | Mean = -1e+07 | Best = -1e+07
GA | iter = 23 | Mean = -1e+07 | Best = -1e+07
GA | iter = 24 | Mean = -1e+07 | Best = -1e+07
GA | iter = 25 | Mean = -10564532 | Best = -10000000
GA | iter = 26 | Mean = -1e+07 | Best = -1e+07
GA | iter = 27 | Mean = -1e+07 | Best = -1e+07
GA | iter = 28 | Mean = -1e+07 | Best = -1e+07
GA | iter = 29 | Mean = -1e+07 | Best = -1e+07
GA | iter = 30 | Mean = -1e+07 | Best = -1e+07
GA | iter = 31 | Mean = -1e+07 | Best = -1e+07
GA | iter = 32 | Mean = -10565518 | Best = -10000000
GA | iter = 33 | Mean = -1e+07 | Best = -1e+07
GA | iter = 34 | Mean = -10564593 | Best = -10000000
GA | iter = 35 | Mean = -1e+07 | Best = -1e+07
GA | iter = 36 | Mean = -10565003 | Best = -10000000
GA | iter = 37 | Mean = -10567136 | Best = -10000000
GA | iter = 38 | Mean = -1e+07 | Best = -1e+07
GA | iter = 39 | Mean = -1e+07 | Best = -1e+07
GA | iter = 40 | Mean = -1e+07 | Best = -1e+07
GA | iter = 41 | Mean = -11132602 | Best = -10000000
GA | iter = 42 | Mean = -1e+07 | Best = -1e+07
GA | iter = 43 | Mean = -1e+07 | Best = -1e+07
GA | iter = 44 | Mean = -1e+07 | Best = -1e+07
GA | iter = 45 | Mean = -1e+07 | Best = -1e+07
GA | iter = 46 | Mean = -11133596 | Best = -10000000
GA | iter = 47 | Mean = -1e+07 | Best = -1e+07
GA | iter = 48 | Mean = -1e+07 | Best = -1e+07
GA | iter = 49 | Mean = -1e+07 | Best = -1e+07
GA | iter = 50 | Mean = -10563668 | Best = -10000000
GA | iter = 51 | Mean = -1e+07 | Best = -1e+07
GA | iter = 52 | Mean = -1e+07 | Best = -1e+07
GA | iter = 53 | Mean = -1e+07 | Best = -1e+07
GA | iter = 54 | Mean = -1e+07 | Best = -1e+07
GA | iter = 55 | Mean = -1e+07 | Best = -1e+07
GA | iter = 56 | Mean = -1e+07 | Best = -1e+07
GA | iter = 57 | Mean = -1e+07 | Best = -1e+07
GA | iter = 58 | Mean = -1e+07 | Best = -1e+07
GA | iter = 59 | Mean = -1e+07 | Best = -1e+07
GA | iter = 60 | Mean = -1e+07 | Best = -1e+07
GA | iter = 61 | Mean = -10564274 | Best = -10000000
GA | iter = 62 | Mean = -1e+07 | Best = -1e+07
GA | iter = 63 | Mean = -10566723 | Best = -10000000
GA | iter = 64 | Mean = -1e+07 | Best = -1e+07
GA | iter = 65 | Mean = -1e+07 | Best = -1e+07
GA | iter = 66 | Mean = -11133478 | Best = -10000000
GA | iter = 67 | Mean = -10565362 | Best = -10000000
GA | iter = 68 | Mean = -1e+07 | Best = -1e+07
GA | iter = 69 | Mean = -1e+07 | Best = -1e+07
GA | iter = 70 | Mean = -1e+07 | Best = -1e+07
GA | iter = 71 | Mean = -1e+07 | Best = -1e+07
GA | iter = 72 | Mean = -10565288 | Best = -10000000
GA | iter = 73 | Mean = -1e+07 | Best = -1e+07
GA | iter = 74 | Mean = -11132318 | Best = -10000000
GA | iter = 75 | Mean = -1e+07 | Best = -1e+07
GA | iter = 76 | Mean = -11701470 | Best = -10000000
GA | iter = 77 | Mean = -11131800 | Best = -10000000
GA | iter = 78 | Mean = -10564773 | Best = -10000000
GA | iter = 79 | Mean = -10567488 | Best = -10000000
GA | iter = 80 | Mean = -1e+07 | Best = -1e+07
GA | iter = 81 | Mean = -1e+07 | Best = -1e+07
GA | iter = 82 | Mean = -1e+07 | Best = -1e+07
GA | iter = 83 | Mean = -1e+07 | Best = -1e+07
GA | iter = 84 | Mean = -10564653 | Best = -10000000
GA | iter = 85 | Mean = -1e+07 | Best = -1e+07
GA | iter = 86 | Mean = -1e+07 | Best = -1e+07
GA | iter = 87 | Mean = -1e+07 | Best = -1e+07
GA | iter = 88 | Mean = -1e+07 | Best = -1e+07
GA | iter = 89 | Mean = -1e+07 | Best = -1e+07
GA | iter = 90 | Mean = -1e+07 | Best = -1e+07
GA | iter = 91 | Mean = -1e+07 | Best = -1e+07
GA | iter = 92 | Mean = -1e+07 | Best = -1e+07
GA | iter = 93 | Mean = -1e+07 | Best = -1e+07
GA | iter = 94 | Mean = -10564223 | Best = -10000000
GA | iter = 95 | Mean = -1e+07 | Best = -1e+07
GA | iter = 96 | Mean = -10567577 | Best = -10000000
GA | iter = 97 | Mean = -10566136 | Best = -10000000
GA | iter = 98 | Mean = -1e+07 | Best = -1e+07
GA | iter = 99 | Mean = -1e+07 | Best = -1e+07
GA | iter = 100 | Mean = -1e+07 | Best = -1e+07

解决方案价值

ga_result2@solution
              x1         x2         x3         x4         x5         x6         x7
 [1,] 0.16634145 0.04334977 0.03966984 0.04517375 0.04751721 0.04560775 0.05269130
 [2,] 0.16687678 0.04621923 0.05054675 0.04705156 0.04730716 0.04867062 0.05250494

问题和疑问

if我用函数中的语句指定了约束。但由于小数位数太多,约束条件很少满足。理想情况下,应始终满足约束。如何确保满足约束并且遗传算法ga函数仅选择小数位的值?

标签: rgenetic-algorithm

解决方案


推荐阅读