Python
Please explain why these two codes work differently.. Actually I am trying to make kind of AI where in initial generations the individuals will go in random directions. For keeping the code simple I have provided some random directions in Brain myself.
There is an Individual class that gives a brain to the individual. It also has a function that returns a child with EXACTLY the same brain (means same directions to go in) as the parent.
I have two codes:
First: When some directions is changed in the parent, the same thing is changed in the child too (or if changed in child, it gets changed in parent too) which I don't want to happen.
Second: This one is not completely mine (and that's why I don't really know why it works) but it works fine. Some direction changed in parent is not changed in the child and vice-versa.
Please someone explain me the difference and why first one didn't work. I would really appreciate your answer.
First one:
class Brain():
def __init__(self):
self.directions = [[1, 2], [5, 3], [7, 4], [1, 5]]
class Individual():
def __init__(self):
self.brain = Brain()
def getChild(self):
child = Individual()
child.brain = self.brain
return child
parent = Individual()
child = parent.getChild()
parent.brain.directions[0] = [5, 2]
print(parent.brain.directions)
print(child.brain.directions)
[ [5, 2], [5, 3], [7, 4], [1, 5] ]
[ [5, 2], [5, 3], [7, 4], [1, 5] ]
Second one:
class Brain():
def __init__(self):
self.directions = [[1, 2], [5, 3], [7, 4], [1, 5]]
def clone(self):
clone = Brain()
for i, j in enumerate(self.directions):
clone.directions[i] = j
return clone
class Individual():
def __init__(self):
self.brain = Brain()
def getChild(self):
child = Individual()
child.brain = self.brain.clone()
return child
parent = Individual()
child = parent.getChild()
parent.brain.directions[0] = [5, 2]
print(parent.brain.directions)
print(child.brain.directions)
[ [5, 2], [5, 3], [7, 4], [1, 5] ]
[ [1, 2], [5, 3], [7, 4], [1, 5] ]
In the first code, setting child.brain = self.brain
doesn't do what you're expecting. That is a shallow copy, meaning that it just creates a new pointer to the same instance of Brain()
. So now child.brain
and self.brain
both point to the same Brain()
in memory.
In the second code, you are making a deep copy. Thus, you are actually allocating another Brain()
in memory. Now child.brain
and parent.brain
point to their own separate instance of a Brain()
in memory.