Python 如何在不改变子列表内容的情况下实现两个嵌套列表的交叉?

How to perform crossover of two nested lists without changing the contents inside their sub lists in Python?

我有两个嵌套列表

parent_M: [[[5222, 'BSC2', 'ST6'], ['LR1'], ['FTM3']], [[4222, 'BSC1', 'ST6'], ['LH2'], ['TTM3']], [[4222, 'BSC1', 'ST6'], ['CR1'], ['MTM3']], [[4202, 'BSC1', 'ST3'], ['LH2'], ['TTM2']], [[6008, 'BSC3', 'ST1'], ['LH2'], ['FTM1']], [[4210, 'BSC1', 'ST1'], ['LH1'], ['TTM2']], [[6008, 'BSC3', 'ST1'], ['LH2'], ['THTM3']], [[3225, 'BSC1', 'ST6'], ['LH2'], ['MTM2']], [[4210, 'BSC1', 'ST1'], ['LR1'], ['THTM3']], [[5225, 'BSC2', 'ST6'], ['LH2'], ['WTM1']], [[5019, 'BSC2', 'ST3'], ['CR1'], ['WTM2']], [[5019, 'BSC2', 'ST3'], ['LB1'], ['THTM1']], [[4220, 'BSC2', 'ST5'], ['LB1'], ['MTM1']], [[6008, 'BSC3', 'ST1'], ['LH2'], ['FTM5']], [[5019, 'BSC2', 'ST3'], ['LH1'], ['FTM1']]]
parent_F: [[[4202, 'BSC1', 'ST3'], ['CR1'], ['THTM2']], [[5225, 'BSC2', 'ST6'], ['LH2'], ['MTM2']], [[5225, 'BSC2', 'ST6'], ['LB1'], ['FTM1']], [[5222, 'BSC2', 'ST6'], ['CR1'], ['WTM1']], [[4202, 'BSC1', 'ST3'], ['LH1'], ['THTM2']], [[4202, 'BSC1', 'ST3'], ['LR1'], ['MTM1']], [[4227, 'BSC1', 'ST4'], ['LH2'], ['TTM1']], [[4222, 'BSC1', 'ST6'], ['LB1'], ['WTM3']], [[4210, 'BSC1', 'ST1'], ['LH1'], ['THTM1']], [[5227, 'BSC2', 'ST8'], ['LB1'], ['WTM2']], [[6226, 'BSC3', 'ST6'], ['LB1'], ['THTM1']], [[6226, 'BSC3', 'ST6'], ['CR1'], ['THTM2']], [[3225, 'BSC1', 'ST6'], ['LB1'], ['THTM2']], [[4202, 'BSC1', 'ST3'], ['LH2'], ['THTM1']], [[4222, 'BSC1', 'ST6'], ['LH2'], ['MTM3']]]

我期望的是将父 1 中的随机子列表与父 2 中同一位置的其他子列表交换,而不更改其中的内容

期望示例:

