diff --git a/comsoc/HelpFunctions.go b/comsoc/HelpFunctions.go index b7b90d8de9a9f61de28e278e6fecaf150f75c8c2..d6cca4a141370ea3cdae8fdc4577af2fa6d42d3c 100644 --- a/comsoc/HelpFunctions.go +++ b/comsoc/HelpFunctions.go @@ -1,61 +1,64 @@ package comsoc + import ( - "fmt" "errors" + "fmt" ) -//cours TODO -func plusN (n int) (func (i int)(int)){ - f:=func(i int) int { - return (i+n) +// cours TODO +func plusN(n int) func(i int) int { + f := func(i int) int { + return (i + n) } return f } + // renvoie l'indice ou se trouve alt dans prefs func rank(alt Alternative, prefs []Alternative) int { - for i := 0; i < len(prefs);i++{ - if prefs[i]==alt{ - return i - } - } - return -1 - } -func Test_rank(){ + for i := 0; i < len(prefs); i++ { + if prefs[i] == alt { + return i + } + } + return -1 +} +func Test_rank() { tableau := []Alternative{1, 2, 3, 4, 5} - indice := rank(tableau[3],tableau) - fmt.Print(indice) + indice := rank(tableau[3], tableau) + fmt.Print(indice) } -// renvoie vrai ssi alt1 est préférée à alt2 +// renvoie vrai ssi alt1 est préférée à alt2 func isPref(alt1, alt2 Alternative, prefs []Alternative) bool { // if (alt1 <0 || alt2 <0){ // return errors.New("l'une des deux valeurs n'est pas présente dans le tableau") // }else { - return rank(alt1,prefs)<rank(alt2,prefs) - } + return rank(alt1, prefs) < rank(alt2, prefs) +} + // } -func Test_isPref(){ +func Test_isPref() { tableau := []Alternative{1, 2, 3, 4, 5} alt1 := Alternative(1) alt2 := Alternative(2) response := isPref(alt1, alt2, tableau) - fmt.Print(response) + fmt.Print(response) } // renvoie les meilleures alternatives pour un décompte donné func maxCount(count Count) (bestAlts []Alternative) { - maxPoints:=-1 - for i, points := range count{ + maxPoints := -1 + for i, points := range count { if points > maxPoints { bestAlts = []Alternative{Alternative(i)} maxPoints = points - }else if points == maxPoints{ - bestAlts=append(bestAlts,Alternative(i)) + } else if points == maxPoints { + bestAlts = append(bestAlts, Alternative(i)) } } return bestAlts } -func Test_maxCount(){ +func Test_maxCount() { count := make(map[Alternative]int) count[Alternative(1)] = 3 count[Alternative(2)] = 5 @@ -63,25 +66,25 @@ func Test_maxCount(){ fmt.Println(maxCount(count)) } -// // vérifie les préférences d'un agent, par ex. -//qu'ils sont tous complets et que chaque alternative n'apparaît qu'une seule fois +// // vérifie les préférences d'un agent, par ex. +// qu'ils sont tous complets et que chaque alternative n'apparaît qu'une seule fois func checkProfile(prefs []Alternative, alts []Alternative) error { - //vérifier - if (len (prefs) < len(alts)){ + //vérifier + if len(prefs) < len(alts) { return errors.New("Il manque des alternatives") - }else if(len (prefs)>len(alts)){ + } else if len(prefs) > len(alts) { return errors.New("Il y a des alternatives en trop.") - }else{//vérifier complet - for _, element := range alts{ + } else { //vérifier complet + for _, element := range alts { if rank(element, prefs) == -1 { return errors.New("au moins une alternative est absente des préférences") } } -} -return nil + } + return nil } -func Test_checkProfile(){ +func Test_checkProfile() { alts := []Alternative{1, 2, 3, 4, 5} //prefs := []Alternative{3, 1, 5, 2, 4} //prefs := []Alternative{1, 2, 3, 4, 5,6} @@ -89,23 +92,34 @@ func Test_checkProfile(){ fmt.Println(checkProfile(prefs, alts)) } -// vérifie le profil donné, par ex. qu'ils sont tous complets +// vérifie le profil donné, par ex. qu'ils sont tous complets // et que chaque alternative de alts apparaît exactement une fois par préférences func checkProfileAlternative(prefs Profile, alts []Alternative) error { - for _, row := range prefs{ - e:=checkProfile(row, alts) - if e != nil{ + for _, row := range prefs { + e := checkProfile(row, alts) + if e != nil { return e } } -return nil + return nil } - -func Test_checkProfileAlternative(){ + +func Test_checkProfileAlternative() { alts := []Alternative{1, 2, 3, 4, 5} - pref1 := []Alternative{5, 2, 1, 4, 3} + pref1 := []Alternative{5, 3, 1, 4, 2} pref2 := []Alternative{1, 5, 4, 3, 2} - Pref := [][]Alternative{pref1,pref2} + Pref := [][]Alternative{pref1, pref2} profil := Profile(Pref) fmt.Println(checkProfileAlternative(profil, alts)) -} \ No newline at end of file +} + +func Test_MajoritySWF() { + pref1 := []Alternative{5, 3, 1, 4, 2} + pref2 := []Alternative{2, 1, 4, 3, 5} + Pref := [][]Alternative{pref1, pref2} + profil := Profile(Pref) + fmt.Println(MajoritySWF(profil)) + c, _ := ApprovalSWF(profil, []int{1, 2, 3, 4, 5}) + fmt.Println(c[Alternative(2)]) + //fmt.Println(CondorcetWinner(profil)) +} diff --git a/comsoc/Majority.go b/comsoc/Majority.go index 93b492c81d055e5d84a2de05fc0f4f0c558a561b..d60f0463e70cfef8499426d2af6c3e677091c178 100644 --- a/comsoc/Majority.go +++ b/comsoc/Majority.go @@ -3,15 +3,71 @@ package comsoc //majorité simple // fonctions de bien-être social (social welfare function, SWF) : // retournent un décompte à partir d'un profil -func MajoritySWF(p Profile) (count Count, err error){ - //1) checkProfileAlternative(prefs Profile, alts []Alternative) - count := make(map[Alternative]int) - for _, row := range p{ - count[row[0]]+=1 +// En utilisation la méthode de la majorité simple +func MajoritySWF(p Profile) (count Count, err error) { + count = make(Count) + for _, pref := range p { + count[pref[0]]++ } - return count + return count, nil } -// fonctions de choix social (choix social, social choice function, SCF) -// renvoient uniquement les alternatives préférées. -func MajoritySCF(p Profile) (bestAlts []Alternative, err error){} +func MajoritySCF(p Profile) (bestAlts []Alternative, err error) { + count, err := MajoritySWF(p) + if err != nil { + return nil, err + } + return maxCount(count), nil +} + +func ApprovalSWF(p Profile, thresholds []int) (count Count, err error) { + count = make(Count) + for _, pref := range p { + for index, alt := range pref { + count[alt] += thresholds[len(thresholds)-1-index] + } + } + return count, nil +} + +func ApprovalSCF(p Profile, thresholds []int) (bestAlts []Alternative, err error) { + count, err := ApprovalSWF(p, thresholds) + if err != nil { + return nil, err + } + return maxCount(count), nil +} + +// Gagnant de condorcet, retourne un slice vide ou de 1 élément +// Utilise la majorité simple sur chaque paire de candidat +/* +func CondorcetWinner(p Profile) (bestAlts []Alternative, err error) { + for _, alt1 := range p[0] { + winner := true + for _, alt2 := range p[0] { + if alt1 != alt2 { + p2 := make(Profile, len(p)) + for index, pref := range p { + if isPref(alt1, alt2, pref) { + p2[index] = append(p2[index], alt1) + } else { + p2[index] = append(p2[index], alt2) + } + } + count, err := MajoritySCF(p2) + if err != nil { + return nil, err + } + if count[alt2] >= count[alt1] { + winner = false + break + } + } + } + if winner { + return []Alternative{alt1}, nil + } + } + return []Alternative{}, nil +} +*/ diff --git a/go.mod b/go.mod index 15c098f84fb864449b9f76723462ccd7fd89d2a9..e5b3e88d9fc586b7182a9c45551c68268c234a7c 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ -module gitlab.utc.fr/gvandevi/ia04 +module gitlab.utc.fr/gvandevi/ia04binome2a go 1.21.1 diff --git a/main.go b/main.go index 3d7eb072fe13e74327fba0209bb1ab9f02edceec..d8e332634ac182dc9b69c9daf694504fdda33743 100644 --- a/main.go +++ b/main.go @@ -1,13 +1,14 @@ package main + import ( - "gitlab.utc.fr/gvandevi/ia04/comsoc" + "gitlab.utc.fr/gvandevi/ia04binome2a/comsoc" ) -func main(){ - //Fonctions utilitaires - //comsoc.Test_rank() - //comsoc.Test_maxCount() - //comsoc.Test_checkProfile() - comsoc.Test_checkProfileAlternative() +func main() { + //Fonctions utilitaires + //comsoc.Test_rank() + //comsoc.Test_maxCount() + //comsoc.Test_checkProfile() + //comsoc.Test_checkProfileAlternative() + comsoc.Test_MajoritySWF() } -