Skip to content
Snippets Groups Projects
Commit 70ca1397 authored by Antoine Kryus's avatar Antoine Kryus
Browse files

merge adding pipeline for STV and scoring

parents 5f143eb6 fe8599ec
No related branches found
No related tags found
No related merge requests found
......@@ -34,4 +34,6 @@ go run cmd\launch_automatic_voting.go
- Gagnant de Condorcet
- Méthode de Copeland
- Scrutin majoritaire
- Single Transferable Vote
- Scoring
- \+ Fonction de tie-break
......@@ -112,7 +112,7 @@ func (rba *RestBallotAgent) doNewBallot(w http.ResponseWriter, r *http.Request)
}
log.Println("NEW BALLOT: Number of alternatives: ", req.Alts)
if rba.rule != "majority" && rba.rule != "borda" && rba.rule != "copeland" && rba.rule != "condorcet" && rba.rule != "approval" && rba.rule != "simple transferable vote" {
if rba.rule != "majority" && rba.rule != "borda" && rba.rule != "copeland" && rba.rule != "condorcet" && rba.rule != "approval" && rba.rule != "single transferable vote" && rba.rule != "scoring" {
w.WriteHeader(http.StatusNotImplemented)
msg := fmt.Sprintf("501: vote rule \"'%s'\" is not impemented in the system", req.Rule)
w.Write([]byte(msg))
......@@ -146,9 +146,12 @@ func (rba *RestBallotAgent) doNewBallot(w http.ResponseWriter, r *http.Request)
case "approval":
rba.count, err = comsoc.ApprovalSWF(rba.pfl, rba.options)
bestAlts, err = comsoc.ApprovalSCF(rba.pfl, rba.options)
case "simple transferable vote":
case "single transferable vote":
rba.count, err = comsoc.SingleTransferableVoteSWF(rba.pfl)
bestAlts, err = comsoc.SingleTransferableVoteSCF(rba.pfl)
case "scoring":
rba.count, err = comsoc.ScoringSWF(rba.pfl, rba.options)
bestAlts, err = comsoc.ScoringSCF(rba.pfl, rba.options)
}
// the tie-break is in the order of rba.alts
tb := comsoc.TieBreakFactory(rba.alts)
......@@ -222,7 +225,7 @@ func (rba *RestBallotAgent) doVote(w http.ResponseWriter, r *http.Request) {
// Process options case
if (len(req.Options) > 0 && rba.rule != "approval") || (len(req.Options) > 1 && rba.rule == "approval") { // modify conditions according to options implemented
if (len(req.Options) > 0 && rba.rule != "approval" && rba.rule != "scoring") || (len(req.Options) > 1 && rba.rule == "approval") { // modify conditions according to options implemented
log.Println("VOTE: Error in given options.")
w.WriteHeader(http.StatusNotImplemented)
msg := fmt.Sprintf("501: Approval threshold only accept threshold for approval (in a list, example: 'options: [3]' in JSON).")
......@@ -231,6 +234,8 @@ func (rba *RestBallotAgent) doVote(w http.ResponseWriter, r *http.Request) {
}
if rba.rule == "approval" {
rba.options = append(rba.options, int(req.Options[0]))
} else if rba.rule == "scoring" {
rba.options = req.Options
}
log.Println(rba.pfl)
......
......@@ -20,6 +20,14 @@ func shuffle(n int, pref []comsoc.Alternative) []comsoc.Alternative {
return pref
}
func makeVector(n int) []int {
vec := make([]int, n)
for i, _ := range vec {
vec[i] = 20 + i
}
return vec
}
func main() {
const url1 = ":8080"
const url2 = "http://localhost:8080"
......@@ -30,7 +38,7 @@ func main() {
choice = -1
ts = -1
for choice < 0 || choice > 5 {
for choice < 0 || choice > 6 {
fmt.Println("Choose the voting rule amonst")
fmt.Println("0: Borda")
......@@ -38,7 +46,8 @@ func main() {
fmt.Println("2: Copeland")
fmt.Println("3: Approval")
fmt.Println("4: Single Transferable Vote")
fmt.Println("5: Randomly choose between all the latters")
fmt.Println("5: Scoring (default vector is <20,21,22,23,...>)")
fmt.Println("6: Randomly choose between all the latters")
fmt.Println("Enter a number: ")
fmt.Scanln(&choice)
......@@ -54,6 +63,10 @@ func main() {
fmt.Println("Enter an integer number for the threshold : ")
fmt.Scanln(&ts)
case 4:
rule = "single transferable vote"
case 5:
rule = "scoring"
case 6:
rules := []string{"borda", "approval", "copeland", "majority"}
rand.Seed(time.Now().UnixNano())
rule = rules[rand.Intn(4)]
......@@ -90,15 +103,18 @@ func main() {
options = append(options, ts)
}
if rule == "scoring" {
options = makeVector(n)
}
deadline := time.Now().Add(time.Second * 10)
server := agt.NewRestBallotAgent(":8080")
//log.Println("MAIN: Server starting...")
go server.Start()
//log.Println("MAIN: Starting voter agents...")
voterAgents := make([]agt2.RestVoterAgent, 0, m)
for i := 0; i < n; i++ {
for i := 0; i < m; i++ {
id := i
ballotID := 1
regle := rule
......
......@@ -180,3 +180,50 @@ func TestCondorcetWinner(t *testing.T) {
t.Errorf("no best alternative for prefs2")
}
}
func TestScoringSWF(t *testing.T) {
prefs := [][]Alternative{
{3, 1, 2, 4},
{3, 1, 2, 4},
{3, 4, 2, 1},
{4, 3, 2, 1},
{1, 4, 3, 2},
}
scores := []int{20, 21, 22, 23}
res, _ := ScoringSWF(prefs, scores)
if res[1] != 107 {
t.Errorf("error, result for 1 should be 107, %d computed", res[1])
}
if res[2] != 104 {
t.Errorf("error, result for 2 should be 104, %d computed", res[2])
}
if res[3] != 112 {
t.Errorf("error, result for 3 should be 112, %d computed", res[3])
}
if res[4] != 107 {
t.Errorf("error, result for 3 should be 107, %d computed", res[3])
}
}
func TestScoringSCF(t *testing.T) {
prefs := [][]Alternative{
{3, 1, 2, 4},
{3, 1, 2, 4},
{3, 4, 2, 1},
{4, 3, 2, 1},
{1, 4, 3, 2},
}
scores := []int{20, 21, 22, 23}
res, err := ScoringSCF(prefs, scores)
if err != nil {
t.Error(err)
}
if len(res) != 1 || res[0] != 3 {
t.Errorf("error, 1 should be the only best Alternative")
}
}
package comsoc
func ScoringSWF(p Profile, scores []int) (count Count, err error) {
count = make(map[Alternative]int)
for _, profile := range p {
for i, alt := range profile {
count[alt] += scores[len(profile)-1-i]
}
}
return count, nil
}
func ScoringSCF(p Profile, scores []int) (bestAlts []Alternative, err error) {
count, erreur := ScoringSWF(p, scores)
return maxCount(count), erreur
}
......@@ -2,7 +2,7 @@ package comsoc
import (
"errors"
//"math"
"math"
)
type Alternative int
......@@ -26,7 +26,7 @@ func isPref(alt1, alt2 Alternative, prefs []Alternative) bool {
// renvoie les meilleures alternatives pour un décompte donné
func maxCount(count Count) (bestAlts []Alternative) {
max := -9999999999//math.MinInt
max := math.MinInt
for k, v := range count {
switch {
case v == max:
......@@ -119,7 +119,7 @@ func retrieveAlt(p Profile, a Alternative) Profile {
}
func minCount(count Count) (bestAlts []Alternative) {
min := 9999999999//math.MaxInt
min := math.MaxInt
for k, v := range count {
switch {
case v == min:
......
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