Children 1: [[[5222, 'BSC2', 'ST6'], ['CR1'], ['FTM3']], [[5225, 'BSC2', 'ST6'], ['LH2'], ['MTM2']], [[4222, 'BSC1', 'ST6'], ['LB1'], ['FTM1']], [[4202, 'BSC1', 'ST3'], ['LH2']…
Children 2: [[[4202, 'BSC1', 'ST3'], ['LR1'], ['THTM2']], [[4222, 'BSC1', 'ST6'], ['LH2'], ['TTM3']], [[5225, 'BSC2', 'ST6'], ['CR1'], ['MTM3']], [[5222, 'BSC2', 'ST6'], ['CR1']…

这是我试过的(将每个元素转换成字符串):

    # Crossover Stage
    def crossover_Chromo(self, population):

        c1 = []
        c2 = []

        # convert nested lists to one list
        merged_p1 = list(itertools.chain.from_iterable(population[0]))
        merged_p2 = list(itertools.chain.from_iterable(population[1]))

        parent1 = list(itertools.chain.from_iterable(merged_p1))
        # parent_1_Chromo = ''.join(map(str, parent1))


        parent2 = list(itertools.chain.from_iterable(merged_p2))
        # parent_2_Chromo = ''.join(map(str, parent2))

        parent1 = [str(r) for r in parent1]
        parent2 = [str(r) for r in parent2]

        print("parent_M:", parent1)
        print("parent_F:", parent2)

输出:

parent_M: ['5222', 'BSC2', 'ST6', 'LR1', 'FTM3', '4222', 'BSC1', 'ST6', 'LH2', 'TTM3', '4222', 'BSC1', 'ST6', 'CR1', 'MTM3', '4202', 'BSC1', 'ST3', 'LH2', 'TTM2', '6008', 'BSC3', 'ST1', 'LH2', 'FTM1', '4210', 'BSC1', 'ST1', 'LH1', 'TTM2', '6008', 'BSC3', 'ST1', 'LH2', 'THTM3', '3225', 'BSC1', 'ST6', 'LH2', 'MTM2', '4210', 'BSC1', 'ST1', 'LR1', 'THTM3', '5225', 'BSC2', 'ST6', 'LH2', 'WTM1', '5019', 'BSC2', 'ST3', 'CR1', 'WTM2', '5019', 'BSC2', 'ST3', 'LB1', 'THTM1', '4220', 'BSC2', 'ST5', 'LB1', 'MTM1', '6008', 'BSC3', 'ST1', 'LH2', 'FTM5', '5019', 'BSC2', 'ST3', 'LH1', 'FTM1']
parent_F: ['4202', 'BSC1', 'ST3', 'CR1', 'THTM2', '5225', 'BSC2', 'ST6', 'LH2', 'MTM2', '5225', 'BSC2', 'ST6', 'LB1', 'FTM1', '5222', 'BSC2', 'ST6', 'CR1', 'WTM1', '4202', 'BSC1', 'ST3', 'LH1', 'THTM2', '4202', 'BSC1', 'ST3', 'LR1', 'MTM1', '4227', 'BSC1', 'ST4', 'LH2', 'TTM1', '4222', 'BSC1', 'ST6', 'LB1', 'WTM3', '4210', 'BSC1', 'ST1', 'LH1', 'THTM1', '5227', 'BSC2', 'ST8', 'LB1', 'WTM2', '6226', 'BSC3', 'ST6', 'LB1', 'THTM1', '6226', 'BSC3', 'ST6', 'CR1', 'THTM2', '3225', 'BSC1', 'ST6', 'LB1', 'THTM2', '4202', 'BSC1', 'ST3', 'LH2', 'THTM1', '4222', 'BSC1', 'ST6', 'LH2', 'MTM3']
        # interchanging the genes
        for i in range(self.CROSSOVER_POINT, len(parent1)):
            parent1[i], parent2[i] = parent2[i], parent1[i]

            c1 = ''.join(parent1)
            c2 = ''.join(parent2)

        print("c1:", c1)
        print("C2:", c2)

输出:

c1: 5222BSC1ST3CR1THTM25225BSC2ST6LH2MTM25225BSC2ST6LB1FTM15222BSC2ST6CR1WTM14202BSC1ST3LH1THTM24202BSC1ST3LR1MTM14227BSC1ST4LH2TTM14222BSC1ST6LB1WTM34210BSC1ST1LH1THTM15227BSC2ST8LB1WTM26226BSC3ST6LB1THTM16226BSC3ST6CR1THTM23225BSC1ST6LB1THTM24202BSC1ST3LH2THTM14222BSC1ST6LH2MTM3
C2: 4202BSC2ST6LR1FTM34222BSC1ST6LH2TTM34222BSC1ST6CR1MTM34202BSC1ST3LH2TTM26008BSC3ST1LH2FTM14210BSC1ST1LH1TTM26008BSC3ST1LH2THTM33225BSC1ST6LH2MTM24210BSC1ST1LR1THTM35225BSC2ST6LH2WTM15019BSC2ST3CR1WTM25019BSC2ST3LB1THTM14220BSC2ST5LB1MTM16008BSC3ST1LH2FTM55019BSC2ST3LH1FTM1

虽然,它在技术上做了交叉操作,但这不是我要找的。我不希望子列表中的内容交叉

例如上面的输出:

Children 1: 5222BSC1ST3...

would be:
[5222, 'BSC1', 'ST3']

现在与父级 1 中的原始列表相比有所不同

[5222, 'BSC2', 'ST6']

此外,如果也可以获得与预期示例

格式相同的答案

您似乎可以使用 random.shuffle 将成对的 sub-sublists 循环洗牌,然后 re-assign 将它们放回原始子列表。由于我们正在洗牌 sub-sublists 对,每个 sub-sublist 中的项目不会被洗牌。

import random
for lst1, lst2 in zip(parent_M, parent_F):
    for i, pair in enumerate(zip(lst1, lst2)):
        pair = list(pair)
        random.shuffle(pair)
        lst1[i], lst2[i] = pair

示例输出:

>>> parent_M
[[[5222, 'BSC2', 'ST6'], ['CR1'], ['THTM2']],
 [[4222, 'BSC1', 'ST6'], ['LH2'], ['TTM3']],
 [[5225, 'BSC2', 'ST6'], ['LB1'], ['FTM1']],
 [[5222, 'BSC2', 'ST6'], ['LH2'], ['WTM1']],
 [[4202, 'BSC1', 'ST3'], ['LH2'], ['FTM1']],
 [[4202, 'BSC1', 'ST3'], ['LH1'], ['TTM2']],
 [[6008, 'BSC3', 'ST1'], ['LH2'], ['TTM1']],
 [[4222, 'BSC1', 'ST6'], ['LB1'], ['WTM3']],
 [[4210, 'BSC1', 'ST1'], ['LR1'], ['THTM3']],
 [[5225, 'BSC2', 'ST6'], ['LH2'], ['WTM2']],
 [[6226, 'BSC3', 'ST6'], ['CR1'], ['WTM2']],
 [[5019, 'BSC2', 'ST3'], ['CR1'], ['THTM2']],
 [[3225, 'BSC1', 'ST6'], ['LB1'], ['MTM1']],
 [[6008, 'BSC3', 'ST1'], ['LH2'], ['FTM5']],
 [[4222, 'BSC1', 'ST6'], ['LH2'], ['FTM1']]]

>>> parent_F
[[[4202, 'BSC1', 'ST3'], ['LR1'], ['FTM3']],
 [[5225, 'BSC2', 'ST6'], ['LH2'], ['MTM2']],
 [[4222, 'BSC1', 'ST6'], ['CR1'], ['MTM3']],
 [[4202, 'BSC1', 'ST3'], ['CR1'], ['TTM2']],
 [[6008, 'BSC3', 'ST1'], ['LH1'], ['THTM2']],
 [[4210, 'BSC1', 'ST1'], ['LR1'], ['MTM1']],
 [[4227, 'BSC1', 'ST4'], ['LH2'], ['THTM3']],
 [[3225, 'BSC1', 'ST6'], ['LH2'], ['MTM2']],
 [[4210, 'BSC1', 'ST1'], ['LH1'], ['THTM1']],
 [[5227, 'BSC2', 'ST8'], ['LB1'], ['WTM1']],
 [[5019, 'BSC2', 'ST3'], ['LB1'], ['THTM1']],
 [[6226, 'BSC3', 'ST6'], ['LB1'], ['THTM1']],
 [[4220, 'BSC2', 'ST5'], ['LB1'], ['THTM2']],
 [[4202, 'BSC1', 'ST3'], ['LH2'], ['THTM1']],
 [[5019, 'BSC2', 'ST3'], ['LH1'], ['MTM3']]]

在较小的样本中,这会产生:

parent_M = [[[1,2], [3,4], [5]], [[6,7], [8,9,10]]]
parent_F = [[[11,12], [13], [14,15]], [[16], [17]]]

>>> parent_M
[[[1, 2], [13], [14, 15]], [[16], [8, 9, 10]]]

>>> parent_F
[[[11, 12], [3, 4], [5]], [[6, 7], [17]]]