Python - wprowadzenie

08 - Zadania 1

Przyszedł czas na ćwiczenia podsumowujące pierwszą część kursu. Przykłady dotyczą kilku zjawisk związanych z biologią, należy więc najpierw zrozumieć problem, a później przystąpić do projektowania i pisania programów.

Malthus, czyli wzrost wykładniczy i arytmetyczny

Thomas Malthus był angielskim ekonomistą i demografem, który pod koniec XVII wieku opublikował pracę ,,An Essay on the Principle of Population''. Zawarł w niej stwierdzenie, że populacja ludzka wzrasta w postępie geometrycznym, natomiast produkcja żywności w postępie arytmetycznym. Ponieważ wzrost arytmetyczny w dłuższej perspektywie nie nadąża za geometrycznym, wg. autora sytuacja taka prowadzi nieuchronnie do klęski głodu.

Opisany przez Malthusa związek między populacją i żywnością nie jest oczywiście ograniczony do ludzi, ale może być podstawą stworzenia uproszczonego modelu wzrostu populacji z uwzględnieniem ograniczeń związanych z zasobami środowiska (niekoniecznie tylko żywności). Można w ten sposób na przykład symulować wzrost populacji zwierząt zasiedlających wyspę, czy rozwój bakterii w pożywce w warunkach laboratoryjnych. Tworząc odpowiedni model, należy oczywiście wziąć pod uwagę specyfikę symulowanego układu: populacja – środowisko. Zauważ, że założenie o wzroście zasobów żywności, związane z postępem w rolnictwie, rzadko będzie miało rację bytu w modelach odnoszących się do warunków naturalnych czy rozwijających się w szalce drobnoustrojów.

Zadanie

Zadanie polega na stworzeniu symulacji wzrostu populacji i zasobów żywnościowych aż do chwili, kiedy zacznie brakować pożywienia. Zakładamy, że pokolenia nie zachodzą na siebie – liczebność populacji i ilość żywności zmienia się w kolejnych krokach co sezon. Program powinien na bieżąco wyświetlać zmieniające się parametry. Rozwiązania pojawią się mniej więcej za tydzień.

Założenia i wzory

Jak wynika z tezy Malthusa, będziemy mieli do czynienia z dwoma rodzajami wzrostu:

Wzrost arytmetyczny polega na tym, że ilość (np. żywności) wzrasta o pewną stałą wartość. Tak więc ilość pożywienia w kolejnym sezonie będzie równa:

$$ Z_{i} = Z_{i-1} + a $$

Gdzie: $$Z\ –\ ilość\ żywności,\ i\ –\ kolejny\ sezon,\ a\ –\ przyrost\ żywności\ w\ kolejnym\ sezonie\ (stała)$$

Z kolei dla wzrostu geometrycznego (wykładniczego) populacji obliczając jej wielkość w kolejnym sezonie, mnożymy liczbę osobników w poprzednim sezonie o pewną stałą, która uwzględnia przyrost osobników (współczynnik wzrostu populacji):

$$ N_{i} = N_{i-1} \cdot R $$

Gdzie: $$N\ –\ liczba\ osobników,\ i\ –\ kolejny\ sezon,\ R\ –\ współczynnik\ wzrostu\ populacji$$

Stała używana we wzorze może uwzględniać pojawienie się nowych osobników i śmierć części osobników populacji. Oczywiście, jeśli chcielibyśmy stworzyć bardziej realistyczny model, należałoby uwzględnić takie czynniki jak dojrzewanie, przerwy między wydaniem kolejnych potomków, czy stosunek płci.

Ponieważ w programie uwzględniamy zależność między populacją a zasobami, zakładamy, że każdy osobnik zużywa określoną ilość pożywienia (zasobów środowiska), którą możemy określić jakąś stałą (np. c). Populacja może się rozrastać, dopóki ilość zużywanych zasobów nie przekracza zasobów istniejących w danym pokoleniu. Jeśli będzie większa, dochodzi do zatrzymania wzrostu, o czym program powinien poinformować i zakończyć działanie.

Wskazówki

Program powinien pobrać od użytkownika wszystkie potrzebne wartości:

  • początkową liczbę osobników
  • początkową ilość pożywienia (zasobów)
  • przyrost ilości żywności w kolejnym sezonie
  • współczynnik wzrostu populacji
  • ilość żywności zużywanej przez osobnika w sezonie

Dla każdego pokolenia wyświetlane są zmieniające się wartości charakteryzujące model, np:

  • numer pokolenia
  • liczba osobników
  • ilość zasobów
  • o ile osobników zwiększyła się populacja w sezonie
  • zużywana żywność przez populację
  • jaki jest bieżący nadmiar żywności

Jeśli zacznie brakować zasobów, program zatrzymuje się i wyświetla końcowy komunikat podsumowujący przebieg symulacji.

Przykładowe rozwiązanie

To jest oczywiście prosta symulacja procesu i dość prosty kod. Na przykład przyjęliśmy wartość float dla liczby osobników dla uproszczenia kodu, ale także dlatego, że może ona niekoniecznie przedstawiać liczbę pojedynczych osobników, lecz np. wyrażać ich liczbę w tysiącach, czy milionach.

Możesz spróbować udoskonalić powyższy kod, np. poprawiając estetykę wyświetlanych wyników, czy umożliwiając użytkownikowi powtarzanie symulacji z nowymi parametrami.

Dobór naturalny

