• # Common Lisp

    Posté par (site web personnel) . En réponse au journal Un article de "Pour la science" m'ayant amené à coder pour une petite vérification perso.... Évalué à 6. Dernière modification le 21 juillet 2021 à 02:56.

    Comme je n'ai pas envie de dormir et que ce que tu dis est très intéressant j'ai écrit ton programme en Common Lisp – utilisable abec sbcl par exemple. Cela ressemble à ça:

    (defparameter *population-size* 500
     "The number of persons in our modelisation.")
    (defparameter *initial-fortune* 2000
     "The initial fortune of each person in the modelisation.")
    (defparameter *transaction-rate* 20/100
     "The proportion of their fortune a person will engage in a transaction.")
    (defparameter *regulatory-advantage* 5/100
     "The correction introduces by the regulator to alleviate the poor.")
    (defun fortune-simulation (number-of-iterations)
     "Run the Boghosian model for NUMBER-OF-ITERATIONS."
     (declare (optimize (speed 3)))
     (labels
     ((make-initial-state ()
     (make-array *population-size* :initial-element (float *initial-fortune*)))
     (transaction (state)
     (let* ((payer
     (random *population-size*))
     (receiver
     (random *population-size*))
     (fortune-payer
     (aref state payer))
     (fortune-receiver
     (aref state receiver))
     (transaction-base
     (min fortune-payer fortune-receiver))
     (transaction-rate
     (float
     (if (> fortune-payer fortune-receiver)
     (+ *transaction-rate* *regulatory-advantage*)
     *transaction-rate*)))
     (transaction-amount
     (* transaction-base transaction-rate)))
     (decf (aref state payer) transaction-amount)
     (incf (aref state receiver) transaction-amount))))
     (let ((state (make-initial-state)))
     (dotimes (_ number-of-iterations state) (transaction state)))))

    La fonction calcule l'état final du modèle après tant et tant d'itérations. Cet état est juste le vecteur des fortunes. (Pourquoi ne pas donner 1 EUR à tout le monde au début au lieu de 2000 ? :-) )

    Pour interpréter les résultats plus facilement j'ai aussi écrit la fonction suivante

    (defun fortune-repartition (fortune-vector &rest query)
     "Analyse fortune repartition according to request QUERY.
    The QUERY is a list of percentages to break down the fortune repartition. The answer
    is a list whose elements have the form
     (P N AMOUNT)
    which reads like
     "In FORTUNE-VECTOR the N-th first people own together AMOUNT of money,
     which is more than P of the total amount of money."
    "
     (let*
     ((total-fortune
     (* *population-size* *initial-fortune*))
     (decreasing-fortune
     (sort fortune-vector #'>=))
     (detailed-query
     (mapcar #'(lambda (p) (cons (float p) (float (* p total-fortune))))
     (sort query #'<=))))
     (loop with current-query = detailed-query
     with answer = nil
     for i from 1 upto *population-size*
     for ax = (aref decreasing-fortune 0) then (+ ax (aref decreasing-fortune (1- i)))
     when (null current-query)
     do (return answer)
     when (>= ax (cdr (first current-query)))
     do (progn
     (push (list (car (first current-query)) i ax) answer)
     (setf current-query (rest current-query)))
     finally (return answer))))

    Au final avec les nombres que tu utilises mais seulement 100000 simulations, on trouve:

    CL-USER> (fortune-repartition (fortune-simulation 1000000) 1/2 3/4 90/100 95/100)
    ((0.95 53 951680.8) (0.9 38 901602.1) (0.75 20 756305.9) (0.5 9 527378.4))
    

    Ce qui signifie que les 53 personnes les plus riches(sur les 500 de départ) possèdent à elles seules plus de 95% de la fortune totale du système, et ainsi de suite jusqu'au terme final qui dit que les 9 personnes possèdent plus de la moitié des richesses totales.

    Si on annule *regulatory-advantage* on voit cet effet s'accentuer:

    CL-USER> (let ((*regulatory-advantage* 0))
     (fortune-repartition (fortune-simulation 1000000) 1/2 3/4 90/100 95/100))
    ((0.95 18 955952.6) (0.9 14 916244.6) (0.75 8 763214.2) (0.5 4 537323.9))
    

    et les seules 4 personnes les plus riches concentrent 50% des richesses totales.