This analysis employs the Non-Dominated Sorting Genetic Algorithm II
(NSGA-II), a robust multi-objective evolutionary algorithm, to address
complex optimization problems. The study includes two scientifically
relevant case studies:
1. Car Example: Optimizes fuel consumption and maximum
speed based on vehicle weight and power. This is critical in automotive
engineering for designing sustainable vehicles, balancing environmental
impact (fuel efficiency) with performance (speed), which influences
market competitiveness and regulatory compliance.
2. DRASTIC Index Example: Optimizes weights of the
DRASTIC parameters (Depth to water, net Recharge, Aquifer media, Soil
media, Topography, Impact of vadose zone, and Conductivity) to maximize
correlation with nitrate concentration (NO3) while minimizing Root Mean
Square Error (RMSE). This enhances groundwater vulnerability assessment,
providing valuable insights for environmental management and
policy-making in regions prone to contamination.
The analysis generates Pareto fronts to visualize trade-offs, computes
optimal solutions, and exports results as CSV files for further
scientific evaluation.
To install these packages, use:
install.packages('package_name').
library(mco) # Using mco for nsga2 consistently
library(irr)
library(terra)
library(raster)
library(randtoolbox)
Define a fitness function to evaluate fuel consumption and maximum speed based on weight and power.
voiture_fitness2 <- function(x) {
if (is.null(dim(x))) x <- matrix(x, nrow = 1)
poids <- x[, 1]
puissance <- x[, 2]
# Objective 1: Fuel consumption (non-linear)
conso <- 3 + (poids/1000)^2 * 2 + (puissance/100)^1.5
# Objective 2: Maximum speed (maximized, so expressed as negative for minimization)
vitesse <- 100 + sqrt(puissance*2) - (poids/50)^1.2
moins_vitesse <- -vitesse
cbind(conso, moins_vitesse)
}
Define bounds for weight (500 to 2000) and power (50 to 300), then run NSGA-II with a population of 100 over 200 iterations.
set.seed(123)
lower_bounds <- c(500, 50)
upper_bounds <- c(2000, 300)
result2 <- nsga2(
fn = voiture_fitness2,
idim = 2, # Two decision variables: weight and power
odim = 2, # Two objectives: consumption and speed
lower.bounds = lower_bounds,
upper.bounds = upper_bounds,
popsize = 100,
generations = 200,
cprob = 0.8,
mprob = 0.1
)
Visualize the Pareto front to highlight trade-offs between fuel consumption and maximum speed.
pareto <- t(result2$value) # Transpose to match expected format
plot(pareto[,1], -pareto[,2],
col = "grey", pch = 16,
xlab = "Fuel Consumption (L/100km)",
ylab = "Maximum Speed (km/h)",
main = "Pareto Front (Car) — Fuel Consumption vs Speed")
points(pareto[,1], -pareto[,2],
col = "red", pch = 19)
grid()
Export the Pareto front solutions as a CSV file.
pareto_df <- data.frame(Fuel_Consumption = pareto[,1], Max_Speed = -pareto[,2])
write.csv(pareto_df, "pareto_car.csv", row.names = FALSE)
Generate synthetic data for DRASTIC parameters and nitrate concentration (NO3).
set.seed(123)
ncell <- 1000
val_D <- runif(ncell, 1, 10)
val_R <- runif(ncell, 10, 200)
val_A <- runif(ncell, 0, 50)
val_S <- runif(ncell, 0.1, 1)
val_T <- runif(ncell, 0, 50)
val_I <- runif(ncell, 0, 1)
val_C <- runif(ncell, 0, 10)
val_NO3 <- 0.3*val_D + 0.2*val_R + 0.1*val_A +
0.15*val_S + 0.05*val_T + 0.1*val_I + 0.1*val_C +
rnorm(ncell, 0, 2)
Define a function to maximize correlation with NO3 and minimize RMSE.
objectif <- function(x) {
indice <- x[1]*val_D + x[2]*val_R + x[3]*val_A +
x[4]*val_S + x[5]*val_T + x[6]*val_I + x[7]*val_C
valid <- complete.cases(indice, val_NO3)
if(sum(valid)<10) return(c(Inf,Inf))
obj1 <- -cor(indice[valid], val_NO3[valid]) # Maximize correlation
obj2 <- sqrt(mean((indice[valid]-val_NO3[valid])^2)) # Minimize RMSE
return(c(obj1, obj2))
}
Run NSGA-II to optimize weights for DRASTIC parameters, specifying input and output dimensions.
lower <- rep(0,7)
upper <- rep(5,7)
resultats <- nsga2(
fn = objectif,
idim = 7, # Seven decision variables: weights for D, R, A, S, T, I, C
odim = 2, # Two objectives: correlation and RMSE
lower.bounds = lower,
upper.bounds = upper,
popsize = 100,
generations = 200,
cprob = 0.8,
mprob = 0.05
)
Visualize the Pareto front for correlation and RMSE.
pareto <- t(resultats$value) # Transpose to match expected format
plot(-pareto[,1], pareto[,2],
xlab="Correlation (Maximize)",
ylab="RMSE (Minimize)",
pch=19, col="blue",
main="Pareto Front - DRASTIC Index vs NO3")
grid()
Extract and display the optimal weights for the DRASTIC parameters.
poids_optimaux <- t(resultats$par) # Transpose to match expected format
head(poids_optimaux, 5)
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 0.29490257 0.31236162 0.29507742 0.29536041 0.29576471 0.29578309
## [2,] 0.20169220 0.20150134 0.20178748 0.20216151 0.20286284 0.20187863
## [3,] 0.09623253 0.09619983 0.09620497 0.09620406 0.09621246 0.09619576
## [4,] 0.06009000 0.19609425 0.06024000 0.05769326 0.05840951 0.05839318
## [5,] 0.04480819 0.04676567 0.04489977 0.04490026 0.04512149 0.04496717
## [,7] [,8] [,9] [,10] [,11] [,12]
## [1,] 0.30386968 0.29515623 0.29639332 0.31026811 0.29981602 0.30048026
## [2,] 0.20251176 0.20183890 0.20257627 0.20152947 0.20301709 0.20317446
## [3,] 0.09616824 0.09620400 0.09620298 0.09619416 0.09619975 0.09619963
## [4,] 0.12342678 0.06235650 0.05739912 0.20718934 0.11159226 0.06550075
## [5,] 0.04650782 0.04495535 0.04501255 0.04708417 0.04569668 0.04586000
## [,13] [,14] [,15] [,16] [,17] [,18]
## [1,] 0.30948433 0.30747454 0.29667032 0.29919897 0.31080509 0.30959704
## [2,] 0.20183569 0.20220654 0.20310219 0.20299146 0.20156263 0.20158895
## [3,] 0.09620515 0.09621181 0.09622426 0.09619889 0.09621866 0.09620154
## [4,] 0.17191941 0.15384833 0.05812079 0.05839452 0.17630884 0.20732396
## [5,] 0.04684861 0.04642746 0.04511297 0.04572203 0.04684447 0.04708417
## [,19] [,20] [,21] [,22] [,23] [,24]
## [1,] 0.29990630 0.29565195 0.29863517 0.29584234 0.30212362 0.29981602
## [2,] 0.20301709 0.20217614 0.20299243 0.20223456 0.20255021 0.20301709
## [3,] 0.09619523 0.09620454 0.09623967 0.09620036 0.09620164 0.09619975
## [4,] 0.11642371 0.06211861 0.05732819 0.05704289 0.15403801 0.11159226
## [5,] 0.04658439 0.04490026 0.04545451 0.04496361 0.04583005 0.04569668
## [,25] [,26] [,27] [,28] [,29] [,30]
## [1,] 0.31223299 0.30176536 0.29576842 0.31026811 0.30739134 0.29515623
## [2,] 0.20152875 0.20255021 0.20263723 0.20152947 0.20186560 0.20186839
## [3,] 0.09620225 0.09620548 0.09620048 0.09620154 0.09620803 0.09620149
## [4,] 0.20682523 0.13395254 0.05841610 0.20732396 0.17643692 0.06215943
## [5,] 0.04667869 0.04584546 0.04526168 0.04708417 0.04669377 0.04495535
## [,31] [,32] [,33] [,34] [,35] [,36]
## [1,] 0.30700197 0.29639332 0.29912933 0.31253753 0.29919520 0.30048026
## [2,] 0.20220654 0.20259798 0.20299243 0.20150461 0.20295614 0.20322946
## [3,] 0.09620355 0.09620692 0.09619703 0.09620032 0.09620439 0.09620660
## [4,] 0.15384833 0.05927509 0.05709548 0.19889731 0.11734551 0.05778310
## [5,] 0.04642746 0.04510456 0.04526524 0.04676567 0.04566827 0.04512154
## [,37] [,38] [,39] [,40] [,41] [,42]
## [1,] 0.30471556 0.30577897 0.30506863 0.30747454 0.30710117 0.30176536
## [2,] 0.20251176 0.20220485 0.20252910 0.20220654 0.20221700 0.20255021
## [3,] 0.09620172 0.09620374 0.09616897 0.09621181 0.09616897 0.09620548
## [4,] 0.11769787 0.15384833 0.13351376 0.15113852 0.15040503 0.13395254
## [5,] 0.04673571 0.04658232 0.04584697 0.04683491 0.04614459 0.04574367
## [,43] [,44] [,45] [,46] [,47] [,48]
## [1,] 0.31253753 0.30116142 0.30559534 0.30116142 0.30941449 0.29587705
## [2,] 0.20150461 0.20293381 0.20220654 0.20299074 0.20184682 0.20239697
## [3,] 0.09620032 0.09616114 0.09621181 0.09620035 0.09617794 0.09619882
## [4,] 0.19579951 0.11307826 0.15028582 0.11307826 0.17670400 0.05449049
## [5,] 0.04676567 0.04569668 0.04657912 0.04575057 0.04661639 0.04496475
## [,49] [,50] [,51] [,52] [,53] [,54]
## [1,] 0.29507434 0.29578724 0.30701010 0.29584234 0.29972108 0.30259448
## [2,] 0.20169184 0.20238314 0.20238422 0.20248843 0.20317185 0.20256749
## [3,] 0.09620497 0.09620161 0.09620242 0.09620007 0.09619985 0.09622554
## [4,] 0.06154954 0.05832155 0.15634277 0.05830393 0.05834213 0.11127120
## [5,] 0.04490025 0.04490553 0.04583422 0.04496361 0.04578321 0.04577421
## [,55] [,56] [,57] [,58] [,59] [,60]
## [1,] 0.30239863 0.30988012 0.30988012 0.29930476 0.30600249 0.30736423
## [2,] 0.20301748 0.20154418 0.20156263 0.20327230 0.20212734 0.20193615
## [3,] 0.09618537 0.09620276 0.09621866 0.09619939 0.09620803 0.09617762
## [4,] 0.11205931 0.17630884 0.17630884 0.07630158 0.16424083 0.17135764
## [5,] 0.04576219 0.04682367 0.04683538 0.04578667 0.04669807 0.04661714
## [,61] [,62] [,63] [,64] [,65] [,66]
## [1,] 0.30587516 0.30768645 0.30459026 0.30747454 0.30718831 0.29584719
## [2,] 0.20221509 0.20253991 0.20252910 0.20220654 0.20220976 0.20220247
## [3,] 0.09619783 0.09620818 0.09616897 0.09621181 0.09620803 0.09620455
## [4,] 0.15054412 0.12342678 0.12342678 0.15113852 0.16424083 0.05842905
## [5,] 0.04654414 0.04613417 0.04613417 0.04685794 0.04669377 0.04502217
## [,67] [,68] [,69] [,70] [,71] [,72]
## [1,] 0.29584719 0.30259448 0.29916645 0.29515623 0.30128698 0.29583732
## [2,] 0.20220018 0.20256749 0.20295532 0.20183890 0.20255021 0.20284411
## [3,] 0.09620458 0.09622489 0.09620439 0.09620400 0.09620548 0.09620007
## [4,] 0.06232190 0.11721919 0.11734551 0.06215943 0.12386557 0.05831298
## [5,] 0.04503287 0.04580188 0.04566827 0.04495535 0.04613265 0.04496361
## [,73] [,74] [,75] [,76] [,77] [,78]
## [1,] 0.29673081 0.30948433 0.30048026 0.30728967 0.29589543 0.30924079
## [2,] 0.20313870 0.20183896 0.20317446 0.20193615 0.20240054 0.20176254
## [3,] 0.09619899 0.09620515 0.09619989 0.09617762 0.09619882 0.09619622
## [4,] 0.05446662 0.17191941 0.05774207 0.17670400 0.05449049 0.17287312
## [5,] 0.04495557 0.04684861 0.04570459 0.04661714 0.04496698 0.04699227
## [,79] [,80] [,81] [,82] [,83] [,84]
## [1,] 0.29503030 0.31223299 0.29973010 0.30701010 0.31133811 0.30950285
## [2,] 0.20169220 0.20142032 0.20317185 0.20231494 0.20151063 0.20176254
## [3,] 0.09623253 0.09620225 0.09619982 0.09620235 0.09620045 0.09619622
## [4,] 0.06009000 0.21778048 0.05834213 0.15634277 0.19524593 0.17176968
## [5,] 0.04480819 0.04665994 0.04511279 0.04583422 0.04676743 0.04699227
## [,85] [,86] [,87] [,88] [,89] [,90]
## [1,] 0.30924079 0.29584234 0.31223428 0.31228096 0.30176536 0.31223428
## [2,] 0.20176254 0.20248843 0.20151330 0.20150423 0.20255021 0.20151708
## [3,] 0.09619636 0.09620007 0.09620045 0.09619983 0.09620574 0.09620045
## [4,] 0.17419720 0.05830393 0.20003377 0.19609425 0.12620387 0.22481779
## [5,] 0.04699227 0.04496361 0.04676782 0.04676567 0.04569005 0.04676743
## [,91] [,92] [,93] [,94] [,95] [,96]
## [1,] 0.30718099 0.29578724 0.30701010 0.29507434 0.29931378 0.30425740
## [2,] 0.20186560 0.20238314 0.20231494 0.20169184 0.20327230 0.20252910
## [3,] 0.09620803 0.09620161 0.09620206 0.09620497 0.09619937 0.09616899
## [4,] 0.17643692 0.05832155 0.15634277 0.06154954 0.07630158 0.12342678
## [5,] 0.04669377 0.04490553 0.04583422 0.04490025 0.04511624 0.04609755
## [,97] [,98] [,99] [,100]
## [1,] 0.29583732 0.30747454 0.29912933 0.30924079
## [2,] 0.20284411 0.20190195 0.20299243 0.20176254
## [3,] 0.09620007 0.09621181 0.09619703 0.09619636
## [4,] 0.05831298 0.17358711 0.05709548 0.17419720
## [5,] 0.04496361 0.04642746 0.04545451 0.04699227
Export the Pareto front and optimal weights as CSV files.
pareto_df <- data.frame(Correlation = -pareto[,1], RMSE = pareto[,2])
write.csv(pareto_df, "pareto_drastic.csv", row.names = FALSE)
write.csv(poids_optimaux, "poids_optimaux_drastic.csv", row.names = FALSE)
Abdi-Basid ADAN (abdi-basid@outlook.com)