Skip to content
Snippets Groups Projects
Commit 3d9b7d77 authored by Balthazar Wilson's avatar Balthazar Wilson
Browse files

add: error handling

parent 42531555
No related branches found
No related tags found
No related merge requests found
...@@ -4,11 +4,10 @@ package comsoc ...@@ -4,11 +4,10 @@ package comsoc
// thresholds est un slice d'entiers strictement positifs // thresholds est un slice d'entiers strictement positifs
func ApprovalSWF(p Profile, thresholds []int) (count Count, err error) { func ApprovalSWF(p Profile, thresholds []int) (count Count, err error) {
count = make(Count) count = make(Count)
alts := make([]Alternative, 0) err = checkProfileFromProfile(p)
for i := 1; i <= len(p[0]); i++ { if err != nil {
alts = append(alts, Alternative(i)) return nil, err
} }
err = checkProfileAlternative(p, alts)
for index, alt := range p { for index, alt := range p {
for i := 0; i < thresholds[index]; i++ { for i := 0; i < thresholds[index]; i++ {
count[alt[i]] += 1 count[alt[i]] += 1
...@@ -19,6 +18,9 @@ func ApprovalSWF(p Profile, thresholds []int) (count Count, err error) { ...@@ -19,6 +18,9 @@ func ApprovalSWF(p Profile, thresholds []int) (count Count, err error) {
func ApprovalSCF(p Profile, thresholds []int) (bestAlts []Alternative, err error) { func ApprovalSCF(p Profile, thresholds []int) (bestAlts []Alternative, err error) {
alts, err := ApprovalSWF(p, thresholds) alts, err := ApprovalSWF(p, thresholds)
if err != nil {
return nil, err
}
bestAlts = maxCount(alts) bestAlts = maxCount(alts)
return return
} }
package comsoc package comsoc
import("fmt")
func BordaSWF(p Profile) (count Count, err error){ import (
"fmt"
)
func BordaSWF(p Profile) (count Count, err error) {
count = make(Count) count = make(Count)
nAlts := len(p[0]) err = checkProfileFromProfile(p)
for _, row := range p{ if err != nil {
for i:=0; i<nAlts;i++{ return nil, err
count[row[i]]+=nAlts-1-i }
nAlts := len(p[0])
for _, row := range p {
for i := 0; i < nAlts; i++ {
count[row[i]] += nAlts - 1 - i
} }
} }
return count,nil return
} }
func BordaSCF(p Profile) (bestAlts []Alternative, err error) { func BordaSCF(p Profile) (bestAlts []Alternative, err error) {
...@@ -17,14 +24,14 @@ func BordaSCF(p Profile) (bestAlts []Alternative, err error) { ...@@ -17,14 +24,14 @@ func BordaSCF(p Profile) (bestAlts []Alternative, err error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return maxCount(count), nil return maxCount(count), err
} }
func Test_borda(){ func Test_borda() {
profil := GenerateProfile(3,5) profil := GenerateProfile(3, 5)
fmt.Println("Profil :", profil) fmt.Println("Profil :", profil)
count,_ := BordaSWF(profil) count, _ := BordaSWF(profil)
fmt.Println("Décompte :", count) fmt.Println("Décompte :", count)
winners,_ := BordaSCF(profil) winners, _ := BordaSCF(profil)
fmt.Println("Vainqueur(s) :", winners) fmt.Println("Vainqueur(s) :", winners)
} }
\ No newline at end of file
package comsoc package comsoc
import "errors"
// Gagnant de condorcet, retourne un slice vide ou de 1 élément // Gagnant de condorcet, retourne un slice vide ou de 1 élément
// A vérifier avec plus d'exemples // A vérifier avec plus d'exemples
func CondorcetWinner(p Profile) (bestAlts []Alternative, err error) { func CondorcetWinner(p Profile) (bestAlts []Alternative, err error) {
...@@ -25,5 +27,5 @@ func CondorcetWinner(p Profile) (bestAlts []Alternative, err error) { ...@@ -25,5 +27,5 @@ func CondorcetWinner(p Profile) (bestAlts []Alternative, err error) {
return []Alternative{alt1}, nil return []Alternative{alt1}, nil
} }
} }
return []Alternative{}, nil return nil, errors.New("pas de gagnant de Condorcet")
} }
...@@ -71,13 +71,22 @@ func Test_maxCount() { ...@@ -71,13 +71,22 @@ func Test_maxCount() {
func checkProfile(prefs []Alternative, alts []Alternative) error { func checkProfile(prefs []Alternative, alts []Alternative) error {
//vérifier //vérifier
if len(prefs) < len(alts) { if len(prefs) < len(alts) {
return errors.New("Il manque des alternatives") return errors.New("préférences non complètes")
} else if len(prefs) > len(alts) { } else if len(prefs) > len(alts) {
return errors.New("Il y a des alternatives en trop.") return errors.New("alternatives en trop")
} else { //vérifier complet } else { //vérifier complet
for _, element := range alts { for _, element := range alts {
if rank(element, prefs) == -1 { if rank(element, prefs) == -1 {
return errors.New("au moins une alternative est absente des préférences") return errors.New("une des alternatives est absente des préférences")
}
nApp := 0
for _, pref := range prefs {
if element == pref {
nApp += 1
}
}
if nApp != 1 {
return errors.New("une alternative apparait plusieurs fois")
} }
} }
} }
...@@ -95,15 +104,21 @@ func Test_checkProfile() { ...@@ -95,15 +104,21 @@ func Test_checkProfile() {
// 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 // et que chaque alternative de alts apparaît exactement une fois par préférences
func checkProfileAlternative(prefs Profile, alts []Alternative) error { func checkProfileAlternative(prefs Profile, alts []Alternative) error {
for _, row := range prefs { for _, pref := range prefs {
e := checkProfile(row, alts) return checkProfile(pref, alts)
if e != nil {
return e
}
} }
return nil return nil
} }
func checkProfileFromProfile(prof Profile) (err error) {
alts := make([]Alternative, 0)
for i := 1; i <= len(prof[0]); i++ {
alts = append(alts, Alternative(i))
}
err = checkProfileAlternative(prof, alts)
return
}
func Test_checkProfileAlternative() { func Test_checkProfileAlternative() {
alts := []Alternative{1, 2, 3, 4, 5} alts := []Alternative{1, 2, 3, 4, 5}
pref1 := []Alternative{5, 3, 1, 4, 2} pref1 := []Alternative{5, 3, 1, 4, 2}
......
package comsoc package comsoc
//majorité simple // majorité simple
// fonctions de bien-être social (social welfare function, SWF) : // fonctions de bien-être social (social welfare function, SWF) :
// retournent un décompte à partir d'un profil // retournent un décompte à partir d'un profil
// En utilisation la méthode de la majorité simple // En utilisation la méthode de la majorité simple
func MajoritySWF(p Profile) (count Count, err error) { func MajoritySWF(p Profile) (count Count, err error) {
count = make(Count) count = make(Count)
err = checkProfileFromProfile(p)
if err != nil {
return nil, err
}
for _, pref := range p { for _, pref := range p {
count[pref[0]]++ count[pref[0]]++
} }
return count, nil return
} }
func MajoritySCF(p Profile) (bestAlts []Alternative, err error) { func MajoritySCF(p Profile) (bestAlts []Alternative, err error) {
...@@ -17,5 +21,5 @@ func MajoritySCF(p Profile) (bestAlts []Alternative, err error) { ...@@ -17,5 +21,5 @@ func MajoritySCF(p Profile) (bestAlts []Alternative, err error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return maxCount(count), nil return maxCount(count), err
} }
package comsoc package comsoc
import("fmt")
import "fmt"
func TieBreakFactory(orderedAlts []Alternative) (func ([]Alternative) (Alternative, error)){
return func (bestAlts []Alternative) (Alternative, error) { func TieBreakFactory(orderedAlts []Alternative) func([]Alternative) (Alternative, error) {
bestAlt := bestAlts[0] return func(bestAlts []Alternative) (Alternative, error) {
for _,alt:= range bestAlts[1:]{ bestAlt := bestAlts[0]
if isPref(alt,bestAlt,orderedAlts){ for _, alt := range bestAlts[1:] {
bestAlt = alt if isPref(alt, bestAlt, orderedAlts) {
} bestAlt = alt
} }
return bestAlt, nil
} }
return bestAlt, nil
}
} }
func Test_tieBreakFactory(){ func Test_tieBreakFactory() {
orderedAlts := []Alternative{8,9,6,1,3,2} orderedAlts := []Alternative{8, 9, 6, 1, 3, 2}
fmt.Println("Ordre strict :", orderedAlts) fmt.Println("Ordre strict :", orderedAlts)
lambda:=TieBreakFactory(orderedAlts) lambda := TieBreakFactory(orderedAlts)
bestAlts := []Alternative{3,6} bestAlts := []Alternative{3, 6}
fmt.Println("Premières alternatives, à départager :", bestAlts) fmt.Println("Premières alternatives, à départager :", bestAlts)
bestAlt,_ := lambda(bestAlts) bestAlt, _ := lambda(bestAlts)
fmt.Println("Première alternative :", bestAlt) fmt.Println("Première alternative :", bestAlt)
} }
func SWFFactory(swf func (Profile) (Count, error), tb func([]Alternative) (Alternative, error)) (func(Profile) ([]Alternative, error)){ func SWFFactory(swf func(Profile) (Count, error), tb func([]Alternative) (Alternative, error)) func(Profile) ([]Alternative, error) {
return func(p Profile) ([]Alternative, error){ return func(p Profile) ([]Alternative, error) {
//récupération du décompte //récupération du décompte
count,_ := swf(p) count, err := swf(p)
if err != nil {
return nil, err
}
//préparation de la sortie //préparation de la sortie
var sorted_alts []Alternative var sortedAlts []Alternative
//PARCOURS DU DECOMPTE //PARCOURS DU DECOMPTE
for len(count) > 0{ for len(count) > 0 {
//On prend les meilleures alternatives (avant tie break) //On prend les meilleures alternatives (avant tie break)
bestAlts := maxCount(count) bestAlts := maxCount(count)
//On supprime les meilleures alternatives du décompte //On supprime les meilleures alternatives du décompte
for alt := range bestAlts{ for alt := range bestAlts {
delete(count, Alternative(alt)) delete(count, Alternative(alt))
} }
//Départage //Départage
for len(bestAlts) > 0{ for len(bestAlts) > 0 {
bestAlt,_ := tb(bestAlts) bestAlt, _ := tb(bestAlts)
//ajout de la meilleure alternative post-tie break //ajout de la meilleure alternative post-tie break
sorted_alts = append(sorted_alts, bestAlt) sortedAlts = append(sortedAlts, bestAlt)
//suppression de l'alternative dans bestAlts //suppression de l'alternative dans bestAlts
indice := rank(bestAlt, bestAlts) indice := rank(bestAlt, bestAlts)
bestAlts=append(bestAlts[:indice], bestAlts[indice+1:]...) bestAlts = append(bestAlts[:indice], bestAlts[indice+1:]...)
//suppression de l'alternativ dans le compte //suppression de l'alternativ dans le compte
delete(count, Alternative(bestAlt)) delete(count, Alternative(bestAlt))
}
} }
return sorted_alts,nil
} }
return sortedAlts, nil
}
} }
func Test_sWFFactory(){ func Test_sWFFactory() {
//Définition de l'Ordre strict //Définition de l'Ordre strict
orderedAlts := []Alternative{8,9,6,1,3,2} orderedAlts := []Alternative{8, 9, 6, 1, 3, 2}
fmt.Println("Ordre strict :", orderedAlts) fmt.Println("Ordre strict :", orderedAlts)
//Construction d'un profil avec alternatives ex aequo //Construction d'un profil avec alternatives ex aequo
profil := make([][]Alternative, 2) profil := make([][]Alternative, 2)
profil[0] = []Alternative{1, 2, 3,4,5,6} profil[0] = []Alternative{1, 2, 3, 4, 5, 6}
profil[1] = []Alternative{3, 2, 1,4,5,6} profil[1] = []Alternative{3, 2, 1, 4, 5, 6}
fmt.Println("Profil :", profil) fmt.Println("Profil :", profil)
//Construction de la fonction Tie Break //Construction de la fonction Tie Break
lambda:=TieBreakFactory(orderedAlts) lambda := TieBreakFactory(orderedAlts)
//Construction de la Social Welfare Factory à partir de la fonction swf + la fonction de TieBreak //Construction de la Social Welfare Factory à partir de la fonction swf + la fonction de TieBreak
mu := SWFFactory(BordaSWF,lambda) mu := SWFFactory(BordaSWF, lambda)
//Construction d'une fonction //Construction d'une fonction
sorted_alts,_ := mu(profil) sorted_alts, _ := mu(profil)
fmt.Println("Alternatives strictement ordonnées selon la méthode de Borda :", sorted_alts) 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)){ func SCFFactory(scf func(p Profile) ([]Alternative, error), tb func([]Alternative) (Alternative, error)) func(Profile) (Alternative, error) {
return func(p Profile) (Alternative, error){ return func(p Profile) (Alternative, error) {
//récupération des meilleures alternatives //récupération des meilleures alternatives
bestAlts,_ := scf(p) bestAlts, err1 := scf(p)
//récupération de la meilleure alternative if err1 != nil {
bestAlt,_ := tb(bestAlts) return Alternative(0), err1
return bestAlt,nil }
//récupération de la meilleure alternative
bestAlt, err2 := tb(bestAlts)
if err2 != nil {
return Alternative(0), err2
}
return bestAlt, nil
} }
} }
func Test_sCFFactory(){ func Test_sCFFactory() {
//Définition de l'Ordre strict //Définition de l'Ordre strict
orderedAlts := []Alternative{8,9,6,1,3,2} orderedAlts := []Alternative{8, 9, 6, 1, 3, 2}
fmt.Println("Ordre strict :", orderedAlts) fmt.Println("Ordre strict :", orderedAlts)
//Construction d'un profil avec alternatives ex aequo //Construction d'un profil avec alternatives ex aequo
profil := make([][]Alternative, 2) profil := make([][]Alternative, 2)
profil[0] = []Alternative{1, 2, 3,4,5,6} profil[0] = []Alternative{1, 2, 3, 4, 5, 6}
profil[1] = []Alternative{3, 2, 1,4,5,6} profil[1] = []Alternative{3, 2, 1, 4, 5, 6}
fmt.Println("Profil :", profil) fmt.Println("Profil :", profil)
//Construction de la fonction Tie Break //Construction de la fonction Tie Break
lambda:=TieBreakFactory(orderedAlts) lambda := TieBreakFactory(orderedAlts)
mu := SCFFactory(BordaSCF,lambda) mu := SCFFactory(BordaSCF, lambda)
//Construction d'une fonction //Construction d'une fonction
best_Alt,_ := mu(profil) best_Alt, _ := mu(profil)
fmt.Println("Meilleure alternative selon la méthode de Borda :", best_Alt) fmt.Println("Meilleure alternative selon la méthode de Borda :", best_Alt)
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment