mikusp / gines

GINES is not epidemic simulation
GNU General Public License v3.0
0 stars 0 forks source link

Algorithm overview RFC #1

Open mikusp opened 10 years ago

mikusp commented 10 years ago

Myślałem trochę o różnych funkcjach jakie będą potrzebne przy symulacji i chciałbym omówić czy wydają się OK na chwilę obecną.

Po pierwsze, najbardziej "główna" funkcja powinna przekształcać stan świata w nowy stan (będę pisał notacją Haskellową).

step :: WorldState -> IO WorldState

Ta funkcja musiałaby załatwiać: infekcję, przesunięcie kwantu dnia/numeru dnia i jakąś interakcję z interfejsem, np. wysłanie zmian/nowego stanu jako JSON (obecnie nie jest to zbyt ważne).

data WorldState = {
      day :: Int -- tutaj mogłoby być liczby naturalne + 0 jeśli jest taki typ dostępny
    , dayChunk :: Chunk -- obecny kwant dnia
    , agents :: [Agent]
    , world :: Map (Int, Int) Cell -- mapa ze współrzędnymi jako kluczem, zapewnia traversable i jednocześnie wybór konkretnej komórki w O(log n)
    }
data Age = Child | Teenager | Adult | Elderly

Obecnie mamy trzy grupy wiekowe, może warto zastanowić się nad dodaniem nastolatków jak w pracy Porzyckiego.

data Health = Healthy | Incubating Int | Ill Int | Immune Int | Vaccinated Int

Tutaj podobnie, obecnie uwzględniamy tylko zdrowy/chory/odporny, warto też uzależnić te fazy od liczby dni spędzonych w każdej z nich. Wtedy wiadomo kiedy należy przestawić stan agenta na kolejny. Mogłoby się tutaj znaleźć też zabezpieczenie na poziomie typu, żeby np. nie dało się stworzyć obiektu Incubating 15 jeśli założymy że choroba rozwija się co najwyżej 14 dni.

type Routine = [Behaviour]
data Behaviour = Behaviour Chunk Cell

Rutyna to nieskończona lista zachowań, z zawsze prawdziwym założeniem, że kolejne fazy dnia są w niej po kolei i nie da się stworzyć listy łamiącej to prawo (jeśli będzie to możliwe do implementacji). W ten sposób przy zwykłym wyrzuceniu headów przy każdej iteracji lista sama będzie się tworzyć, a jednocześnie będzie możliwa tymczasowa zmiana zachowania, np. podmieniając drugie zachowanie na jakieś inne. Wtedy będzie to jednorazowa zmiana codziennej rutyny. Oprócz tego, każde zachowanie wiąże konkretny kwant dnia i komórkę, gdzie będzie się odbywać dane zachowanie. Dalej nie wiem czy zezwalamy na teleportację pomiędzy dalekimi komórkami ale nie widzę innej możliwości.

data Agent = {
      age :: Age
    , health :: Health
    , routine :: Routine
    , cell :: Cell
    }

Wreszcie sam agent, wydaje mi się że jest oczywiste co zawiera.

data CellType = School | Work | House -- coś jeszcze?
data Cell = {
      agents :: [Agent]
    -- nie wiem co jeszcze może być potrzebne
    }

Na koniec typ komórki - nie wiem czy uznamy że wszystko ze sobą graniczy i nie uwzględniamy dróg, chodników, itp.? Do tego, co powinna mieć każda komórka oprócz listy agentów obecnie się w niej znajdujących?

Masz jakieś pomysły na poprawę/uwagi? Jak widziałbyś kwestię algorytmu zarażania, bo chyba to będzie obecnie najważniejsze?

bkowalik commented 10 years ago

Wydaje mi się, że na początek możemy przyjąć uproszczony model, że nie uwzględniamy chodników itp. Jednak te graniczne komórki sprawdzałbym tylko z komórkami tego samego typu przez co eliminowałbym nielegalne interakcje np komórka mieszkalna <--> komórka pracownicza w kwancie dnia praca.

Jeżeli chodzi o implementację nieskończonych list to jest w Scali leniwy strumień, który powinien spełnić oczekiwania rutyny: http://scala-lang.org/api/current/#scala.collection.immutable.Stream

Jeżeli chodzi o mechanizm zarażania to trzeba by się nad tym zastanowić grubiej i ze 2, 3 koncepcje obgadać bo może uda się taką abstrakcję osiągnąć, że będą wymienialne.

mikusp commented 10 years ago

Kilka zmian:

mikusp commented 10 years ago

Zmiany: