scrutin mention majoritaire
Bonjour,
voici le scrutin à jugement majoritaire:
https://fr.wikipedia.org/wiki/Jugement_majoritaire
(je rappelle que les URL sont faites pour les ouvrir)
Comme l'explique Monsieur Balinski et Monsieur Laraki, le candidat élu est celui qui a le meilleur jugement majoritaire. Par contre, lorsque que plusieurs candidats on le même, et le meilleur, jugement majoritaire, on ne retient que ces candidats et on supprime la ligne des 50%, ainsi de suite jusqu'à ce que l'on ait qu'un candidat qui obtienne le jugement majoritaire, ou alors jusqu'à ce que il n'y ait plus qu'une ligne. dans ce dernier cas, si il y a plusieurs candidat ayant le meilleur jugement alors il y a ex æquo, sinon l'élu est celui qui a le meilleur jugement.
Tant que le meilleur jugement est attribué à plusieurs candidats, on supprime les autres candidats, on décrémente le nombre de votants des candidat pour leur jugement majoritaire et on décrémente le nombre de votants, puis on recalcule les jugements majoritaires. Je voudrais savoir si cela revient au même que l'algorithme récursif de M Balinski et M Laraki
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #ifndef SCRUTIN_HPP
#define SCRUTIN_HPP
#include <map>
#include <vector>
#include "syntaxique.hpp"
class scrutin{
public:
scrutin(std::string nomfichier);
void elu();
private:
syntaxique S;
unsigned int nbvotants;
std::map<std::string,int[6]> scores; //0:TB 1:B 2:AB 3:P 4:I 5:AR
//scores est un map qui indique pour chaque candidats le nombre d'électeurs pour chaque jugement
std::map<std::string,int>mentionchacun;
//mentionchacun indique la mention majoritaire de chaque candidats
std::vector<std::string>vec_nomscandidats;//liste des candidats
std::vector<occurence_bulletin> vec_listebulletins;
std::vector<std::string>nom_exaequo;//nom des candidats ayant obtenu ensemble la meilleure mention
void garder_meilleure_mention();//supprimer
void absentarejeter(occurence_bulletin &struct_bulletin);
bool absent(occurence_bulletin const &struct_bulletin,std::string nom);
void unjugementparcandidatetbulletin();
void absentarejeter();
void nomsvalides();
void mentionmajoritaires();
void calculscores();
void afficherscores();
bool exaequo();
std::string mentionmini();
};
#endif |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
| #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "scrutin.hpp"
#include "enumetstruct.hpp"
scrutin::scrutin(std::string nomfichier):S(nomfichier){
S.anasynt(vec_nomscandidats,vec_listebulletins);//construit les candidats et les bulletins à partir du texte d'entrée
}
void scrutin::elu(){
for(auto &struct_bulletin:vec_listebulletins){//pour chaque bulletin
absentarejeter(struct_bulletin);//on attribue la mention "à rejeter" aux candidats absent du bulletin
}
nomsvalides();//vérifie que les noms sont constitués par un ensemble de mot débutant par une majuscule et éventuellement suivi de minuscules
unjugementparcandidatetbulletin();//vérifie que, sur un bulletin de vote, un candidat n'a pas plus d'une mention
if(vec_listebulletins.size()!=0){//si la liste des bulletins n'est pas vide
calculscores();
afficherscores();
nbvotants=vec_listebulletins.size();
mentionmajoritaires();//calcule la mention majoritaire de chaque candidat
garder_meilleure_mention();//supprime les candidate n'ayant pas la meilleure mention majoritaire
while(nbvotants>1 && exaequo()){//La fonction exaequo retourne vrai si plus d'un candidat a le meilleure mention majoritaire
for(auto nom:vec_nomscandidats)
scores[nom][mentionchacun[nom]]--;//on décrémente la mention majoritaire dans les scores, pour chaque candidat
nbvotants--;//le nombre de votant est alors décrémenté
mentionmajoritaires();//calcule la nouvelle mention majoritaire de chaque candidat
garder_meilleure_mention();//on supprime les candidats qui n'ont pas la meilleure mention majoritaire
}
if(exaequo()){
std::cout<<"Ex æquo entre ";
for(size_t i=0;i<nom_exaequo.size();i++){
std::cout<<nom_exaequo[i];
if(i+1<nom_exaequo.size())
std::cout<<" et ";
}
std::cout<<std::endl;
}
else
std::cout<<"Le candidat élu est "<<mentionmini()<<std::endl;
}
else
std::cout<<"Pas de buletin valide"<<std::endl;
}
void scrutin::garder_meilleure_mention(){
int mention_min=5;// 5= mention "à rejeter"
for(auto nom:vec_nomscandidats)
if(mentionchacun[nom]<mention_min)
mention_min=mentionchacun[nom];
for(size_t i=0;i<vec_nomscandidats.size();i++){
std::string nom=vec_nomscandidats[i];
if(mentionchacun[nom]!=mention_min){
vec_nomscandidats.erase(vec_nomscandidats.begin()+i);
mentionchacun.erase(nom);
scores.erase(nom);
i=-1;
}
}
}
void scrutin::unjugementparcandidatetbulletin(){
bool ecraser=false;
for(size_t numbulletin=0;numbulletin<vec_listebulletins.size();numbulletin++){
for(int jugement=0;jugement<6;jugement++)
for(auto nom:vec_listebulletins[numbulletin].candidatmention[jugement])
for(int compare=jugement+1;compare<6;compare++){
std::vector<std::string>listenoms=vec_listebulletins[numbulletin].candidatmention[compare];
if(find(listenoms.begin(),listenoms.end(),nom) != listenoms.end()){
std::cerr<<"Présence d'un nom ayant plusieur mention dans le même bulletin. Bulletin nul"<<std::endl;
ecraser=true;
}
}
if(ecraser){
vec_listebulletins.erase(vec_listebulletins.begin()+numbulletin);
numbulletin--;
ecraser=false;
}
}
}
void scrutin::mentionmajoritaires(){
for(auto nomcandidat:vec_nomscandidats){
long double mention=0.0;
int jugement;
for(jugement=0;jugement<6;jugement++){
mention+=(long double)scores[nomcandidat][jugement]/(long double)nbvotants;
if(mention>=0.5)
break;
}
mentionchacun[nomcandidat]=jugement;
}
}
bool scrutin::absent(occurence_bulletin const &struct_bulletin,std::string nom){
for(int i=0;i<6;i++){
std::vector<std::string>listenomsmention;
listenomsmention=struct_bulletin.candidatmention[i];
if(find(listenomsmention.begin(),listenomsmention.end(),nom) != listenomsmention.end())
return false;
}
return true;
}
void scrutin::absentarejeter(occurence_bulletin &struct_bulletin){
for(auto nom:vec_nomscandidats)
if(absent(struct_bulletin,nom))
struct_bulletin.candidatmention[5].push_back(nom);// on attribue la mention "à rejeter" aux absent du bulletin de vote
}
void scrutin::nomsvalides(){
for(size_t numbulletin=0;numbulletin<vec_listebulletins.size();numbulletin++){
for(int jugement=0;jugement<6;jugement++){
std::vector<std::string>listenoms;
listenoms=vec_listebulletins[numbulletin].candidatmention[jugement];
for(auto nom:listenoms)
if(find(vec_nomscandidats.begin(),vec_nomscandidats.end(),nom)==vec_nomscandidats.end()){
std::cerr<<"\""<<nom<<"\""<<" absent de la liste des candidats. Bulletin nul"<<std::endl;
vec_listebulletins.erase(vec_listebulletins.begin()+numbulletin);
if(numbulletin!=0){
numbulletin--;
}
}
}
}
}
void scrutin::calculscores(){
for(auto struct_bulletin:vec_listebulletins){
for(int jugement=0;jugement<6;jugement++)
for(auto nomcandidat:struct_bulletin.candidatmention[jugement])
scores[nomcandidat][jugement]++;
}
}
void scrutin::afficherscores(){
unsigned int nbvotantsdansafficher=vec_listebulletins.size();
for(auto nom:vec_nomscandidats){
std::cout<<nom<<":"<<std::endl;
for(int i=0;i<6;i++){
switch(i){
case 0:
std::cout<<"très bien: "<<(long double)scores[nom][i]/(long double)nbvotantsdansafficher*100<<"%";
break;
case 1:
std::cout<<"bien: "<<(long double)scores[nom][i]/(long double)nbvotantsdansafficher*100<<"%";
break;
case 2:
std::cout<<"assez bien: "<<(long double)scores[nom][i]/(long double)nbvotantsdansafficher*100<<"%";
break;
case 3:
std::cout<<"passable: "<<(long double)scores[nom][i]/(long double)nbvotantsdansafficher*100<<"%";
break;
case 4:
std::cout<<"insuffisant: "<<(long double)scores[nom][i]/(long double)nbvotantsdansafficher*100<<"%";
break;
case 5:
std::cout<<"à rejeter: "<<(long double)scores[nom][i]/(long double)nbvotantsdansafficher*100<<"%";
break;
}
std::cout<<std::endl;
}
std::cout<<std::endl;
}
}
bool scrutin::exaequo(){
nom_exaequo.clear();
int minimum=5;//5=à rejeter
for(auto nom:vec_nomscandidats)
if(mentionchacun[nom]<minimum)//si le candidat(nom) a une meilleure mention majoritaire
minimum=mentionchacun[nom];//alors cette mention est retenue
int compteur=0;
for(auto nom:vec_nomscandidats){
if(mentionchacun[nom]==minimum){
compteur++;//compte combien de candidats ont la meileure mention majoritaire
if(std::find(nom_exaequo.begin(),nom_exaequo.end(),nom)==nom_exaequo.end())//si ce nom n'est pas dans la liste des exaequo
nom_exaequo.push_back(nom);//alors on l'ajoute
}
}
return compteur>1;//retourne vrai si plus d'un nom a obtenu la mention majoritaire
}
std::string scrutin::mentionmini(){
int minimum=5;//5=à rejeter
std::string nommini;
for(auto nom:vec_nomscandidats)//pour chaque nom de candidat
if(mentionchacun[nom]<minimum){//si ce candidat a une meilleure mention majoritaire
minimum=mentionchacun[nom];//alors on retient cette mention
nommini=nom;//et on retient aussi le nom ce candidat
}
return nommini;//retourne le nom du candidat ayant la meilleure mention majoritaire
} |
Ce code est-il équivalent à l'algorithme récursif de M Balinski et M Laraki?
pensez-vous que c'est assez exact pour que je puisse le mettre dans un billet du blog?