我的人工智能课有一个作业。
这是一个必须用遗传算法在R(使用GA库)中解决的问题我在想办法解决这个问题。
说明
野蛮人围攻一座城市。将军下令每天每小时有多少士兵守卫城墙。这是他的桌子:
Time of the day | Number of soldiers
00:00 - 01:00 150
01:00 - 02:00 160
02:00 - 03:00 160
03:00 - 04:00 170
04:00 - 05:00 350
05:00 - 06:00 380
06:00 - 07:00 400
07:00 - 08:00 420
08:00 - 09:00 450
09:00 - 10:00 470
10:00 - 11:00 500
11:00 - 12:00 500
12:00 - 13:00 450
13:00 - 14:00 350
14:00 - 15:00 300
15:00 - 16:00 300
16:00 - 17:00 310
17:00 - 18:00 350
18:00 - 19:00 350
19:00 - 20:00 330
20:00 - 21:00 300
21:00 - 22:00 250
22:00 - 23:00 200
23:00 - 24:00 170
防长希望士兵们在巡逻时能全神贯注,所以他下令:
每一个守卫城墙的士兵一天整整6小时(24小时):在城墙上4小时,然后休息2小时,然后再回到城墙上2小时
在午夜前开始,在第二天早上继续的焊工-算法必须考虑白天的连续性。
护墙需要多少士兵?
到目前为止我的想法
两种可能的方法(目前为止):
第一种方法
遗传算法的适应度函数接受多个焊料,然后进行模拟:
将初始分数设置为0。
如果在模拟过程中,城市中的士兵数量不足或过多,则从分数中减去。
最优解是当得分为零时(所需兵力的数量是最优的)。
第二种方法
创建一个初始种群(solders),并在fitness函数中应用来自指挥官的规则(我不知道如何在这里定义上述规则),然后运行ga,直到得到一些有用的分数。
最佳答案
因为作业结束了(是的,我和OP上同一个班),这是一个非常有趣的问题,所以我在这里发布我的解决方案:
library(GA)
Fitness <- function(x) {
x <- as.integer(x)
# z represents required soldiers at each hour
z <- c(150,160,160,170,350,380,400,420,450,470,500,500,450,350,300,300,310,350,350,330,300,250,200,170)
y <- rep(0,31)
for (i in 1:length(x)) {
y[i] <- y[i] + x[i]
y[i+1] <- y[i+1] + x[i]
y[i+2] <- y[i+2] + x[i]
y[i+3] <- y[i+3] + x[i]
#resting 4, 5
y[i+6] <- y[i+6] + x[i]
y[i+7] <- y[i+7] + x[i]
}
for (i in 1:7) {
y[i] <- y[i]+y[24+i]
}
y <- y[1:24]
p <- y >= z
if (FALSE %in% p) { return(-3000) }
return(-sum(x))
}
GA <- ga(type = "real-valued", fitness = Fitness, min = rep(0, 24), max = rep(150, 24), popSize = 24, suggestions = sol, maxiter = 5000, run = 5000, pmutation=0.9)
summary(GA)
sol <- (as.integer(GA@solution[1, ]))
sol
sum(sol)
遗传算法生成一个每个小时开始观察的士兵数量向量(有24小时,这就是为什么24个零和24乘以150),并用该向量调用
Fitness
函数。fitness函数首先将实数转换为整数(r
as.integer
函数只去除小数点后的任何数字,不舍入),并将士兵分配给其6小时的工作。它通过将开始于x[i]
的士兵数量增加到y[i, i+1, ... i+7]
而不需要士兵休息的两个小时。因为士兵们24小时不间断地守卫,所以在
y
的前7小时加上y
的最后7小时,然后只考虑y
的前24个值。然后我们将生成的值班士兵向量与所需向量进行比较,如果向量中有任何
FALSE
s,Fitness
返回一个非常大的负数(GA总是取较大的数作为较好的数)。最后,我们希望“雇佣”尽可能少的士兵,这就是我们否定结果的原因(需要的士兵数量越少=否定的数量越高),这样遗传算法就可以找到最好的结果。
剩下的很简单,我们调用ga函数,修改它的设置并显示结果。