227 lines
8.7 KiB
TeX
227 lines
8.7 KiB
TeX
\documentclass[11pt, a4paper]{article}
|
|
|
|
% Préambule : packages utiles
|
|
\usepackage[utf8]{inputenc}
|
|
\usepackage[T1]{fontenc}
|
|
\usepackage[french]{babel}
|
|
\usepackage{graphicx}
|
|
\usepackage{amsmath}
|
|
\usepackage[a4paper, margin=2cm]{geometry}
|
|
\usepackage[table]{xcolor}
|
|
\usepackage{listings}
|
|
\usepackage{hyperref} % hyperref se charge en dernier
|
|
|
|
\graphicspath{ {./images/} }
|
|
|
|
\definecolor{codebg}{HTML}{F6F8FA}
|
|
\definecolor{codeframe}{HTML}{D0D7DE}
|
|
\definecolor{kw}{HTML}{CF222E} % mots-clés C
|
|
\definecolor{tp}{HTML}{0550AE} % types
|
|
\definecolor{str}{HTML}{0A3069} % chaînes
|
|
\definecolor{cmt}{HTML}{6E7781} % commentaires
|
|
\definecolor{prep}{HTML}{8250DF} % préprocesseur
|
|
|
|
\lstset{
|
|
language=C,
|
|
basicstyle=\ttfamily\small,
|
|
keywordstyle=\color{kw}\bfseries,
|
|
commentstyle=\color{cmt}\itshape,
|
|
stringstyle=\color{str},
|
|
backgroundcolor=\color{codebg},
|
|
frame=single,
|
|
rulecolor=\color{codeframe},
|
|
numbers=left,
|
|
numberstyle=\tiny\color{cmt},
|
|
numbersep=8pt,
|
|
breaklines=true,
|
|
showstringspaces=false,
|
|
tabsize=4,
|
|
captionpos=b,
|
|
% types et fonctions courantes du C
|
|
morekeywords={size_t, uint8_t, uint32_t, uint64_t, NULL,
|
|
malloc, free, printf, rand, srand,
|
|
sqrt, log, cos, sin, M_PI},
|
|
% directives du préprocesseur (le # reste gris, le mot est coloré)
|
|
emph={include, define, ifndef, ifdef, endif, pragma},
|
|
emphstyle=\color{prep}\bfseries
|
|
}
|
|
|
|
\title{Simulation de population de lapins \\ « Rabbit Hole »}
|
|
\author{Aubin DORIVAL \\ F2 -- Promo 28}
|
|
\date{\today}
|
|
|
|
\begin{document}
|
|
\maketitle
|
|
|
|
\begin{center}
|
|
\url{https://git.dukantic.fr/dukantic/Rabbit-s-Hole}\\[0.5cm]
|
|
\includegraphics[width=0.7\textwidth]{draw_rabbit.jpg}
|
|
\end{center}
|
|
|
|
\section{Introduction}
|
|
Le projet « Rabbit Hole » est une simulation de population de lapins.
|
|
Elle vise à simuler la croissance de cette population en suivant certaines
|
|
règles, tout en faisant abstraction d'autres paramètres. Tout au long du
|
|
projet, j'ai globalement conservé les conditions et les probabilités
|
|
fournies dans le sujet.
|
|
|
|
\section{Règles}
|
|
Tout d'abord, il faut définir les règles à suivre.
|
|
|
|
\begin{itemize}
|
|
\item taux de gestation de $50\%$ par mois ;
|
|
\item $3$ à $6$ bébés par gestation, répartis de manière uniforme ;
|
|
\item les bébés deviennent adultes entre le 5\ieme{} et le 8\ieme{} mois ;
|
|
\item les adultes meurent avec un taux de $40\%$ par an, auquel s'ajoute
|
|
$10\%$ par an à partir de 10 ans ;
|
|
\item les bébés meurent avec un taux de $65\%$ par an, soit environ
|
|
$5\%$ par mois pendant 7 mois en moyenne.
|
|
\end{itemize}
|
|
|
|
\begin{center}
|
|
\includegraphics[width=\textwidth]{rabbit's_rules.png}
|
|
\end{center}
|
|
|
|
\section{Structure de données}
|
|
Pour stocker les lapins, j'ai choisi de les classer par âge. En effet,
|
|
toutes les règles sont basées sur l'âge : il suffit donc de compter les
|
|
lapins par classe d'âge. Ma structure de données repose sur ce principe :
|
|
un tableau par sexe, dont l'indice correspond à l'âge, ainsi que le nombre
|
|
de lapines en gestation. Pour les bébés, j'ai exactement la même chose,
|
|
si ce n'est que l'indice représente le mois plutôt que l'année. Pour les
|
|
nombres, j'ai choisi un entier non signé de 128 bits (non disponible sur
|
|
toutes les plateformes) afin de limiter au maximum les dépassements
|
|
d'entier.
|
|
|
|
\begin{figure}[htbp]
|
|
\begin{lstlisting}[caption={Structure de données pour les lapins}, label={lst:struct}]
|
|
#define N_MATURE (16)
|
|
#define N_KITTEN (8)
|
|
|
|
typedef struct rabbit_hole_s {
|
|
__uint128_t male_mature[N_MATURE];
|
|
__uint128_t female_mature[N_MATURE];
|
|
__uint128_t female_litter;
|
|
__uint128_t kitten_male[N_KITTEN];
|
|
__uint128_t kitten_female[N_KITTEN];
|
|
} rabbit_hole_t;
|
|
\end{lstlisting}
|
|
\end{figure}
|
|
|
|
\section{Implémentation}
|
|
Pour la génération de nombres aléatoires, j'utilise le générateur
|
|
Mersenne Twister, associé à la méthode de Box-Muller. Dans un premier
|
|
temps, j'effectuais un tirage aléatoire pour chaque probabilité et pour
|
|
chaque lapin. Par exemple, pour la mort : pour chaque lapin, je tire un
|
|
nombre aléatoire et je décide s'il meurt ou s'il survit. Cette approche
|
|
était beaucoup trop lente : au bout de 9 à 10 ans simulés, les calculs
|
|
prenaient déjà trop de temps. Je me suis alors dit que toutes mes
|
|
probabilités suivaient des lois uniformes et que je pouvais donc les
|
|
approximer par des gaussiennes grâce à la méthode de Box-Muller.
|
|
Je n'utilise cette approximation que lorsque le nombre de lapins à
|
|
traiter dépasse 100.
|
|
|
|
\begin{figure}[htbp]
|
|
\centering
|
|
\begin{align*}
|
|
R_{n,1},\, R_{n,2} &\gets \text{nombres aléatoires} \\
|
|
X_1 &= \sqrt{-2 \ln R_{n,1}} \cdot \cos(2\pi R_{n,2}) \\
|
|
X_2 &= \sqrt{-2 \ln R_{n,1}} \cdot \sin(2\pi R_{n,2})
|
|
\end{align*}
|
|
\caption{Méthode de Box-Muller}
|
|
\label{fig:box-muller}
|
|
\end{figure}
|
|
|
|
La gaussienne générée par la méthode de Box-Muller est centrée en 0 et
|
|
réduite (écart type 1). Dans mon cas, j'ai besoin de la centrer sur le
|
|
nombre de lapins attendu. Pour cela, je calcule $\mu$, la moyenne de la
|
|
valeur attendue, ainsi que $\sigma$, l'écart type de la gaussienne.
|
|
|
|
\begin{figure}[htbp]
|
|
\centering
|
|
\begin{align*}
|
|
\text{Loi binomiale (survies, sexes) : } \mathcal{B}(n, p) \\
|
|
\mu_{\text{bin}} &= n \cdot p \\
|
|
\sigma_{\text{bin}} &= \sqrt{n \cdot p \cdot (1-p)} \\[4pt]
|
|
\text{Somme de $n$ lois uniformes (portées) : } \sum_{i=1}^{n} \mathcal{U}([a,b]) \\
|
|
\mu_{\text{unif}} &= n \cdot \frac{a+b}{2} \\
|
|
\sigma_{\text{unif}} &= \sqrt{\frac{n \cdot (b-a)^2}{12}} \\[4pt]
|
|
\text{Tirage Box-Muller : } X_0 \sim \mathcal{N}(0,1) \\
|
|
X_{\text{utilisable}} &= \mu + \sigma \cdot X_0
|
|
\;\sim\; \mathcal{N}(\mu, \sigma^2)
|
|
\end{align*}
|
|
\caption{Décalage de la gaussienne par Box-Muller}
|
|
\label{eq:decalage-gaussienne}
|
|
\end{figure}
|
|
|
|
\begin{figure}[htbp]
|
|
\begin{lstlisting}[caption={Code des naissances}, label={lst:naissance}]
|
|
if (rabbits->female_litter < 100) {
|
|
for (i = 0; i < rabbits->female_litter; i++) {
|
|
taille1 = 3 + (int)(4.0 * genrand_real2());
|
|
for (int k = 0; k < taille1; k++) {
|
|
if (genrand_real1() > 0.5) (*new_kitten_male)++;
|
|
else (*new_kitten_female)++;
|
|
}
|
|
|
|
}
|
|
}else {
|
|
ul_mu_k = 4.5*(double)rabbits->female_litter; // 4.5 = (b+a)/2
|
|
ul_sigma_k = sqrt(1.118 * (double)rabbits->female_litter); //(k*k-1)/12 = 1.118
|
|
gauss(x_gauss);
|
|
x_gauss[0] = CLAMP_BTW(x_gauss[0] * ul_sigma_k+ ul_mu_k, 0.0 , rabbits->female_litter * 9.0);
|
|
|
|
ul_mu_sex = x_gauss[0] * 0.5;
|
|
ul_sigma_sex = sqrt(ul_mu_sex * 0.5);
|
|
x_gauss[1] = CLAMP_BTW(x_gauss[1] * ul_sigma_sex + ul_mu_sex , 0.0, rabbits->female_litter * 9.0);
|
|
|
|
(*new_kitten_female) = (__uint128_t)roundl(x_gauss[1]) ;
|
|
(*new_kitten_male) = (__uint128_t)roundl(x_gauss[0] - x_gauss[1]);
|
|
}
|
|
\end{lstlisting}
|
|
\end{figure}
|
|
|
|
\section{Statistiques}
|
|
\subsection{Régles}
|
|
Pour collecter les statistiques, j'écris sur la sortie d'erreur (stderr)
|
|
au format CSV, puis je redirige cette sortie vers un fichier afin de
|
|
l'exploiter. J'inscris une nouvelle ligne chaque mois, contenant
|
|
l'ensemble des nombres de ma structure. Pour afficher les nombres en
|
|
\verb|__uint128_t|, il n'existe pas de format d'affichage par défaut,
|
|
contrairement à \verb|uint64_t| par exemple (\verb|%llu|) : il a donc
|
|
fallu réaliser un formatage manuel. Les graphiques obtenus permettent de
|
|
vérifier que les règles posées au départ sont bien respectées. J'ai pris, pour
|
|
commencer, 10 lapins mâles et 10 lapines, pour être sûr qu'ils grandissent.
|
|
|
|
\begin{figure}[htbp]
|
|
\centering
|
|
\includegraphics[width=0.45\textwidth]{population_total}
|
|
\includegraphics[width=0.45\textwidth]{regle1_gestation}
|
|
\includegraphics[width=0.45\textwidth]{regle2_distribution}
|
|
\includegraphics[width=0.45\textwidth]{regle2_portees}
|
|
\includegraphics[width=0.45\textwidth]{regle3_maturation}
|
|
\includegraphics[width=0.45\textwidth]{regle4_mortalite_adultes}
|
|
\includegraphics[width=0.45\textwidth]{regle5_survie_kittens}
|
|
\caption{Vérification graphique des règles}
|
|
\label{fig:regles}
|
|
\end{figure}
|
|
|
|
\subsection{Taux de commencement}
|
|
|
|
En prenant un seul couple il y a une possibilité de mort trop tôt et que la
|
|
reaction en chaine ne ce fasse pas. J'ai donc essayer de lancer plusieur fois
|
|
pour avoir le taux de fois ou on arrive a lancer la simulation a partir d'un couple.
|
|
Le taux optenu est du coup de $92\%$ donc $8\%$ des simulations ne sont
|
|
pas pertinante.
|
|
|
|
\section{Utilisation de l'IA}
|
|
Pendant ce TP, l'IA a été utilisée pour :
|
|
\begin{itemize}
|
|
\item réaliser les graphiques (Python, avec NumPy et Matplotlib) ;
|
|
\item vérifier la cohérence des valeurs retournées par la simulation ;
|
|
\item m'aider à rédiger ce rapport (LaTeX, correction d'erreurs et de
|
|
formulations en français).
|
|
\end{itemize}
|
|
Pour le reste du TP, aucune utilisation n'a été faite.
|
|
|
|
\end{document} |