# colonne 1 : age # colonne 2 : nombre d'hommes en vie a cet age depuis la naissance # colonne 3 : nombre de femmes en vie a cet age depuis la naissance # colonne 4 : nombre de gens en vie a cet age depuis la naissance mortalite = [\ [ 0 , 100000 , 100000 , 100000 ], \ [ 1 , 99571 , 99658 , 99613 ], \ [ 2 , 99537 , 99631 , 99583 ], \ [ 3 , 99514 , 99613 , 99562 ], \ [ 4 , 99495 , 99599 , 99546 ], \ [ 5 , 99479 , 99587 , 99532 ], \ [ 6 , 99465 , 99577 , 99520 ], \ [ 7 , 99453 , 99567 , 99509 ], \ [ 8 , 99442 , 99558 , 99499 ], \ [ 9 , 99433 , 99550 , 99490 ], \ [ 10 , 99422 , 99543 , 99481 ], \ [ 11 , 99411 , 99535 , 99472 ], \ [ 12 , 99400 , 99527 , 99462 ], \ [ 13 , 99387 , 99518 , 99451 ], \ [ 14 , 99371 , 99507 , 99437 ], \ [ 15 , 99350 , 99495 , 99421 ], \ [ 16 , 99320 , 99480 , 99398 ], \ [ 17 , 99280 , 99461 , 99368 ], \ [ 18 , 99227 , 99438 , 99330 ], \ [ 19 , 99157 , 99410 , 99281 ], \ [ 20 , 99076 , 99382 , 99225 ], \ [ 21 , 98989 , 99353 , 99167 ], \ [ 22 , 98899 , 99324 , 99106 ], \ [ 23 , 98808 , 99295 , 99046 ], \ [ 24 , 98718 , 99267 , 98986 ], \ [ 25 , 98632 , 99239 , 98928 ], \ [ 26 , 98545 , 99212 , 98871 ], \ [ 27 , 98455 , 99180 , 98809 ], \ [ 28 , 98367 , 99148 , 98748 ], \ [ 29 , 98279 , 99116 , 98687 ], \ [ 30 , 98187 , 99080 , 98623 ], \ [ 31 , 98085 , 99039 , 98551 ], \ [ 32 , 97979 , 98998 , 98476 ], \ [ 33 , 97871 , 98951 , 98398 ], \ [ 34 , 97756 , 98899 , 98314 ], \ [ 35 , 97633 , 98846 , 98225 ], \ [ 36 , 97500 , 98783 , 98126 ], \ [ 37 , 97355 , 98716 , 98020 ], \ [ 38 , 97201 , 98642 , 97905 ], \ [ 39 , 97033 , 98558 , 97777 ], \ [ 40 , 96849 , 98464 , 97637 ], \ [ 41 , 96645 , 98363 , 97483 ], \ [ 42 , 96427 , 98249 , 97316 ], \ [ 43 , 96186 , 98128 , 97134 ], \ [ 44 , 95912 , 97987 , 96924 ], \ [ 45 , 95606 , 97837 , 96695 ], \ [ 46 , 95272 , 97675 , 96445 ], \ [ 47 , 94901 , 97493 , 96166 ], \ [ 48 , 94483 , 97295 , 95855 ], \ [ 49 , 94024 , 97087 , 95518 ], \ [ 50 , 93532 , 96858 , 95155 ], \ [ 51 , 92993 , 96615 , 94760 ], \ [ 52 , 92428 , 96358 , 94346 ], \ [ 53 , 91835 , 96084 , 93909 ], \ [ 54 , 91201 , 95794 , 93442 ], \ [ 55 , 90533 , 95487 , 92950 ], \ [ 56 , 89824 , 95168 , 92432 ], \ [ 57 , 89070 , 94828 , 91880 ], \ [ 58 , 88266 , 94472 , 91295 ], \ [ 59 , 87407 , 94086 , 90666 ], \ [ 60 , 86496 , 93667 , 89995 ], \ [ 61 , 85546 , 93226 , 89294 ], \ [ 62 , 84556 , 92766 , 88562 ], \ [ 63 , 83504 , 92272 , 87783 ], \ [ 64 , 82388 , 91749 , 86956 ], \ [ 65 , 81202 , 91188 , 86075 ], \ [ 66 , 79938 , 90587 , 85135 ], \ [ 67 , 78599 , 89936 , 84131 ], \ [ 68 , 77184 , 89236 , 83065 ], \ [ 69 , 75653 , 88467 , 81906 ], \ [ 70 , 74012 , 87633 , 80659 ], \ [ 71 , 72245 , 86710 , 79304 ], \ [ 72 , 70350 , 85692 , 77837 ], \ [ 73 , 68317 , 84567 , 76247 ], \ [ 74 , 66155 , 83344 , 74543 ], \ [ 75 , 63859 , 81995 , 72709 ], \ [ 76 , 61404 , 80490 , 70718 ], \ [ 77 , 58802 , 78823 , 68572 ], \ [ 78 , 56060 , 76968 , 66263 ], \ [ 79 , 53165 , 74899 , 63771 ], \ [ 80 , 50171 , 72622 , 61127 ], \ [ 81 , 47013 , 70078 , 58269 ], \ [ 82 , 43733 , 67275 , 55222 ], \ [ 83 , 40329 , 64168 , 51963 ], \ [ 84 , 36830 , 60763 , 48509 ], \ [ 85 , 33321 , 57061 , 44906 ], \ [ 86 , 29785 , 53099 , 41162 ], \ [ 87 , 26244 , 48845 , 37273 ], \ [ 88 , 22775 , 44371 , 33314 ], \ [ 89 , 19407 , 39804 , 29360 ], \ [ 90 , 16252 , 35111 , 25455 ], \ [ 91 , 13351 , 30448 , 21694 ], \ [ 92 , 10752 , 25917 , 18153 ], \ [ 93 , 8489 , 21596 , 14885 ], \ [ 94 , 6563 , 17564 , 11931 ], \ [ 95 , 4919 , 13959 , 9331 ], \ [ 96 , 3588 , 10756 , 7086 ], \ [ 97 , 2562 , 8079 , 5254 ], \ [ 98 , 1791 , 5918 , 3805 ], \ [ 99 , 1254 , 4245 , 2714 ], \ [ 100 , 879 , 3014 , 1921 ], \ [ 101 , 628 , 2110 , 1351 ], \ [ 102 , 467 , 1482 , 962 ], \ [ 103 , 375 , 1056 , 707 ], \ [ 104 , 279 , 752 , 510 ], \ ] class Population : def __init__ (self, mortalite) : self.mortalite = mortalite def proba_vie_sup (self, age_vie, age_mort) : nb1 = self.mortalite [age_vie][3] if age_mort < len (mortalite) : nb2 = self.mortalite [age_mort][3] else : nb2 = 0 return float (nb2) / float (nb1) def proba_mortalite_sexuee (self, age_vie, age_mort, indice) : nb1 = self.mortalite [age_vie][indice] if age_mort < len (mortalite) : nb2 = self.mortalite [age_mort][indice] else : nb2 = 0 return 1.0 - float (nb2) / float (nb1) def proba_mort_egale (self, age_vie, age_mort) : p1 = self.proba_vie_sup (age_vie, age_mort) p2 = self.proba_vie_sup (age_vie, age_mort+1) return p1 - p2 def esperance_vie (self, age_vie) : s = 0.0 w = 0.0 for i in range (age_vie, len (mortalite)) : s += i * self.proba_mort_egale (age_vie, i) w += self.proba_mort_egale (age_vie, i) if w == 0 : return 0.0 else : return s / w - age_vie def proportion_femme (self, age_vie) : d1 = self.mortalite [age_vie][3] - self.mortalite [age_vie][1] d2 = self.mortalite [age_vie][2] - self.mortalite [age_vie][1] if d1 == 0 and d2 == 0 : return 0.5 else : return float (d1) / float (d2) def annee_viager (self, i, j) : return self.esperance_vie (i) - self.esperance_vie (j) def proportion_femme_tout (self) : p1f = self.proportion_femme (1) p1h = 1.0 - p1f m1f = self.proba_mortalite_sexuee (0, 1, 1) m1h = self.proba_mortalite_sexuee (0, 1, 2) cf = 1.0 / (1.0 - m1f) ch = 1.0 / (1.0 - m1h) return p1f * cf / ( p1f * cf + p1h * ch ) class PopulationPlus (Population) : def proba_mort_egale (self, age_vie, age_mort) : if age_mort > 0 : return Population.proba_mort_egale (self, age_vie, age_mort) else : p1 = self.proba_vie_sup (age_vie, age_mort) p2 = 1.0 - (1.0 - self.proba_vie_sup (age_vie, age_mort+1)) / 2 return p1 - p2 class Simulation (Population) : def __init__ (self, popu, fecondite = 0.2, age1 = 25, age2 = 34) : Population.__init__ (self, popu) self.fecondite = fecondite self.age1 = age1 self.age2 = age2 def prepare (self) : p = self.proportion_femme_tout () self.sim = [ [ t [1] * p, t [2] * (1.0 - p) ] for t in self.mortalite ] def proportion_bebe_fille (self) : p1 = self.proportion_femme_tout () #p2 = self.proportion_femme (1) return p1 # approximation def bebe (self) : b = 0 for a in range (self.age1, self.age2 + 1) : b += self.sim [a][0] * self.fecondite p = self.proportion_bebe_fille () return int (b * p), int (b * (1.0 - p)) def iteration (self) : for i in range (len (self.sim)-1, 0, -1) : # boucle a l'envers self.sim [i][0] = self.sim [i-1][0] * (1.0 - self.proba_mortalite_sexuee (i-1, i, 1)) self.sim [i][1] = self.sim [i-1][1] * (1.0 - self.proba_mortalite_sexuee (i-1, i, 2)) f,g = self.bebe () self.sim [0][0] = f self.sim [0][1] = g def simulation (self, nb) : self.prepare () for i in range (0, nb) : self.iteration () return self.sim def nb (self, sim) : f,g = 0,0 for i in sim : f += i [0] g += i [1] return int (f), int (g) p = Population (mortalite) print p.proba_vie_sup (20, 40) print p.esperance_vie (20), p.esperance_vie (0) for i in range (0, 5) : print p.proportion_femme (i) print "--------------------" pp = PopulationPlus (mortalite) print pp.esperance_vie (20), pp.esperance_vie (0) print pp.proportion_femme_tout () for x in range (0, 200) : fecondite = 0.2 + x * 0.0001 s = Simulation (mortalite, fecondite = fecondite) r = s.simulation (0) z = s.nb (r) r = s.simulation (100) print "fecondite = ", fecondite, " population H,F ", s.nb (r), " initiale ", z