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.
In first case you are referring same object. Try adding following print statement in first case.
print (id(parent.brain))
print (id(child.brain))
Have new reference for Brain() in first case. you can see how it handles.
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 = Brain()
return child
parent = Individual()
child = parent.getChild()
parent.brain.directions[0] = [5, 2]
print(parent.brain.directions)
print(child.brain.directions)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.