[100] | 1 | from typing import List
|
---|
| 2 |
|
---|
| 3 | from tudelft_utilities_logging.Reporter import Reporter
|
---|
| 4 |
|
---|
| 5 | from geniusweb.deadline.Deadline import Deadline
|
---|
| 6 | from geniusweb.protocol.session.SessionProtocol import SessionProtocol
|
---|
| 7 | from geniusweb.protocol.session.SessionSettings import SessionSettings
|
---|
| 8 | from geniusweb.protocol.session.TeamInfo import TeamInfo
|
---|
| 9 | from geniusweb.protocol.tournament.Team import Team
|
---|
| 10 | from geniusweb.references.PartyWithProfile import PartyWithProfile
|
---|
| 11 | from geniusweb.voting.VotingEvaluator import VotingEvaluator
|
---|
| 12 |
|
---|
| 13 |
|
---|
| 14 | class MOPACSettings (SessionSettings):
|
---|
| 15 | '''
|
---|
| 16 | Settings for MOPAC negotiation. in MOPAC, each party may get a "power"
|
---|
| 17 | parameter containing an natural number ≤1.
|
---|
| 18 | '''
|
---|
| 19 |
|
---|
| 20 | def __init__(self, participants:List[TeamInfo] ,
|
---|
| 21 | deadline:Deadline ,
|
---|
| 22 | votingevaluator:VotingEvaluator):
|
---|
| 23 | '''
|
---|
| 24 | @param participants the list of {@link PartyWithProfile} in clockwise
|
---|
| 25 | order. There must be at least 2 to run the MOPAC
|
---|
| 26 | protocol. This is not tested in the constructor
|
---|
| 27 | because this can be initialized with less, for use in
|
---|
| 28 | TournamentSettings.
|
---|
| 29 | @param deadline the {@link Deadline} for the negotiation
|
---|
| 30 | @param votingeval the {@link VotingEvaluator} to use.
|
---|
| 31 | '''
|
---|
| 32 | self._participants = participants;
|
---|
| 33 | self._deadline = deadline;
|
---|
| 34 | if participants == None or deadline == None or votingevaluator == None:
|
---|
| 35 | raise ValueError(
|
---|
| 36 | "participants, deadline and votingeval must be not none")
|
---|
| 37 | self._votingevaluator = votingevaluator
|
---|
| 38 | self._checkTeams();
|
---|
| 39 |
|
---|
| 40 | def getMaxRunTime(self)->float:
|
---|
| 41 | return self._deadline.getDuration() / 1000.
|
---|
| 42 |
|
---|
| 43 | def getProtocol(self, logger:Reporter) -> SessionProtocol :
|
---|
| 44 | from geniusweb.protocol.session.mopac.MOPACState import MOPACState
|
---|
| 45 | from geniusweb.protocol.session.mopac.MOPAC import MOPAC
|
---|
| 46 |
|
---|
| 47 | return MOPAC(MOPACState(None, [], None, self, {}), logger)
|
---|
| 48 |
|
---|
| 49 | def getTeams(self ) -> List[TeamInfo] :
|
---|
| 50 | return list(self._participants)
|
---|
| 51 |
|
---|
| 52 | def getParticipants(self ) -> List[TeamInfo] :
|
---|
| 53 | '''
|
---|
| 54 | bit hacky, same as getTeams, for deserialization...
|
---|
| 55 | '''
|
---|
| 56 | return list(self._participants)
|
---|
| 57 |
|
---|
| 58 | def getDeadline(self)-> Deadline :
|
---|
| 59 | '''
|
---|
| 60 | @return the deadline for this negotiation
|
---|
| 61 | '''
|
---|
| 62 | return self._deadline
|
---|
| 63 |
|
---|
| 64 | def getAllParties(self)->List[PartyWithProfile] :
|
---|
| 65 | return [ particip.getParties()[0] for particip in self._participants]
|
---|
| 66 |
|
---|
| 67 |
|
---|
| 68 | def getVotingEvaluator(self)->VotingEvaluator :
|
---|
| 69 | '''
|
---|
| 70 | @return a class that allows us to evaluate the voting results in
|
---|
| 71 | different ways, selectable by the user.
|
---|
| 72 | '''
|
---|
| 73 | return self._votingevaluator
|
---|
| 74 |
|
---|
| 75 | def With(self, team:TeamInfo ) -> "MOPACSettings" :
|
---|
| 76 | if team.getSize() != 1:
|
---|
| 77 | raise ValueError(
|
---|
| 78 | "Added party must have one party but got " + str(team))
|
---|
| 79 | newparts:List[TeamInfo] = list(self._participants)
|
---|
| 80 | newparts.append(team)
|
---|
| 81 | return MOPACSettings(newparts, self._deadline, self._votingevaluator)
|
---|
| 82 |
|
---|
| 83 | def __repr__(self)->str:
|
---|
| 84 | return "MOPACSettings[" + str(self._participants) + "," +\
|
---|
| 85 | str(self._deadline) + "," + \
|
---|
| 86 | type(self._votingevaluator).__name__ + "]";
|
---|
| 87 |
|
---|
| 88 | def getTeamSize(self)->int:
|
---|
| 89 | return 1;
|
---|
| 90 |
|
---|
| 91 | def __hash__(self):
|
---|
| 92 | return hash((tuple(self._participants), self._deadline, self._votingevaluator))
|
---|
| 93 |
|
---|
| 94 | def __eq__(self, other):
|
---|
| 95 | return isinstance(other, self.__class__)\
|
---|
| 96 | and self._participants == other._participants \
|
---|
| 97 | and self._deadline == other._deadline \
|
---|
| 98 | and self._votingevaluator == other._votingevaluator
|
---|
| 99 |
|
---|
| 100 | def _checkTeams(self):
|
---|
| 101 | '''
|
---|
| 102 | @throws IllegalArgumentException if teams have improper power settings.
|
---|
| 103 | '''
|
---|
| 104 | for team in self._participants:
|
---|
| 105 | if team.getSize() != 1:
|
---|
| 106 | raise ValueError("All teams must be size 1 but found " + str(team))
|
---|
| 107 | party = team.getParties()[0]
|
---|
| 108 | if 'power' in party.getParty().getParameters().getParameters():
|
---|
| 109 | power = party.getParty().getParameters().get("power")
|
---|
| 110 | if not isinstance(power, int):
|
---|
| 111 | raise ValueError(
|
---|
| 112 | "parameter 'power' for party" + str(party)
|
---|
| 113 | + " must be integer but found " + str(power))
|
---|
| 114 | if power < 1:
|
---|
| 115 | raise ValueError(
|
---|
| 116 | "parameter 'power' for party" + str(party)
|
---|
| 117 | + " must be >=1 but found " + str(power))
|
---|
| 118 |
|
---|