多个约束条件下的二维装箱问题——寻找《开罗拉面店》最优布局之代码解析(五)遗传算法解析
前言 遗传算法的一些思路我在开篇有提到一些,这里给出具体过程: 1、生成两个种群,分别使用BL算法和BL_plus算法; 2、开始迭代 3、调用两个种群的update_max()函数更新最优个体 4、如果两个种群中有最优解(也就是12家店铺全部铺上去了),则跳出循环,返回该个体; 5、如果达到迭代次数,则跳出循环,返回两个种群的最优个体; 6、如果达到交换迭代次数,则: 假设种群P1的最优个体适应
目录3 个章节

前言
遗传算法的一些思路我在开篇有提到一些,这里给出具体过程: 1、生成两个种群,分别使用BL算法和BL_plus算法; 2、开始迭代 3、调用两个种群的update_max()函数更新最优个体 4、如果两个种群中有最优解(也就是12家店铺全部铺上去了),则跳出循环,返回该个体; 5、如果达到迭代次数,则跳出循环,返回两个种群的最优个体; 6、如果达到交换迭代次数,则: 假设种群P1的最优个体适应值为fbest1,P2的最优个体适应值为fbest2 (1)若fbest1>fbest2,则用P1的最优个体替换P2的最劣个体; (2)若fbest1<fbest2,则用P2的最优个体替换P1的最劣个体; 7、对两个种群分别进行选择、交叉、变异

8、更新两个新种群的最优个体 9、若新种群最优个体的适应值小于旧种群最优个体适应值,则用旧种群的最优个体替换新种群的最劣个体。
核心代码
/// <summary>
/// 遗传算法
/// </summary>
/// <param name="path">店铺数据位置</param>
/// <param name="w">地区宽度</param>
/// <param name="h">地区高度</param>
/// <param name="iterations">迭代次数</param>
/// <param name="size">种群大小</param>
/// <param name="change">交换迭代次数</param>
/// <param name="crossover_frequency">交叉频率</param>
/// <param name="Pc1">用于计算交叉概率的参数一</param>
/// <param name="Pc2">用于计算交叉概率的参数二</param>
/// <param name="Pm1">用于计算变异概率的参数一</param>
/// <param name="Pm2">用于计算变异概率的参数二</param>
/// <param name="op_int">在基因片段一上的交叉算子</param>
/// <param name="op_bool">在基因片段二上的交叉算子</param>
/// <param name="va_int">在基因片段一上的变异算子</param>
/// <param name="va_bool">在基因片段二上的变异算子</param>
/// <returns>最优个体</returns>
public static Individual Inheritance(string path, int w, int h, int iterations, int size, int change,
double crossover_frequency, double Pc1, double Pc2, double Pm1, double Pm2, operator_int op_int,
operator_bool op_bool, variation_int va_int, variation_bool va_bool)
{
Population pop1 = new Population(path, w, h, size, "BL");
Population pop2 = new Population(path, w, h, size, "BL_plus");
int fbest;
for (int iteration = 0; iteration < iterations; iteration++)
{
pop1.update_max();
pop2.update_max();
fbest = pop1.fmax > pop2.fmax ? pop1.fmax : pop2.fmax;
Console.WriteLine("第{0}次迭代,最优解的适应度为:{1}", iteration, fbest);
if (pop1.Fmax.character.Count == 12)
{
return pop1.Fmax;
}
if (pop2.Fmax.character.Count == 12)
{
return pop2.Fmax;
}
if ((iteration + 1) % change == 0)
{
int min_index_1 = pop1.find_min_index();
int min_index_2 = pop2.find_min_index();
if (pop1.fmax > pop2.fmax)
{
pop2.ind[min_index_2] = pop1.Fmax;
pop2.update_max();
}
else if (pop1.fmax < pop2.fmax)
{
pop1.ind[min_index_1] = pop2.Fmax;
pop1.update_max();
}
}
int crossover_times = (int) (size * crossover_frequency);
double cros_prob, r, var_prob;
Individual parent1, parent2;
List<Individual> new_ind = new List<Individual>();
List<int[]> gene_int;
List<bool[]> gene_bool;
//处理pop1
for (int i = 0; i < crossover_times; i++)
{
parent1 = pop1.ind[pop1.roulette()];
parent2 = pop1.ind[pop1.roulette()];
cros_prob = pop1.cros_probability(parent1, parent2, Pc1, Pc2);
r = Population.rand_double();
if (r <= cros_prob)
{
gene_int = op_int(parent1.gene_order, parent2.gene_order);
gene_bool = op_bool(parent1.gene_rotate, parent2.gene_rotate);
Individual child;
int[] ge_int;
bool[] ge_bool;
for (int j = 0; j < 2; j++)
{
child = new Individual(w, h, gene_int[j], gene_bool[j], "BL",
pop1.decode(gene_int[j], gene_bool[j]));
var_prob = pop1.mut_probability(child, Pm1, Pm2);
r = Population.rand_double();
if (r < var_prob)
{
ge_int = va_int(gene_int[j]);
ge_bool = va_bool(gene_bool[j]);
child = new Individual(w, h, ge_int, ge_bool, "BL",
pop1.decode(ge_int, ge_bool));
}
new_ind.Add(child);
}
}
}
while (new_ind.Count < size)
{
new_ind.Add(pop1.ind[pop1.roulette()]);
}
int index, fmax = 0;
for (int i = 0; i < size; i++)
{
if (new_ind[i].fit_count() > fmax)
{
fmax = new_ind[i].fit_count();
}
}
if (fmax < pop1.fmax)
{
index = 0;
int fmin = int.MaxValue;
for (int i = 0; i < size; i++)
{
if (new_ind[i].fit_count() < fmin)
{
index = i;
fmin = new_ind[i].fit_count();
}
}
new_ind[index] = pop1.Fmax;
}
pop1.ind = new_ind;
//处理pop2
new_ind = new List<Individual>();
for (int i = 0; i < crossover_times; i++)
{
parent1 = pop2.ind[pop2.roulette()];
parent2 = pop2.ind[pop2.roulette()];
cros_prob = pop2.cros_probability(parent1, parent2, Pc1, Pc2);
r = Population.rand_double();
if (r <= cros_prob)
{
gene_int = op_int(parent1.gene_order, parent2.gene_order);
gene_bool = op_bool(parent1.gene_rotate, parent2.gene_rotate);
Individual child;
int[] ge_int;
bool[] ge_bool;
for (int j = 0; j < 2; j++)
{
child = new Individual(w, h, gene_int[j], gene_bool[j], "BL_plus",
pop2.decode(gene_int[j], gene_bool[j]));
var_prob = pop2.mut_probability(child, Pm1, Pm2);
r = Population.rand_double();
if (r > var_prob)
{
ge_int = va_int(gene_int[j]);
ge_bool = va_bool(gene_bool[j]);
child = new Individual(w, h, ge_int, ge_bool, "BL_plus",
pop2.decode(ge_int, ge_bool));
}
new_ind.Add(child);
}
}
}
while (new_ind.Count < size)
{
new_ind.Add(pop2.ind[pop2.roulette()]);
}
fmax = 0;
for (int i = 0; i < size; i++)
{
if (new_ind[i].fit_count() > fmax)
{
fmax = new_ind[i].fit_count();
}
}
if (fmax < pop2.fmax)
{
index = 0;
int fmin = int.MaxValue;
for (int i = 0; i < size; i++)
{
if (new_ind[i].fit_count() < fmin)
{
index = i;
fmin = new_ind[i].fit_count();
}
}
new_ind[index] = pop2.Fmax;
}
pop2.ind = new_ind;
}
if (pop1.fmax > pop2.fmax)
{
return pop1.Fmax;
}
return pop2.Fmax;
}
最后
以上便是我寻找《开罗拉面店》最优解的全部过程啦!中间我走了很多弯路,甚至还准备了十几个参数准备拿来调参的,没想到才迭代了130多次就出结果了,非常幸运!不过其实也很好理解,因为按照我改进的算法生成的初始解,本来就离最优解不远,收敛速度快是很显然的。
最后贴上我找到的两个最优解:


