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, errSWF := swf(p) if errSWF != nil { return nil, errSWF } //préparation de la sortie var sortedAlts []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, errTB := tb(bestAlts) if errTB != nil { return nil, errTB } //ajout de la meilleure alternative post-tie break sortedAlts = append(sortedAlts, 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 sortedAlts, 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(MajoritySWF, lambda) // 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 SWFFactoryWithOptions( swf func(Profile, []int) (Count, error), tb func([]Alternative) (Alternative, error), ) func(Profile, []int) ([]Alternative, error) { return func(p Profile, o []int) ([]Alternative, error) { //récupération du décompte count, errSWF := swf(p, o) if errSWF != nil { return nil, errSWF } //préparation de la sortie var sortedAlts []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, errTB := tb(bestAlts) if errTB != nil { return nil, errTB } //ajout de la meilleure alternative post-tie break sortedAlts = append(sortedAlts, 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 sortedAlts, nil } } func SCFFactoryWithOptions( scf func(Profile, []int) ([]Alternative, error), tb func([]Alternative) (Alternative, error), ) func(Profile, []int) (Alternative, error) { return func(p Profile, o []int) (Alternative, error) { //récupération des meilleures alternatives bestAlts, errSCF := scf(p, o) if errSCF != nil { return Alternative(0), errSCF } //récupération de la meilleure alternative bestAlt, errTB := tb(bestAlts) return bestAlt, errTB } } 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, errSCF := scf(p) if errSCF != nil { return Alternative(0), errSCF } //récupération de la meilleure alternative bestAlt, errTB := tb(bestAlts) return bestAlt, errTB } } 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) }