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 |
|
---|