On veut étudier le caractère grégaire de plusieurs espèces.
Une espèce est grégaire si les individus ont tendance à se rapprocher les uns des autres. Dans le cas contraire, on dira que les individus ont une tendance solitaire.
Protocole de l’expérience
Deux individus d’une espèce sont placés dans un espace qui peut prendre diverses formes et peuvent se déplacer dans cet espace.
Un appareil relié à un ordinateur détermine à intervalle régulier la position de chacun des individus et calcule la distance entre eux.
Au bout d’un moment l’expérience s’arrête et l’ordinateur calcule la moyenne des distances recueillies.
Expériences
Chevaux
On place deux chevaux dans un pré carré de côté 20 mètres.
La distance moyenne entre eux est de 4 mètres.
Est-ce supérieur ou inférieur à la moyenne obtenue par des positions aléatoires indépendantes des chevaux ?
Les chevaux ont-ils une tendance grégaire ?
On répète l’expérience avec deux vieux chevaux et on obtient une moyenne de 6,3 mètres. Conclusion ?
[accordions id= »3375″]
Éléments attendus
Algorithme
somme←0
Pour n de 1 à 10000 :
yA←au hasard de 0 à 20
xB←au hasard de 0 à 20
yB←au hasard de 0 à 20
somme←somme+distance de A à B
moyenne←somme/10000
En langage Pythonimport random import math n=10000 #nombre d'experiences cote=20 #longueur du cote du carre somme=0 # pour calculer la moyenne for i in range(0,n) : #premier cheval xA=random.random()*cote #entre 0 et 20 yA=random.random()*cote #deuxieme cheval xB=random.random()*cote yB=random.random()*cote # distance=math.sqrt((xB-xA)*(xB-xA)+(yB-yA)*(yB-yA)) somme=somme+distance print("Moyenne : "+str(somme/n)) |
En langage Python avec le module graphique Tkinterimport random import math from Tkinter import * canvas = Canvas(width=400, height=400, bg='white') #image : 400x400 canvas.pack(expand=YES, fill=BOTH) n=200 #nombre d'experiences cote=20 #longueur du cote du carre somme=0 # pour calculer la moyenne for i in range(0,n) : #premier cheval xA=random.random()*cote #entre 0 et 20 yA=random.random()*cote #deuxieme cheval xB=random.random()*cote yB=random.random()*cote # canvas.create_line(20*xA,20*yA,20*xB,20*yB) #echelle x20 distance=math.sqrt((xB-xA)*(xB-xA)+(yB-yA)*(yB-yA)) somme=somme+distance print("Moyenne : "+str(somme/n)) mainloop() |
[/spoiler]
Blattes
Lorsqu’on place deux blattes dans une boite circulaire plate de rayon 10 cm, la moyenne des distances entre elles est d’environ 3,5 cm. Les blattes ont-elles une tendance grégaire ?
[accordions id= »3380″]
Éléments attendus
Algorithme (haut niveau)
somme←0
Pour n de 1 à 10000 :
Choisir les coordonnées de B dans le cercle de centre (0,0) et de rayon 10 cm.
Calculer la longueur AB et l’ajouter à somme
FinPour
moyenne←somme/10000
L’écriture de cet algorithme permet de s’affranchir des difficultés techniques telle celle qui permet de s’assurer que les points choisis au hasard sont bien dans le cercle voulu.
On pourra pour cela :
- Prendre les coordonnées dans un carré de côté 20 cm et faire passer un test pour s’assurer que le point est aussi dans le cercle.
- Utiliser les coordonnées polaires.
Algorithme (bas niveau avec test de présence dans le cercle voulu)somme←0 Répéter xA←au hazard de -10 à 10
yA←au hazard de -10 à 10 Jusqu’à ce que xA²+yA²≤10² xB←au hazard de -10 à 10
yB←au hazard de -10 à 10 Jusqu’à ce que xB²+yB²≤10² FinPour Moyenne←somme/10000 En langage Pythonimport random import math n=10000 #nombre d'experiences somme=0 #pour calculer la moyenne #En python, il n'y a pas de boucle du type repeter...jusqu'a ce que... #Alors il faut ruser : on place les points en dehors du cercle pour #etre sur de rentrer dans la boucle faire...tant que... (boucle while) for i in range(0,n) : #premier insecte xA=10;yA=10 #En dehors du cercle ! while ((xA*xA+yA*yA)>100) : xA=random.uniform(-10,10) # entre -10 et 10 avec loi uniforme yA=random.uniform(-10,10) #deuxieme insecte xB=10;yB=10 while ((xB*xB+yB*yB)>100) : xB=random.uniform(-10,10) # entre -10 et 10 avec loi uniforme yB=random.uniform(-10,10) distance=math.sqrt((xB-xA)*(xB-xA)+(yB-yA)*(yB-yA)) somme=somme+distance print("Moyenne : "+str(somme/n)) |
En langage Python avec le module graphique Tkinterimport random import math from Tkinter import * canvas = Canvas(width=400, height=400, bg='white') canvas.pack(expand=YES, fill=BOTH) n=500 somme=0 for i in range(0,n) : #premier insecte xA=10;yA=10 #En dehors du cercle ! while ((xA*xA+yA*yA)>100) : xA=random.uniform(-10,10) yA=random.uniform(-10,10) #deuxieme insecte xB=10;yB=10 while ((xB*xB+yB*yB)>100) : xB=random.uniform(-10,10) yB=random.uniform(-10,10) canvas.create_line(200+20*xA,200+20*yA,200+20*xB,200+20*yB) distance=math.sqrt((xB-xA)*(xB-xA)+(yB-yA)*(yB-yA)) somme=somme+distance print("Moyenne : "+str(somme/n)) mainloop() |
Algorithme (bas niveau avec coordonnées polaires – Version naïve)
somme←0 Pour n de 1 à 10000 : angleA←au hasard de 0 à 2π
rayonA←au hasard de 0 à 10 xA←rayonA×cos(angleA) yA←rayonA×sin(angleA) angleB←au hasard de 0 à 2π rayonB←au hasard de 0 à 10 xB←rayonB×cos(angleB) yB←rayonB×sin(angleB) somme←racine((xB-xA)²+(yB-yA)²) FinPour Moyenne←somme/10000 En langage Pythonimport random import math n=10000 rayon=10 somme=0 for i in range(0,n) : #premier insecte angleA=random.random()*2*math.pi #random() : entre 0 et 1 rayonA=random.random()*rayon xA=rayonA*math.cos(angleA) yA=rayonA*math.sin(angleA) #deuxieme insecte angleB=random.random()*2*math.pi rayonB=random.random()*rayon xB=rayonB*math.cos(angleB) yB=rayonB*math.sin(angleB) # distance=math.sqrt((xB-xA)*(xB-xA)+(yB-yA)*(yB-yA)) somme=somme+distance print("Moyenne : "+str(somme/n)) |
En langage Python avec le module graphique Tkinterimport random import math from Tkinter import * canvas = Canvas(width=400, height=400, bg='white') canvas.pack(expand=YES, fill=BOTH) n=500 rayon=10 somme=0 for i in range(0,n) : #premier insecte angleA=random.random()*2*math.pi #random() : entre 0 et 1 rayonA=random.random()*rayon xA=rayonA*math.cos(angleA) yA=rayonA*math.sin(angleA) #deuxieme insecte angleB=random.random()*2*math.pi rayonB=random.random()*rayon xB=rayonB*math.cos(angleB) yB=rayonB*math.sin(angleB) # canvas.create_line(200+20*xA,200+20*yA,200+20*xB,200+20*yB) distance=math.sqrt((xB-xA)*(xB-xA)+(yB-yA)*(yB-yA)) somme=somme+distance print("Moyenne : "+str(somme/n)) mainloop() |
Avec cette version, un problème apparaît : les deux algorithmes ne donnent pas les mêmes résultats. Une discussion peut être engagée pour en déterminer la cause : choisir un point dans le carré et vérifier après coup s’il est dans le cercle est-il équivalent à choisir directement un point dans le cercle ? Ou bien est-ce un problème avec l’utilisation des coordonnées polaires ?
En mettant côte à côte les deux dessins obtenus, la solution apparaît :
|
|
Dans l’algorithme avec les coordonnées polaires, les points vers le centre du cercle sont sur-représentés. Cela vient du fait qu’en prenant un point au hasard dans le cercle, la distance au centre du cercle ne suit pas une loi uniforme.
La probabilité de présence dans un disque dépend de l’aire de ce disque, elle-même étant fonction du carré de son rayon.
Une solution est de redresser le choix de la distance au centre.
Pour cela, on peut choisir le rayon selon la racine carrée d’une loi uniforme. (Voir des explications)
On obtient l’algorithme suivant :
Algorithme (bas niveau avec coordonnées polaires – Version corrigée)
somme←0
Pour n de 1 à 10000 :
rayonA←racine(au hasard de 0 à 1) x 10
xA←rayonA×cos(angleA)
yA←rayonA×sin(angleA)
angleB←au hasard de 0 à 2π
rayonB←racine(au hasard de 0 à 1) x 10
xB←rayonB×cos(angleB)
yB←rayonB×sin(angleB)
somme←racine((xB-xA)²+(yB-yA)²)
FinPour
Moyenne←somme/10000
En langage Python
import random import math n=10000 rayon=10 somme=0 for i in range(0,n) : #premier insecte angleA=random.random()*2*math.pi rayonA=math.sqrt(random.random())*rayon #redressement xA=rayonA*math.cos(angleA) yA=rayonA*math.sin(angleA) #deuxieme insecte angleB=random.random()*2*math.pi rayonB=math.sqrt(random.random())*rayon #redressement xB=rayonB*math.cos(angleB) yB=rayonB*math.sin(angleB) # distance=math.sqrt((xB-xA)*(xB-xA)+(yB-yA)*(yB-yA)) somme=somme+distance print("Moyenne : "+str(somme/n))
Complément pour le professeur : une autre démarche possible
Plutôt que de retirer les coordonnées de façon aléatoire à chaque fois, on simule une marche aléatoire : on part de la position précédente et on se déplace dans une direction aléatoire d’une distance donnée.
import random import math from Tkinter import * canvas = Canvas(width=400, height=400, bg='white') canvas.pack(expand=YES, fill=BOTH) n=3000 somme=0 #premier insecte : choix du depart xA=10;yA=10 #En dehors du cercle ! while ((xA*xA+yA*yA)>100) : xA=random.uniform(-10,10) # entre -10 et 10 yA=random.uniform(-10,10) #deuxieme insecte : choix du depart xB=10;yB=10 while ((xB*xB+yB*yB)>100) : xB=random.uniform(-10,10) # entre -10 et 10 yB=random.uniform(-10,10) for i in range (0,n) : #On stoque les coordonnees oldxA=xA;oldyA=yA;oldxB=xB;oldyB=yB angleA=random.random()*2*math.pi #angle de deplacement xA=xA+.5*math.cos(angleA) #deplacement yA=yA+.5*math.sin(angleA) if (xA*xA+yA*yA>100) : #si on sort du cercle... norme=math.sqrt(xA*xA+yA*yA) #alors on se replace au bord xA=xA*10/norme yA=yA*10/norme angleB=random.random()*2*math.pi xB=xB+.5*math.cos(angleB) yB=yB+.5*math.sin(angleB) if (xB*xB+yB*yB>100) : norme=math.sqrt(xB*xB+yB*yB) xB=xB*10/norme yB=yB*10/norme canvas.create_line(200+20*xA,200+20*yA,200+20*oldxA,200+20*oldyA,fill="red") canvas.create_line(200+20*xB,200+20*yB,200+20*oldxB,200+20*oldyB,fill="blue") distance=math.sqrt((xB-xA)*(xB-xA)+(yB-yA)*(yB-yA)) somme=somme+distance print("Moyenne : "+str(somme/n)) mainloop() |
On peut modifier le comportement des insectes pour instaurer le grégarisme de la façon suivante : lorsqu’un déplacement tend à s’éloigner du congénère, le déplacement est moindre (de 20% dans l’exemple ci-dessous)
import random import math from Tkinter import * canvas = Canvas(width=400, height=400, bg='white') canvas.pack(expand=YES, fill=BOTH) n=3000 somme=0 #premier insecte xA=10;yA=10 #En dehors du cercle ! while ((xA*xA+yA*yA)>100) : xA=random.uniform(-10,10) # entre -10 et 10 avec une loi uniforme yA=random.uniform(-10,10) #deuxieme insecte xB=10;yB=10 while ((xB*xB+yB*yB)>100) : xB=random.uniform(-10,10) # entre -10 et 10 avec une loi uniforme yB=random.uniform(-10,10) for i in range (0,n) : oldxA=xA;oldyA=yA;oldxB=xB;oldyB=yB angleA=random.random()*2*math.pi xA=xA+.5*math.cos(angleA) yA=yA+.5*math.sin(angleA) #teste si le deplacement eloigne les points if ((xB-xA)**2+(yB-yA)**2>(xB-oldxA)**2+(yB-oldyA)**2) : xA=oldxA+.4*math.cos(angleA) #dans ce cas, le deplacement yA=oldyA+.4*math.sin(angleA) #est moindre if (xA*xA+yA*yA>100) : norme=math.sqrt(xA*xA+yA*yA) xA=xA*10/norme yA=yA*10/norme angleB=random.random()*2*math.pi xB=xB+.5*math.cos(angleB) yB=yB+.5*math.sin(angleB) if ((xB-xA)**2+(yB-yA)**2>(oldxB-xA)**2+(oldyB-yA)**2) : xB=oldxB+.4*math.cos(angleB) yB=oldyB+.4*math.sin(angleB) if (xB*xB+yB*yB>100) : norme=math.sqrt(xB*xB+yB*yB) xB=xB*10/norme yB=yB*10/norme canvas.create_line(200+20*xA,200+20*yA,200+20*oldxA,200+20*oldyA,fill="red") canvas.create_line(200+20*xB,200+20*yB,200+20*oldxB,200+20*oldyB,fill="blue") distance=math.sqrt((xB-xA)*(xB-xA)+(yB-yA)*(yB-yA)) somme=somme+distance print("Moyenne : "+str(somme/n)) mainloop() |
En modifiant les paramètres, on peut simuler une tendance à l’éloignement (pour un éloignement, on augmente la distance de déplacement de 20%) :
[/spoiler]
Plusieurs situations
Espèce | Description du champ d’expérimentation | distance moyenne mesurée et calculée |
Scarabée | Fond d’une boite de forme circulaire de rayon 15 cm | 9,5 cm |
Caméléon | Fond d’une boite de forme rectangulaire de dimensions 1 m par 60 cm | 105 cm |
Humain | 10 sièges alignés dans une salle d’attente | 3 chaises vides d’écart |
Crevette | Aquarium de dimensions 80 cm par 80 cm par 60 cm | 25 cm |
En classe
Objectifs
Seconde : Distance entre deux points du plan.
Terminale : Module et argument d’un nombre complexe et son interprétation géométrique ; notion de loi de densité
Documents
Déroulement possible en classe (à adapter selon les besoins, les objectifs) : document élève (fichier source LaTeX et ses annexes) ; fichier d’exemple (chevaux)
Travaux d’élèves
Discussion sur le nombre d’expériences :
Distance entre deux points :
Changement de modèle (un élève se demande si le modèle présenté est équivalent à celui avec 3 chevaux) :