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

Merge branch 'copeland_and_stv' into 'main'

Copeland and stv

See merge request !9
parents 937b399f 8ced7dea
No related branches found
No related tags found
1 merge request!9Copeland and stv
......@@ -77,6 +77,10 @@ func (rsa *BallotServerAgent) createBallot(w http.ResponseWriter, r *http.Reques
go rsa.handleBallot(resp, cs.BordaSWF, cs.BordaSCF, tb, deadline)
case "approval":
go rsa.handleBallotWithSingleOption(resp, cs.ApprovalSWF, cs.ApprovalSCF, tb, deadline)
case "copeland":
go rsa.handleBallot(resp, cs.CopelandSWF, cs.CopelandSCF, tb, deadline)
case "stv":
go rsa.handleBallot(resp, cs.STV_SWF, cs.STV_SCF, tb, deadline)
default:
w.WriteHeader(http.StatusNotImplemented)
msg := fmt.Sprintf("Unkonwn rule '%s'", req.Rule)
......
package comsoc
\ No newline at end of file
package comsoc
func CopelandSWF(p Profile) (count Count, err error) {
count = make(Count)
alts := make([]Alternative, 0)
for i := 1; i <= len(p[0]); i++ {
alts = append(alts, Alternative(i))
}
err = checkProfileAlternative(p, alts)
if err != nil {
return nil, err
}
for alt1 := 1; alt1 <= len(alts); alt1++ {
for alt2 := alt1 + 1; alt2 <= len(alts); alt2++ {
score1, score2 := 0, 0
for _, pref := range p {
if isPref(Alternative(alt1), Alternative(alt2), pref) {
score1++
} else {
score2++
}
}
if score1 > score2 {
count[Alternative(alt1)]++
count[Alternative(alt2)]--
} else if score2 > score1 {
count[Alternative(alt1)]--
count[Alternative(alt2)]++
}
}
}
return
}
func CopelandSCF(p Profile) (bestAlts []Alternative, err error) {
count, err := CopelandSWF(p)
if err != nil {
return nil, err
}
return maxCount(count), err
}
package comsoc
\ No newline at end of file
package comsoc
func getRandomKey(count Count) Alternative {
for k := range count {
return k
}
return 0 // should never happen
}
func countContains(count Count, alt Alternative) bool {
for k := range count {
if alt == k {
return true
}
}
return false
}
// renvoie une des pires alternatives pour un décompte donné
func minCount(count Count, alts []Alternative) (worstAlt Alternative) {
for _, alt := range alts {
if !countContains(count, alt) {
return alt
}
}
worstAlt = getRandomKey(count)
minPoints := count[worstAlt]
for i, points := range count {
if points < minPoints {
worstAlt = i
minPoints = points
}
}
return worstAlt
}
func STV_SWF(p Profile) (count Count, err error) {
count = make(Count)
alts := make([]Alternative, 0)
for i := 1; i <= len(p[0]); i++ {
alts = append(alts, Alternative(i))
}
err = checkProfileAlternative(p, alts)
if err != nil {
return nil, err
}
nbRounds := len(alts)
for round := 0; round < nbRounds; round++ {
majorityRes := make(Count)
for _, pref := range p {
majorityRes[pref[0]]++
}
worstAlt := minCount(majorityRes, alts)
count[worstAlt] = round
// On enlève la pire alt des alts
alts[rank(worstAlt, alts)] = alts[len(alts)-1]
alts = alts[:len(alts)-1]
// on enlève la pire alt de chacunes des preferences
for i, pref := range p {
pref[rank(worstAlt, pref)] = pref[len(pref)-1]
pref = pref[:len(pref)-1]
p[i] = pref
}
}
return
}
func STV_SCF(p Profile) (bestAlts []Alternative, err error) {
count, err := STV_SWF(p)
if err != nil {
return nil, err
}
return maxCount(count), err
}
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