每条染色体包含一组基因,每个基因包含一个字母和一个数字,每个染色体中字母和数字都只能存在一次。
Parent A = {a,1}{c,2}{e,3}{g,4}
Parent B = {a,2}{b,1}{c,4}{d,3}
创建不违反上述规则的孩子的最佳交叉运算符是什么?
每条染色体包含一组基因,每个基因包含一个字母和一个数字,每个染色体中字母和数字都只能存在一次。
Parent A = {a,1}{c,2}{e,3}{g,4}
Parent B = {a,2}{b,1}{c,4}{d,3}
创建不违反上述规则的孩子的最佳交叉运算符是什么?
首先,将两个父染色体存储到一个排序字典中(就实现而言,std::map在 C++ 中可能是一个不错的选择),其中键是字母,值是一对ints(第二个基因元素)。当您填充地图时,将来自每个染色体的所有字母添加为键并取0(或负数)以指示具有相应字母的基因不存在于其中一个父母中。
接下来,创建第二张地图,这次使用数字作为键。遍历第一张地图。如果两个父染色体都包含具有相同字母的基因,则映射中的值字段将包含两个正数 - 随机选择一个并将 {number, letter} 组合插入到第二个映射中,前提是该数字不存在一键。如果该基因仅存在于一个亲本中,则要么按原样选择该基因,要么选择完全跳过该基因。
这将保证 1)您的基因组仅包含一次 {letter, number} 基因和 2)后代染色体中的基因将自动按字母排序。如果您不需要对基因进行排序但仍需要它们是唯一的,则可以使用无序映射(哈希表)。
在您的示例中,地图如下所示:
Mapped parent chromosomes
{a: (1,2)}
{b: (0,1)}
{c: (2,4)}
{d: (0,3)}
{e: (3,0)}
{g: (4,0)}
Offspring chromosome (OC)
{}
where0表示对应的基因在那个亲本中不存在。从上到下遍历此表,您最终可能会执行以下操作:
a:挑选1;1不是 OC 中的键,所以插入{1,a}b:挑选1;1是 OC 中的一个键,所以跳过字母bc:挑选4;4不是 OC 中的键,所以插入{4,c}d:选择跳过e:挑选3;3不是 OC 中的键,所以插入{3,e}g:挑选4;4是 OC 中的一个键,所以跳过字母g最终后代染色体:
{a,1}{c,4}{e,3}