Home > Blockchain >  How to perform crossover of two nested lists without changing the contents inside their sub lists in
How to perform crossover of two nested lists without changing the contents inside their sub lists in

Time:05-02

I have two nested lists

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']]]

What I expect is to swap random sub lists from Parent 1 with the other sub lists at the same position in Parent 2 without changing the contents inside them

Expectation example:

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']…

This is what I tried (convert each element into string):

    # 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)

output:

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)

output:

c1: 5222BSC1ST3CR1THTM25225BSC2ST6LH2MTM25225BSC2ST6LB1FTM15222BSC2ST6CR1WTM14202BSC1ST3LH1THTM24202BSC1ST3LR1MTM14227BSC1ST4LH2TTM14222BSC1ST6LB1WTM34210BSC1ST1LH1THTM15227BSC2ST8LB1WTM26226BSC3ST6LB1THTM16226BSC3ST6CR1THTM23225BSC1ST6LB1THTM24202BSC1ST3LH2THTM14222BSC1ST6LH2MTM3
C2: 4202BSC2ST6LR1FTM34222BSC1ST6LH2TTM34222BSC1ST6CR1MTM34202BSC1ST3LH2TTM26008BSC3ST1LH2FTM14210BSC1ST1LH1TTM26008BSC3ST1LH2THTM33225BSC1ST6LH2MTM24210BSC1ST1LR1THTM35225BSC2ST6LH2WTM15019BSC2ST3CR1WTM25019BSC2ST3LB1THTM14220BSC2ST5LB1MTM16008BSC3ST1LH2FTM55019BSC2ST3LH1FTM1

Although, it technically did a crossover operation, it's not what I what I'm looking for. I don't want the contents inside the sub lists to get crossover.

for example from the output above:

Children 1: 5222BSC1ST3...

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

is now different compare to it's original list in parent 1

[5222, 'BSC2', 'ST6']

Also if it's also possible to get the answer in the same format as the Expectation example

CodePudding user response:

It seems you could use random.shuffle to shuffle pairs of sub-sublists in loop and re-assign them back to the original sublists. Since we're shuffling pairs of sub-sublists, the items inside each sub-sublist don't get shuffled.

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

A sample output:

>>> 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']]]

On a smaller sample, this produces:

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]]]
  • Related