Tematem tego zadania będzie symulacja doboru naturalnego. Będziemy symulować ten proces na poziomie genetycznym a dokładniej jako zmiany częstości występowania dwu alleli jednego genu. Będziemy brali pod uwagę trzy genotypy: AA, Aa, oraz aa. Można sobie wyobrazić na przykład, że gen odpowiada za barwę sierści: czarną (genotyp AA), szarą (Aa) i białą (aa). Każdy z nich może mieć inne dostosowanie (w) co oznacza, że trzymając się powyższego przykładu, barwa sierści ma wpływ na możliwość przetrwania albo zwabienie partnera. W skrócie – im większa wartość, tym więcej osobniki o danym genotypie pozostawiają przeciętnie potomstwa. Dostosowanie jest wartością wynikającą z porównania konkurujących osobników (genotypów), aby wartości miały biologiczny sens, powinny mieścić się między 0 a 1, przy czym, przynajmniej dla jednego z genotypów dostosowanie powinno wynosić 1.

W kolejnych pokoleniach dochodzi do losowego krzyżowania się osobników, a to jak wiele powstaje osobników o poszczególnych genotypach, wynika z tego, jak dużo jest poszczególnych alleli w populacji a dokładnie z ich częstości, czyli frekwencji. Frekwencja danego allelu to liczba kopii tego allelu podzielona przez liczbę wszystkich alleli może więc przyjmować wartości między 0 a 1. Frekwencje alleli, oznaczane są zwyczajowo literami p (dla allelu A) i q (a). Częstość genotypów (liczba osobników o danym genotypie/liczba wszystkich osobników), które powstają w kolejnym pokoleniu, można wyliczyć ze wzorów znanych z prawa Hardy’ego-Weinberga:

$$ P_{AA} = p^2, P_{Aa} = 2pq, P_{aa} = q^2 $$

Gdzie: $$P_{AA}\ –\ frekwencja\ genotypu\ AA,\ P_{Aa}\ –\ frekwencja\ genotypu\ Aa,\ P_{aa}\ –\ frekwencja\ genotypu\ aa,$$ $$p\ –\ frekwencja\ allelu\ A,\ q\ –\ frekwencja\ allelu\ a$$

Pamiętaj, że suma frekwencji alleli jak też suma frekwencji wszystkich genotypów powinna wynosić 1.

Ponieważ, jak napisałem powyżej, genotypy mogą mieć różne wartości dostosowania, a więc różna będzie ilość zostawionego przez nich potomstwa, będzie w takiej sytuacji mogło dochodzić do zmian częstości alleli w kolejnych pokoleniach. Zmianę częstości występowania allelu a opisuje wzór:

$$ \Delta q = \frac{pq}{W_s}[q(w_{aa}-w_{Aa})- p(w_{AA}-w_{Aa})] $$

Gdzie: $$\Delta q\ –\ zmiana\ częstości\ allelu\ a\ (q)\ między\ pokoleniami,\ p\ –\ częstość\ allelu\ A,\ q\ -\ częstość\ allelu\ a,$$ $$W_s\ –\ średnie\ dostosowanie,\ w_{AA}\ –\ dostosowanie\ genotypu\ AA,\ w_{Aa}\ –\ dostosowanie\ genotypu\ Aa$$ $$w_{aa}\ –\ dostosowanie\ genotypu\ aa$$.

Z powyższych oznaczeń zagadkowe pozostaje średnie dostosowanie (Ws). Wyliczamy je ze wzoru:

$$W_s = p^2w_{AA}+2pqw_{Aa}+q^2w_{aa}$$

Oznaczenia jak wyżej

Frekwencja allelu w kolejnym pokoleniu będzie więc wynosić:

$$ q_i=q_{i-1} +\Delta q $$

Odpowiednie wartości dla drugiego allelu łatwo wyliczyć pamiętając, że p + q = 1.

W zależności od wprowadzonych wartości frekwencje alleli mogą się zachowywać w różny sposób. Może dojść do wyeliminowania jednego z alleli albo frekwencja może zmierzać do tego stanu, ale go nie osiągnąć, może też powstać stan równowagi.

Nieco szerzej temat jest omówiony w moich prezentacjach do kursu „Genetyka”, ale jeśli temat wydaje się interesujący, to z pewnością warto zajrzeć do bardziej fachowej literatury.

Zadanie

Napisać program, który prześledzi zmiany frekwencji alleli i genotypów oraz wartość dq w populacji w kolejnych pokoleniach. Użytkownik podaje wartości dostosowania poszczególnych genotypów, początkową frekwencją allelu a (frekwencja A powinna się wyliczyć) oraz maksymalną liczbę pokoleń.

Program ma obliczać (i drukować na ekranie) numer pokolenia, frekwencje alleli i genotypów w kolejnych pokoleniach aż frekwencja jednego z alleli osiągnie 0 (co oznacza, że został wyeliminowany) lub 1 (co oznacza, że drugi został wyeliminowany, a więc dalsze zmiany nie są możliwe) lub liczba pokoleń osiągnie wartość dopuszczoną przez użytkownika, lub wystąpi stan równowagi (brak zmian frekwencji alleli w kolejnych pokoleniach).

Działanie programu można skonfrontować np. z wynikami uzyskanymi w programie populus. W tym celu wybierz z menu: Model -> Quantative-Genetic Models: -> Population & Quantative Genetics, wpisz odpowiednie dane i porównaj wyniki.

Przykładowe rozwiązanie

Last updated on 7 Nov 2020
Published on 7 Nov 2020