Я думаю, что Джон Коулман прав, и вам нужно просто изменить знак своей функции стоимости, чтобы она была минимизирована. Ниже приведен (немного избыточный) пример того, как это небольшое добавление минуса к вашей функции приведет к совершенно другому решению (надеюсь, правильному). Я нанес на график результаты аналогично тому, как это делает GA
, как я видел из вашего кода, что вы также рассматривали это как вариант (на самом деле довольно хороший). Для GA
функция стоимости: максимальное , поэтому вам нужно удалить минус.
library(GenSA)
library(GA)
df <- read.table(text = ",gewichten(gr),waarde
Voorwerp 1,70,135
Voorwerp 2,73,139
Voorwerp 3,77,149
Voorwerp 4,80,150
Voorwerp 5,82,156
Voorwerp 6,87,163
Voorwerp 7,90,173
Voorwerp 8,94,184
Voorwerp 9,98,192
Voorwerp 10,106,201
Voorwerp 11,110,210
Voorwerp 12,113,214
Voorwerp 13,115,221
Voorwerp 14,118,229
Voorwerp 15,120,240", sep = ",", header = T
)
#Define function
knapsack <- function(x) {
f <- sum(x * df[3])
penalty <- sum(df[2]) * abs(sum(x*df[2]) - 750)
-(f - penalty) # SIMPLY ADDED A MINUS SIGN
}
init <- runif(1, -5000, 5000)
onder <- rep(-5000, length(init))
boven <- rep(5000, length(init))
controlelijst <- list(max.time=25, nb.stop.improvement = 100)
resultaatSA <- GenSA(par=init, lower = onder, upper = boven, fn=knapsack, control=controlelijst)
resultaatSA$par # 0.5233775
head(resultaatSA$trace.mat)
# summarize results
tmp <- as.data.frame(resultaatSA$trace.mat)
meani <- aggregate(tmp$function.value, list(step = tmp$nb.steps),mean, na.rm = TRUE)
exe <- aggregate(tmp$current.minimum, list(step = tmp$nb.steps),mean, na.rm = TRUE)
medi <- aggregate(tmp$function.value, list(step = tmp$nb.steps),median, na.rm = TRUE)
ylim <- c(min(range(exe$x,na.rm = TRUE, finite = TRUE)),
max(range(meani$x, na.rm = TRUE, finite = TRUE)))
# plot
op <- par(mar=c(5.1, 4.1, 1, 4.1))
plot(tmp$nb.steps, tmp$function.value, type = "n", ylim = ylim, xlab = "Iteration",
ylab = "Cost value")
graphics::grid(equilogs = FALSE)
points(tmp$nb.steps, tmp$current.minimum, type = "o", pch = 16, lty = 1,
col = "green3", cex = 0.7)
points(meani$step, meani$x, type = "o", pch = 1, lty = 2,
col = "dodgerblue3", cex = 0.7)
polygon(c(meani$step, rev(meani$step)),
c(exe$x, rev(medi$x)),
border = FALSE, col = adjustcolor("green3", alpha.f = 0.1))
par(new=TRUE)
plot(tmp$nb.steps, tmp$temperature, t="l", col=2, lty=2, log="y", axes = FALSE, xlab = "", ylab = "")
axis(4, col=2, col.axis=2); mtext(text = "Temperature", side = 4, line = par()$mgp[1], col=2)
legend("topright", legend = c("Best", "Mean", "Median", "Temperature"),
col = c("green3", "dodgerblue3", adjustcolor("green3", alpha.f = 0.1), 2),
pch = c(16, 1, NA, NA), lty = c(1,2,1,2),
lwd = c(1, 1, 10, 1), pt.cex = c(rep(0.7,2), 2, NA),
inset = 0.02)
par(op)