Objective and Data
I have disutilities values by percentage for off-peak and peak hours as shown below. I want to optimize the percent values for each hour so that the sum of disutilities (shown in columns with the x prefix e.g. x0506am_td) is the minimum.
## 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"
))
Constraint
The sum of percent values for each hour other than 0809am should be equal to mdp.
Attempt at Solution using GA Package
I used the GA package with a fitness function shown below to optimize the percent values for each hour.
# 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
Solution values
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
Problem and Questions
I specified the constraint with an if statement in the function. But because of so many number of decimal places, the constraint condition is satisfied rarely. Ideally, the constraint should always be satisfied. How can I make sure that the constraint is satisfied and genetic algorithm ga function picks the values to decimal places only?