Athée-souhait

Lisons les textes religieux, et voyons ce qu'ils disent de faux ou d'inacceptable en l'abscence de preuve.

Comparaison des systèmes de votes

Voici une liste des candidats (un par colone) et des préférences des votants (un classement par ligne, ou chaque électeur met une note à chaque candidat)

Résultats

Chaque système nous sort une liste de couples candidats/note.

Nous souhaitons plusieurs propriétés dans un système de vote :

  • La confiance
  • L'alternance politique
  • Se présenter ne doit pas désservir nos idées
  • Le vote utile ne doit pas être possible (les votants ne doivent pas avoir intéret à mentir
  • Si un candidat est majoritaire, il doit être élu
  • L'élu ne doit pas pouvoir perdre un second tour contre un autre candidat
  • On ne doit pas pouvoir acheter un vote, ni menacer (le vote doit être secret, et on ne doit pas pouvoir techniquement prouver son vote)
Il existe d'autres systèmes de votes, probablement d'autres propriétés qu'on aimerait avoir, j'ai mis l'essentiel. Il n'existe aucune méthode qui permette de respecter toutes ces propriétés. On peut discutter longtemps de quelle méthode permet d'élire UN humain pour diriger un pays, mais on constate simplement qu'aucune méthode n'est fiable pour ce point. Partant de ce constat, ma proposition est simplement de réduire au maximum le pouvoir de cette personne, qu'elle n'ai qu'un rôle de représentation, et laisser le législatif au pouvoir législatif (assemblée nationale, sénat). Le système de vote est un sujet pour moi principalement algorithmique, une curiosité de théorie des jeux, mais pas une solution institutionnelle.

Voici le code ocaml qui sert pour cette simulation


let sort_result li = List.sort (fun (_, a) (_, b) -> b - a) li

let list_candidats_to_scores candidats votes = (* bulletins de vote => liste de couples nom, score *)
  Array.map (fun candidat -> candidat, List.length (List.filter (fun v -> v = candidat) votes)) candidats |> Array.to_list |> sort_result

let uninominal_1tour candidats preferences = List.map List.hd preferences |> list_candidats_to_scores candidats

let uninominal_2tours candidats preferences =
  match uninominal_1tour candidats preferences with
  | (c1, _)::(c2, _)::_ -> List.map (fun p -> List.find_opt (fun c -> c = c1 || c = c2) p |> un_opt) preferences |> list_candidats_to_scores candidats
  | x -> x

let remove_worst candidats preferences =
  let nth = List.length (List.hd preferences) in
  let (worst, _)::_ = list_candidats_to_scores candidats (List.map (fun x -> List.nth x (nth - 1)) preferences)
  in List.map (fun p -> List.filter ((<>) worst) p) preferences;;

let australian_legislatif0 candidats preferences =
  let rec f = function
    | ([x]::_ ) as prefs -> list_candidats_to_scores candidats (List.map List.hd prefs)
    | x -> f (remove_worst candidats x)
  in f preferences

let australian_legislatif1 candidats preferences =
  let nbr_majority = List.length preferences / 2 + 1 in
  let rec f x = match uninominal_1tour candidats x with
    | [x] -> [x]
    | ((winner, score)::_) as li ->
       if score >= nbr_majority then li else f (remove_worst candidats x)
  in f preferences

let majoritaire preferences_f = (* la liste des candidats doit être triée par nom *)
  let median_index = List.length preferences_f / 2 in
  let rec f r votes tail_preferences = function
    | [] -> failwith "Error"
    | [[(nom, vote)]] -> (nom, vote::votes)::r
    | [(nom, vote)::tl] -> f ((nom, vote::votes)::r) [] [] (tl::tail_preferences)
    | ((_, vote)::tl)::tl2 -> f r (vote::votes) (tl::tail_preferences) tl2 in
  let scores = f [] [] [] preferences_f |> List.map (fun (nom, votes) -> nom, List.sort (-) votes) in
  let median = List.map (fun (nom, votes) -> nom, List.nth votes median_index) scores in
  median |> sort_result


let condorcet candidats preferences_f =
  let preferences_f = List.map (Array.of_list @* (List.map snd)) preferences_f in
  let score i1 i2 =
    let s = List.fold_left (fun acc votes ->
        if votes.(i1) = votes.(i2) then acc
        else if votes.(i1) > votes.(i2) then acc+1 else acc - 1 ) 0 preferences_f
    in if s > 0 then 1 else 0
  in
  let matrix = candidats |> Array.mapi (fun i1 c1 -> c1, candidats |> Array.mapi (fun i2 c2 -> score i1 i2))
  in matrix |> Array.map (fun (c, l) -> c, Array.fold_left (+) 0 l) |> Array.to_list |> sort_result

let bulletins preferences_f = List.map (fun a -> List.sort (fun (_, a) (_, b) -> b - a) a |> List.map fst) preferences_f