Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
QUORUM ?= 3
MALFUNCTION ?= 0
DF_MAX_RESULT := $(shell expr $(QUORUM) + 5)
PATH_PROJECT_JAR = target/election_structure-0.0.1-SNAPSHOT.jar
PROJECT_GROUP = election_structure
JADE_AGENTS = election_structure:$(PROJECT_GROUP).App($(QUORUM), $(MALFUNCTION));
JADE_AGENTS = election_structure:$(PROJECT_GROUP).App($(QUORUM));
JADE_FLAGS = -gui -jade_domain_df_maxresult $(DF_MAX_RESULT) -agents "$(JADE_AGENTS)"

.PHONY:
Expand Down Expand Up @@ -40,7 +39,5 @@ help:
@echo " $$ make help"
@echo " Shows this help resume"
@echo ""
@echo "If wanted it's possible to change the quantity of agents by adding the variable QUORUM to the command, as seen in the next line"
@echo " $$ make build-and-run QUORUM=<Quantity of agents>"
@echo "It's possible to activate a random agent malfunction to test timeout more effectively, as seen in the next line"
@echo " $$ make build-and-run MALFUNCTION=1"
@echo "If wanted it's possible to change the quantity of agents by adding the variable QUORUM (with a value equal or greater than 1) to the command, as seen in the next line"
@echo " $$ make build-and-run QUORUM=<Quantity of agents>"
1 change: 0 additions & 1 deletion src/main/java/election_structure/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ protected void setup() {
int votersQuorum = 0;
if (args != null && args.length > 0) {
votersQuorum = Integer.parseInt(args[0].toString());
randomAgentMalfunction = (Integer.parseInt(args[1].toString()) > 0);
}

int votingStarter = rand.nextInt(votersQuorum);
Expand Down
127 changes: 118 additions & 9 deletions src/main/java/election_structure/Ballot.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,35 @@

import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;

import jade.core.AID;
import jade.core.behaviours.OneShotBehaviour;
import jade.core.behaviours.WakerBehaviour;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;

public class Ballot extends BaseAgent {

private Hashtable<AID, Types> registeredVoters;
private ArrayList<AID> registeredCandidates;
private Hashtable<Integer, AID> registeredCandidates;

private Hashtable<Types, Integer> receivedVotes;
private Hashtable<Integer, Map<Types, Integer>> receivedVotes;
private Hashtable<Types, Integer> votingWeights;

private AtomicInteger receivedVotesCnt;

private Boolean votesCollected = false;

private final transient Object lock = new Object();

@Override
protected void setup() {

Expand All @@ -28,7 +39,9 @@ protected void setup() {
logger.log(Level.INFO, "I'm the ballot!");
this.registerDF(this, "Ballot", "ballot");


receivedVotes = new Hashtable<>();

receivedVotesCnt = new AtomicInteger(0);
addBehaviour(handleMessages());

ArrayList<DFAgentDescription> foundAgent = new ArrayList<>(
Expand Down Expand Up @@ -60,17 +73,58 @@ public void action () {
}

setupBallot();
} else {

} else if (msg.getContent().startsWith(Integer.toString(votingCode))) {
Types voterType = registeredVoters.get(msg.getSender());
int vote = Integer.parseInt(splittedMsg[1]);

if(!registeredCandidates.containsKey(vote)) vote = -1;

synchronized(lock){
Map<Types, Integer> updateMap = receivedVotes.get(vote);

if (updateMap == null) updateMap = new EnumMap<>(Types.class);

updateMap.put(voterType, updateMap.get(voterType) == null? 1 : updateMap.get(voterType) + 1);
receivedVotes.put(vote, updateMap);

if(receivedVotesCnt.incrementAndGet() == 1){
addBehaviour(timeoutBehaviour("collectVotes", TIMEOUT_LIMIT*3));
}

if(receivedVotesCnt.get() == registeredVoters.size()){
votesCollected = true;
computeResults();
}
}
} else {
logger.log(Level.INFO,
String.format("%s %s %s", getLocalName(), UNEXPECTED_MSG, msg.getSender().getLocalName()));
}
}
};
}

@Override
protected WakerBehaviour timeoutBehaviour( String motivation, long timeout) {
return new WakerBehaviour(this, timeout) {
private static final long serialVersionUID = 1L;

@Override
protected void onWake() {
if ( motivation.equals("collectVotes") && !votesCollected) {
votesCollected = true;
logger.log(Level.WARNING,
String.format("%s Agent voting time window ended! %s", ANSI_YELLOW, ANSI_RESET));
computeResults();
}
}
};
}

private void setupBallot () {
receivedVotes = new Hashtable<>();
registeredCandidates = new ArrayList<>();
registeredCandidates = new Hashtable<>();
registeredVoters = new Hashtable<>();

ArrayList<DFAgentDescription> foundVoters = new ArrayList<>(
Expand All @@ -86,7 +140,7 @@ private void setupBallot () {
if ( Arrays.toString(Types.values()).contains(el.getName()) ) {
registeredVoters.put(voter.getName(), Types.valueOf(el.getName()));
} else if ( el.getName().equals("Candidate") ) {
registeredCandidates.add(voter.getName());
registeredCandidates.put( Integer.parseInt(el.getType()), voter.getName());
}
}
}
Expand All @@ -95,13 +149,13 @@ private void setupBallot () {
e.printStackTrace();
}

if ( registeredCandidates.size() < 1 || registeredVoters.size() < 2 ) {
if ( registeredCandidates.isEmpty() || registeredVoters.size() < 2 ) {
logger.log(Level.WARNING, String.format("%s THERE CANNOT BE AN ELECTION WITH NO CANDIDATES OR NOT ENOUGH QUORUM %s", ANSI_YELLOW, ANSI_RESET));

ACLMessage msg = new ACLMessage(ACLMessage.INFORM);

ArrayList<DFAgentDescription> foundMediators = findMediators( new String[]{ Integer.toString(votingCode) } );
if ( foundMediators.size() > 0 ) {
if ( !foundMediators.isEmpty() ) {
for ( DFAgentDescription fndMed : foundMediators ) {
msg.addReceiver(fndMed.getName());
}
Expand All @@ -123,7 +177,7 @@ private void startElection () {
ACLMessage msg = new ACLMessage(ACLMessage.INFORM);

ArrayList<DFAgentDescription> foundMediators = findMediators( new String[]{ Integer.toString(votingCode) } );
if ( foundMediators.size() > 0 ) {
if ( !foundMediators.isEmpty() ) {
for ( DFAgentDescription fndMed : foundMediators ) {
msg.addReceiver(fndMed.getName());
}
Expand All @@ -136,4 +190,59 @@ private void startElection () {
e.printStackTrace();
}
}

private void computeResults() {
HashMap<Integer, Integer> results = new HashMap<>();

int sum;

int maxVote = -1;

ArrayList<Integer> winnerCandidates = new ArrayList<>();

for(Map.Entry<Integer, Map<Types, Integer>> entry : receivedVotes.entrySet()){
sum = 0;
Map<Types, Integer> votesCount = entry.getValue();

for(Map.Entry<Types, Integer> entry2 : votesCount.entrySet()){
sum += votingWeights.get(entry2.getKey()) * entry2.getValue();
}

results.put(entry.getKey(), sum);

if(sum == maxVote){
winnerCandidates.add(entry.getKey());
}

if(sum > maxVote){
maxVote = sum;
winnerCandidates.clear();
winnerCandidates.add(entry.getKey());
}

}

ACLMessage msg = new ACLMessage(ACLMessage.INFORM);

msg.addReceiver(findMediators(new String[]{ Integer.toString(votingCode) }).get(0).getName());

StringBuilder strBld = new StringBuilder();
for ( Integer winner : winnerCandidates ) {
strBld.append(String.format("%d ", winner));
}

String winners = strBld.toString().trim();
msg.setContent(String.format("%s WinnersCount %d VotesCount %d Winners %s", "RESULTS", winnerCandidates.size(), maxVote, winners));
send(msg);

strBld.setLength(0);
for ( Map.Entry<Integer,Integer> entry : results.entrySet() ) {
strBld.append(String.format("%d %d ", entry.getKey(), entry.getValue()));
}

String voteLog = strBld.toString().trim();
msg.setContent(String.format("%s Size %d %s", "ELECTIONLOG", results.size(),voteLog));
send(msg);

}
}
1 change: 0 additions & 1 deletion src/main/java/election_structure/BaseAgent.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ public abstract class BaseAgent extends Agent {
protected static final Logger logger = Logger.getLogger(BaseAgent.class.getName());

protected static final Long TIMEOUT_LIMIT = 1000L;
protected static boolean randomAgentMalfunction = false;
protected boolean brokenAgent = false;
protected boolean candidate = false;

Expand Down
Loading