@@ -19,6 +19,9 @@ class Position:
1919 preferred_by : Collection [AbstractParticipant ] # preferred by participant (less important)
2020 label : Optional [str ] = None
2121 aux_score : float = 0.0 # additional score control in range [0,1]
22+ designation_only : bool = (
23+ False # if this Position was created purely out of overdesignation, mark it here
24+ )
2225
2326 def __post_init__ (self ):
2427 self .required_qualifications = frozenset (self .required_qualifications )
@@ -128,27 +131,41 @@ def score_pairing(
128131 required_value = padded_participant_count * sum (
129132 (base_score , preferred_value , max_skill_value , confirmed_value , max_aux_value )
130133 )
131- designated_value = required_value ** 2
132- unqualified_penalty = designated_value ** 2
134+ designated_unqualified_value = required_value ** 2
135+ designated_and_qualified_value = 2 * designated_unqualified_value
136+ undesignated_unqualified_value = designated_unqualified_value ** 2
133137
134138 is_designated = participant in position .designated_for
135139 # optimally, we should reject a pairing for a participant designated for another position,
136140 # but we don't have that info here.
141+ is_qualified = position .required_skill <= participant .skill
137142
138- if not is_designated and not position . required_skill <= participant . skill :
143+ if not is_designated and not is_qualified :
139144 # the participant does not have some required skill
140- return - unqualified_penalty # avoid matching unqualified participants
145+ return - undesignated_unqualified_value # avoid matching unqualified participants
141146
142147 score = base_score
143148 if is_designated :
144- score += designated_value
149+ if is_qualified :
150+ score += designated_and_qualified_value
151+ else :
152+ # designated participants get assigned even if they don't qualify, and at a lower score
153+ score += designated_unqualified_value
154+
145155 if participant in position .preferred_by :
146156 score += preferred_value
147157 if position .required :
148158 score += required_value
149159 if participant in confirmed_participants :
150160 score += confirmed_value
151- score += position .skill_level * max_skill_value
161+
162+ if is_qualified :
163+ # if qualified, lets prefer high skill positions
164+ score += position .skill_level * max_skill_value
165+ else :
166+ # if not qualified (but designated), let's prefer low skill positions
167+ score -= position .skill_level * max_skill_value
168+
152169 score += position .aux_score * max_aux_value
153170 return score
154171
0 commit comments