我的人工智能课程中有一项任务。
这是我们必须使用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
国防指挥官希望士兵在巡逻时完全专注,所以他给出了这个命令:
两种可能的方法(到目前为止):
GA的适应度函数将接受许多焊料,然后进行模拟:
创建一个初始种群(焊接者)并在健身功能中应用指挥官的规则(我真的不知道如何在这里定义上述规则),然后运行GA直到我们得到一些有用的分数。
答案 0 :(得分:1)
我的方法是让人口中的个人代表一些士兵并将这些士兵分配给轮班。因此,对于300名士兵来说,染色体在0到23之间需要300个数字(假设每个士兵每天都采取相同的班次),标记他开始6个小时的时间,但不是每个人都有相同的染色体长度。有些人将分配300名士兵,其他人将是500名士兵。我不熟悉R中的GA库,但这是他们应该能够处理的。
现在,考虑到一个人并将每个士兵分配到轮班,你可以使用问题规则轻松计算每小时有多少士兵在守卫墙壁。您的目标是使此计划尽可能接近一般订单,因此您的适应度函数(GA将最大化)应与结果计划和一般订单之间的差异成反比。当差值为0时,您已找到最佳解决方案。
您可以添加其他偏差和约束。比方说,如果你不想要任何有防护墙的解决方案,你可以给这些人特别低的适应性。
答案 1 :(得分:1)
由于作业结束了(是的,我和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)
GA生成一组士兵数量,每小时开始观察(有24小时,这就是为什么24个零和24倍150),并用所述向量调用Fitness
函数。
Fitness函数首先将实数转换为整数(R as.integer
函数只是在小数点后删除任何数字,不进行舍入),并将士兵分配给它的6小时工作。它是通过在士兵休息的两个小时内添加从x[i]
到y[i, i+1, ... i+7]
开始的士兵数量来实现的。
由于士兵全天候守卫,y
中的最后7个小时会被添加到y
的前7个小时,然后才会考虑y
的前24个值。
然后我们将手表上生成的士兵矢量与所需的矢量进行比较,如果矢量中有FALSE
个,Fitness
会返回一个非常大的负数(GA总是需要更大数字是一个更好的)。
最后,我们希望尽可能“雇用”小兵,这就是为什么我们否定结果(需要更少的士兵数量=更高的否定数量),以便GA找到最佳结果。
其余部分非常自我解释,我们称之为GA功能,我们调整其设置并显示结果。
答案 2 :(得分:0)
以下是我们每小时需要的士兵
soldiers
# 150 160 160 170 350 380 400 420 450 470 500 500 450 350 300 300 310 350 350
# 330 300 250 200 170
所以我们需要:
sum(soldiers)
# 7770
但每个士兵在墙上工作6个小时,所以:
sum(soldiers)/6
# 1295
现在问题是如何适应规则:我会说2小时休息是最小的而不是必须的。我没有看到它的重点,它会导致问题(我们需要更多的士兵而不是1295) 这是一个起点,而不是0从1295开始。所以我会选择第一种方法,即使我对GA库一无所知。
答案 3 :(得分:0)
我认为第一种方法不是遗传算法。据我所知,GA从一些初始人口开始,健身功能用于选择人口中最好的个体。
但是,我会以不同于你的方式定义初始人口。它应该是一个数字集合,其中每个数字表示城市中的士兵数量。例如,个人1代表10名士兵,个人2代表120名士兵,个人N代表680名士兵。
然后在GA的每个步骤中,您应该选择(基于适应度函数)最佳个体,即最佳的数字。这些人将被用于使用交叉和变异等遗传算子创造新一代。例如,交叉可以定义为计算两个数字的平均值。
关于健身功能。它应该确定给定数量的士兵是否是最佳的。最佳,我的意思是如果有太多(一些士兵无聊)或太少(城墙上没有足够的士兵)士兵的信息。
你应该运行GA,直到最好的个人从你的角度来看足够好。
请注意,这是一项功课,如果没有遗传算法,这个问题就可以解决。