asymptote-config/gm_probabilitytree.asy
2018-08-15 17:17:01 +02:00

148 lines
4.4 KiB
Plaintext

/*
AVERTISSEMENT du 05/02/11 :
après près de deux ans d'utilisation, je songe à revopir
en profondeur cette extension(ette) pour en faire
une vraie extension avec davantage de possibilités.
Tout est susceptible de changer !
*/
// probabilitytree.asy - v. 1.1 - 19/04/09
// Extension destinée à dessiner un arbre de probabilités
// C'est une première version, non documentée, en phase de test.
// G. Marris
real DistVertEntreNoeuds = .5cm;
real DistHoriEntreNiveaux = 2cm;
real HauteurNoeudMinimale = .5cm;
pen StyleEvenParDefaut = 1bp+black;
pen StyleBackGrParDefaut = invisible;
pen StyleProbParDefaut = black;
pen StyleBrParDefaut = black;
struct Noeud {Noeud parent;
Noeud[] enfants;
Label evenement;
Label probabilite;
pen coul_pr;
pen coul_br;
pair lieu;
frame cadre;
real decalage_y;
}
Noeud addN( Noeud parent = null,
Label evenement = "",
pen[] evpen={StyleEvenParDefaut,StyleBackGrParDefaut},
Label probabilite = null,
pen prpen=StyleProbParDefaut,
pen brpen=StyleBrParDefaut)
{
frame fr;
Noeud nouvelenfant = new Noeud;
if (evpen.length==1) evpen[1]=StyleBackGrParDefaut;
label(fr,evenement,evpen[0]);
roundbox(fr,
xmargin=1mm,
Fill(evpen[1]));
nouvelenfant.cadre = fr;
nouvelenfant.probabilite = probabilite;
nouvelenfant.coul_pr = prpen;
nouvelenfant.coul_br = brpen;
if( parent != null ) {
nouvelenfant.parent = parent;
parent.enfants.push( nouvelenfant );
}
return nouvelenfant;
}
real CalculHauteur( int niveau, Noeud noeud )
{
real hauteurcadrenoeud=(max(noeud.cadre)-min(noeud.cadre)).y;
if( noeud.enfants.length > 0 ) {
real hauteur[] = new real[noeud.enfants.length];
real H = 0;
for( int i = 0; i < noeud.enfants.length; ++i ) {
hauteur[i] = CalculHauteur(niveau+1, noeud.enfants[i] );
noeud.enfants[i].lieu =(niveau*DistHoriEntreNiveaux, H-hauteur[i]/2);
H -= hauteur[i]+DistVertEntreNoeuds;
}
real hauteurramifications = (sum(hauteur)
+DistVertEntreNoeuds*(hauteur.length-1));
for( int i = 0; i < noeud.enfants.length; ++i ) {
noeud.enfants[i].decalage_y = hauteurramifications/2;
}
return max(hauteurcadrenoeud,sum(hauteur)
+DistVertEntreNoeuds*(hauteur.length-1));
}
else {
return max(hauteurcadrenoeud,HauteurNoeudMinimale);
}
}
void TracerRecursivement( Noeud noeud, frame f )
{
pair pos;
if( noeud.parent != null )
pos = (0, noeud.parent.lieu.y + noeud.decalage_y);
else
pos = (0, noeud.decalage_y);
noeud.lieu += pos;
noeud.cadre = shift(noeud.lieu)*noeud.cadre;
if( noeud.parent != null ) {
pair dirtrait=noeud.parent.lieu-noeud.lieu;
path p = point(noeud.cadre,dirtrait)--point(noeud.parent.cadre,E);
draw(f,p,noeud.coul_br);
if( noeud.probabilite != null ) {
label(f,scale(.9)*noeud.probabilite,
relpoint(p,.3),noeud.coul_pr,Fill(1,white));
}
}
add( f, noeud.cadre );
for( int i = 0; i < noeud.enfants.length; ++i )
TracerRecursivement( noeud.enfants[i], f );
}
void TracerArbre( Noeud racine, pair pos=(0,0) )
{
frame f;
racine.lieu = (0,0);
CalculHauteur( 1, racine );
TracerRecursivement( racine, f );
add(f,pos);
}
void Bernouilli( Label Succes="$S$", Label probS="$p$",
Label Echec="$\overline{S}$", Label probE="$q$",
int repet=2, pair pos=(0,0) )
{
int n = 2^repet-1, j;
Noeud[] N;
N[0] = addN( );
for (int i=1; i<=2*n; i+=2) {
j=floor((i-1)/2);
N[i] = addN( N[j], Succes, probS );
N[i+1] = addN( N[j], Echec, probE );
}
TracerArbre( N[0], pos );
}
void GagnerAToutPrix( Label Succes="$G$", Label probS="$\frac{1}{2}$",
Label Echec="$P$", Label probE="$\frac{1}{2}$",
int repet=4, pair pos=(0,0) )
{
int n = 2*repet;
Noeud[] N;
N[0] = addN( );
for (int i=0; i<=repet; ++i) {
N[2*i+1] = addN( N[2*i], Succes, probS );
N[2*i+2] = addN( N[2*i], Echec, probE );
}
TracerArbre( N[0], pos );
}
pair operator cast(Noeud P)
{
return P.lieu;
}