diff --git a/comsoc/Borda.go b/comsoc/Borda.go index 7076a9b4de20578f2bfe7749ab88012274203de2..9e16bacbb597ed9665db894ea16f014df81c6305 100644 --- a/comsoc/Borda.go +++ b/comsoc/Borda.go @@ -1 +1,30 @@ -package comsoc \ No newline at end of file +package comsoc +import("fmt") + +func BordaSWF(p Profile) (count Count, err error){ + count = make(Count) + nAlts := len(p[0]) + for _, row := range p{ + for i:=0; i<nAlts;i++{ + count[row[i]]+=nAlts-1-i + } + } + return count,nil +} + +func BordaSCF(p Profile) (bestAlts []Alternative, err error) { + count, err := BordaSWF(p) + if err != nil { + return nil, err + } + return maxCount(count), nil +} + +func Test_borda(){ + profil := GenerateProfile(3,5) + fmt.Println("Profil :", profil) + count,_ := BordaSWF(profil) + fmt.Println("Décompte :", count) + winners,_ := BordaSCF(profil) + fmt.Println("Vainqueur(s) :", winners) +} \ No newline at end of file diff --git a/comsoc/GenerateProfile.go b/comsoc/GenerateProfile.go new file mode 100644 index 0000000000000000000000000000000000000000..728df7f069c9ee2d9881413e9cf5162328d1e7ac --- /dev/null +++ b/comsoc/GenerateProfile.go @@ -0,0 +1,35 @@ +package comsoc + +import ( + "math/rand" + "time" +) + +func GenerateProfile(nVoters int, nAlts int)(profil Profile) { + // Initialisation du profil + profil = make([][]Alternative, nVoters) + for i := range profil { + profil[i] = make([]Alternative, nAlts) + } + + // Définition des alternatives + values := make([]Alternative, nAlts) + for i := range values { + values[i] = Alternative(i + 1) + } + + // Remplissage du profil avec des permutations différentes à chaque rang + rand.Seed(time.Now().UnixNano()) + for i := range profil { + // Mélange les valeurs pour chaque ligne + permutation := make([]Alternative, len(values)) + copy(permutation, values) + rand.Shuffle(len(permutation), func(i, j int) { + permutation[i], permutation[j] = permutation[j], permutation[i] + }) + + // Remplit la ligne avec la permutation + copy(profil[i], permutation) + } + return profil +} \ No newline at end of file diff --git a/comsoc/TieBreak.go b/comsoc/TieBreak.go new file mode 100644 index 0000000000000000000000000000000000000000..872f249ace73e0f3fd8feaeaa47ee8d650901a0e --- /dev/null +++ b/comsoc/TieBreak.go @@ -0,0 +1,105 @@ + +package comsoc +import("fmt") + +func TieBreakFactory(orderedAlts []Alternative) (func ([]Alternative) (Alternative, error)){ + return func (bestAlts []Alternative) (Alternative, error) { + bestAlt := bestAlts[0] + for _,alt:= range bestAlts[1:]{ + if isPref(alt,bestAlt,orderedAlts){ + bestAlt = alt + } + } + return bestAlt, nil + } +} + +func Test_tieBreakFactory(){ + orderedAlts := []Alternative{8,9,6,1,3,2} + fmt.Println("Ordre strict :", orderedAlts) + lambda:=TieBreakFactory(orderedAlts) + bestAlts := []Alternative{3,6} + fmt.Println("Premières alternatives, à départager :", bestAlts) + bestAlt,_ := lambda(bestAlts) + fmt.Println("Première alternative :", bestAlt) +} + +func SWFFactory(swf func (Profile) (Count, error), tb func([]Alternative) (Alternative, error)) (func(Profile) ([]Alternative, error)){ + + return func(p Profile) ([]Alternative, error){ + //récupération du décompte + count,_ := swf(p) + //préparation de la sortie + var sorted_alts []Alternative + + //PARCOURS DU DECOMPTE + for len(count) > 0{ + //On prend les meilleures alternatives (avant tie break) + bestAlts := maxCount(count) + //On supprime les meilleures alternatives du décompte + for alt := range bestAlts{ + delete(count, Alternative(alt)) + } + //Départage + for len(bestAlts) > 0{ + bestAlt,_ := tb(bestAlts) + //ajout de la meilleure alternative post-tie break + sorted_alts = append(sorted_alts, bestAlt) + //suppression de l'alternative dans bestAlts + indice := rank(bestAlt, bestAlts) + bestAlts=append(bestAlts[:indice], bestAlts[indice+1:]...) + //suppression de l'alternativ dans le compte + delete(count, Alternative(bestAlt)) + } + } + return sorted_alts,nil + } +} + +func Test_sWFFactory(){ + //Définition de l'Ordre strict + orderedAlts := []Alternative{8,9,6,1,3,2} + fmt.Println("Ordre strict :", orderedAlts) + + //Construction d'un profil avec alternatives ex aequo + profil := make([][]Alternative, 2) + profil[0] = []Alternative{1, 2, 3,4,5,6} + profil[1] = []Alternative{3, 2, 1,4,5,6} + fmt.Println("Profil :", profil) + + //Construction de la fonction Tie Break + lambda:=TieBreakFactory(orderedAlts) + //Construction de la Social Welfare Factory à partir de la fonction swf + la fonction de TieBreak + mu := SWFFactory(BordaSWF,lambda) + //Construction d'une fonction + sorted_alts,_ := mu(profil) + fmt.Println("Alternatives strictement ordonnées selon la méthode de Borda :", sorted_alts) +} + +func SCFFactory(scf func (p Profile) ([]Alternative, error),tb func ([]Alternative) (Alternative, error)) (func(Profile) (Alternative, error)){ + return func(p Profile) (Alternative, error){ + //récupération des meilleures alternatives + bestAlts,_ := scf(p) + //récupération de la meilleure alternative + bestAlt,_ := tb(bestAlts) + return bestAlt,nil + } +} +func Test_sCFFactory(){ + //Définition de l'Ordre strict + orderedAlts := []Alternative{8,9,6,1,3,2} + fmt.Println("Ordre strict :", orderedAlts) + + //Construction d'un profil avec alternatives ex aequo + profil := make([][]Alternative, 2) + profil[0] = []Alternative{1, 2, 3,4,5,6} + profil[1] = []Alternative{3, 2, 1,4,5,6} + fmt.Println("Profil :", profil) + + //Construction de la fonction Tie Break + lambda:=TieBreakFactory(orderedAlts) + mu := SCFFactory(BordaSCF,lambda) + //Construction d'une fonction + best_Alt,_ := mu(profil) + fmt.Println("Meilleure alternative selon la méthode de Borda :", best_Alt) +} \ No newline at end of file