最近写一个遗传算法,采用部分匹配交叉策略,假设两条染色体是:
X : 2 3 4 5 6 7 8 1
Y : 1 2 3 4 5 6 7 8
交叉点i = 2, j = 6, 即中间的4个基因进行交换
X : 2 3 3 4 5 6 8 1
Y : 1 2 4 5 6 7 7 8
这样将产生重复基因,所以需要对交叉片段之外的基因按照交叉片段之内的基因对应关系进行映射。
比如对上面那条染色体的基因3,与交叉片段内的3冲突,映射成下面那条染色体交叉片段内对应的4。而映射之后可能再次与交叉片段内的基因冲突,所以需要重新再检查基因片段中的每个基因。
首先对X中的每个基因,在交叉片段中遍历查找是否有冲突的基因,如果有则进行基因映射,并且循环地执行前面的过程直到找不到冲突的基因为止。
总之,最后我用了4重循环才实现,而这个4重循环本来就套在两重循环里面……
后来发现,如果使用goto,可以很直接地表达通常思维,将4重循环改成2重循环,是循环变量局限了我的思维。
//xk> 总结
在循环结构里面,用continue可以跳出本次循环,用break可以跳出整个循环结构。
而用goto,可以实现跳到循环开头重新执行这个循环结构。正好符合上面部分交叉匹配策略的要求:用Y染色体中的4将X[1]从3换成4之后,需要重新检索是否与交叉片段中的某个基因冲突。
好吧,我2了,在循环中将循环变量i赋值为0然后continue就可以重新执行这个循环结构了。写这篇博客就是记下自己是怎么2的……
不过,如果要跳出多重循环结构之外,比如需要跳出然后重新执行一个多重循环结构,这时修改每层的循环变量就不好使了,需要break跳出多个内层循环并且正好接下来执行最外层循环中的一个continue语句。这便是goto的一个典型应用场景:跳出到多重循环结构之前重新执行多重循环。