_EOF_
多个约束条件下的二维装箱问题——寻找《开罗拉面店》最优布局之代码解析(五)遗传算法解析
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
多个约束条件下的二维装箱问题——寻找《开罗拉面店》最优布局
前言 前段时间无聊回坑玩《开罗拉面店》,这是一款模拟经营类的小游戏,不管是画风还是游戏性都很对我胃口。 里面有一个玩法是拉面店布局,就给你一块地,还有几家店铺,你可以随便铺随便摆,当然肯定是摆的越多家店铺越好。 我一开始玩的时候也没想那么多,随便摆了摆就完事了,但玩到后期人气上不去,我就突发奇想,能不能把所有店铺摆进去?或者能不能尽可能多地去铺满这块地? 我就到处去找资料,然后有找到一个帖子是摆了
2021-12-18 · 算法/机器学习 · 约 1 分钟
使用分形思想,通过图灵完备的机器赛跑关卡,并获得小机快跑成就
本文将用尽量通俗易懂的语言, 为了解过和没了解过图灵完备和分形的读者讲解用分形思想来通过机器赛跑这一关并达成成就“小机快跑”的思路, 同时也将给出实现该思路的汇编代码。
2024-02-06 · 算法/机器学习 · 约 1 分钟
多个约束条件下的二维装箱问题——寻找《开罗拉面店》最优布局之代码解析(一)
介绍 本代码是用C#实现的。在开始代码解析之前,先把要用到的数据贴出来: | 店铺id | 店铺宽度 | 店铺高度 | 入口位置 | | ------ | -------- | -------- | -------- | | 1 | 9 | 6 | (5,6) | | 2 | 5 | 6 | (1,6) | | 3
2021-12-18 · 算法/机器学习 · 约 1 分钟
LittleWhiteOne基本设计
LittleWhite One 魔改chatterbot框架实现的新版小白~ 简介 core:核心框架,魔改版chatterbot corpus:英文和中文训练语料 nltk_data:需要用到的nltk数据集 文本相似度算法 LevenshteinDistance SpacySimilarity JaccardSimilarity Levenshtein Distance算法 中文名:莱文斯坦距
2021-12-18 · 算法/机器学习 · 约 1 分钟
讨论
共 0 条加载评论中…