Пайтон, функция random, математика, генетический отбор
программа является попыткой имитации генетического отбора в биологии, суть которого заключается в том, что при появлении потомства мама и папа дают ему свои гены, однако у людей гены бывают бракованными, в проге "2" это хороший ген, "1" это ген который работает на половину, а "0" это не рабочий ген (обычно такие люди рождаются мутантами и долго не живут), но в попытке написать это мы обнаружили что люди с единицами выражаются, и всё сводится либо к плохим(0) генам либо к хорошим(2) (в программе они по сути тождественны друг-другу), поводом написать программу стала наше желание узнать какие люди будут преобладать (ожидалось, что тех кого изначально было больше) в реальной жизни это работает не так как у нас в программе тк, ирл люди с мутациями обычно не оставляют потомства, да и не рождают только двух детей... вопрос: почему независимо от исходных значений единицы выраждаются, такого быть не должно это мы неправильно написали программу или что?
import numpy as np
import random as rd
def proc(): ## генирирует 1,2 или 0 с разными шансам у единицы 50%, у нуля и двойки по 25%
a=0
a = rd.randrange(1, 5)
if a == 2:
lst2.append(2)
if a == 1 or a == 4:
lst2.append(1)
if a == 3:
lst2.append(0)
lst=[]
lst2=[]
for i in range(45):
lst.append(2)
for i in range(50):
lst.append(1)
for i in range(5):
lst.append(0)
print(lst)
for i in range(1000):
rd.shuffle(lst)
print(lst)
for j in range(0,100,2):
if lst[j]==2 and lst[j+1]==2:
lst2.append(2)
lst2.append(2)
if lst[j] == 1 and lst[j + 1] == 2 or lst[j] == 2 and lst[j + 1] == 1:
lst2.append(rd.randrange(1,3))
lst2.append(rd.randrange(1,3))
if lst[j] == 1 and lst[j + 1] == 1:
proc()
proc()
if lst[j] == 1 and lst[j + 1] == 0 or lst[j] == 0 and lst[j + 1] == 1:
lst2.append(rd.randrange(0, 2))
lst2.append(rd.randrange(0, 2))
if lst[j] == 2 and lst[j + 1] == 0 or lst[j] == 0 and lst[j + 1] == 2:
lst2.append(1)
lst2.append(1)
if lst[j] == 0 and lst[j + 1] == 0:
lst2.append(0)
lst2.append(0)
k1, k2, k3 = 0, 0, 0
for i in range(100):
if lst[i] == 2:
k2 += 1
if lst[i] == 1:
k1 += 1
if lst[i] == 0:
k3 += 1
print("2=", k2, " 1=", k1, " 0=", k3)
lst = lst2
lst2 = []
""
Ответы (1 шт):
Проблемы:
- В начальном заполнении
- В правилах
Если вы посмотрите на правила, то по ним сохраняются стабильными все комбинации, кроме 1+1, которая рандомизируется в произвольные числа в определённом соотношении. Да, ещё есть шанс получить на выходе 1 и 1 по одному из правил, но для этого нужно сочетание 0+2 или 2+0. А теперь представьте себе ситуацию, когда чего-то одного у вас уже больше, чем другого - либо 0 либо 2. Много ли вы получите комбинаций 0+2 и 2+0 на выходе? Не больше, чем количество меньше встречающегося из этих двух чисел. Таким образом, если ситуация начнёт перекашиваться в какую-то сторону (в сторону 0 или в сторону 2), то количество 1 начнёт соответственно уменьшаться и чем дальше, тем сильнее.
А теперь посмотрите на начальное распределение. Вы изначально добавляете много двоек и мало нулей. Чтобы хотя бы более-менее были равные условия, вам нужно сделать начальное соотношение хотя бы такое же, как вы делаете в proc(), иначе у вас единицы начинают исчезать практически сразу.
Ну и в целом, эти правила можно было бы записать гораздо короче с помощью словаря, где ключом будет кортеж из двух значений, а значением можно прописать lambda, выдающую нужный результат (фиксированный, либо получаемый вызовом функции). Таким образом можно было бы код записать короче, проще и понятнее. Если не совсем ясно, я потом могу добавить такой код.