def __init__(self, matching, mode="m_opt"): self.mode = mode if mode == "m_opt": self.matching = matching elif mode == "w_opt": self.matching = Matching(matching.females, matching.males, matching.females_pref, matching.males_pref) else: raise Exception(f"unknown mode: {mode}")
def mock_matching_smti(mock_nr=0): if mock_nr == 0: return Matching(deepcopy(males), deepcopy(females), deepcopy(males_pref_smti), deepcopy(females_pref_smti)) elif mock_nr == 1: return Matching(deepcopy(males), deepcopy(females), deepcopy(males_pref_smti_1), deepcopy(females_pref_smti_1)) elif mock_nr == 2: return Matching(deepcopy(males[:2]), deepcopy(females[:2]), deepcopy(males_pref_smti_2), deepcopy(females_pref_smti_2)) else: raise Exception(f"unknown mock nr {mock_nr}")
def create_smp_instance(size: int): """ create a random smp instance :param size: size of the instance :return: """ males, females = ut.create_males_and_females(size) males_pref, females_pref = _create_sm_preferences(males, females) return Matching(males, females, males_pref, females_pref)
def create_smti_instance(size: int, g1: float, g2: float): """ create one instance for SMTI :param size: how many males females <=> size :param g1: (0,1] => possibility that an element will be IN the preflist => determines the lenght :param g2: (0,1] => possibility of a tie :return: """ assert 0 < g1 <= 1 and 0 < g2 <= 1 males, females = ut.create_males_and_females(size) males_pref = _create_smti_preference(males, females, size, g1, g2) females_pref = _create_smti_preference(females, males, size, g1, g2) return Matching(males, females, males_pref, females_pref)
def break_men_ties(self): new_mens_pref = {} for man in self.matching.males: mans_pref = dict( sorted(self.matching.males_pref[man].items(), key=lambda x: x[1])) new_m_pref = {} # of single man new_index = 0 for w, index in mans_pref.items(): new_m_pref[w] = new_index new_index += 1 new_mens_pref[man] = new_m_pref return Matching(deepcopy(self.matching.males), deepcopy(self.matching.females), new_mens_pref, deepcopy(self.matching.females_pref))
def get_smp(index_f: int, size: int): """ get a smp from file with index index_f :param index_f: :param size: :return: """ dir_name = get_smp_folder(size) with open(f"{dir_name}/{index_f}.json", 'r') as fp: meta = json.load(fp) males, females = ut.create_males_and_females(meta["size"]) matching = Matching(males, females, meta["males_pref"], meta["females_pref"], solutions=meta["possible_solutions"]) return matching
def get_smti(index_f: int, size: int) -> Matching: """ Get one stored SMTI instance, by its size, p1, p2, index_f :param size: the size of the smp instance :param p1: (0,1] => possibility that an element will be IN the preflist => determines the lenght :param p2: (0,1] => possibility of a tie :param index_f: index of the SMTI instance (unique int) :return: """ dir_name = get_smti_folder(size) with open(f"{dir_name}/{index_f}.json", 'r') as fp: meta = json.load(fp) males, females = ut.create_males_and_females(meta["size"]) matching = Matching(males, females, meta["males_pref"], meta["females_pref"], solutions=meta["possible_solutions"], meta=meta["meta"]) assert matching is not None return matching
def solve(self): matches_m = {} matches_w = {} proposal_m = {m: [] for m in self.matching.males} unmatched_males = deque(self.get_active()) m_pref = deepcopy(self.matching.males_pref) while not len(unmatched_males) == 0: m_alone = unmatched_males[0] most_desired = _get_most_desired(m_pref[m_alone], proposal_m[m_alone]) if most_desired is None: unmatched_males.remove(m_alone) continue proposal_m[m_alone].append(most_desired) if most_desired not in matches_w.keys(): if self.matching.is_acceptable(m_alone, most_desired): matches_w[most_desired] = m_alone matches_m[m_alone] = most_desired unmatched_males.remove(m_alone) else: if self.is_better_partner(most_desired, m_alone, matches_w[most_desired]): unmatched_males.remove(m_alone) unmatched_males.append(matches_w[most_desired]) proposal_m[matches_w[most_desired]].append(most_desired) del matches_m[matches_w[most_desired]] matches_w[most_desired] = m_alone matches_m[m_alone] = most_desired else: unmatched_males.rotate(1) if self.mode == "m_opt": return Solution(self.matching, matches_m) elif self.mode == "w_opt": matching = Matching(self.matching.females, self.matching.males, self.matching.females_pref, self.matching.males_pref) return Solution(matching, matches_w) else: raise Exception(f"unknown mode: {self.mode}")
def from_shiftbrk(males, females, males_pref, females_pref, all_ties_m, all_ties_w): tmp = Matching(males, females, males_pref, females_pref) return ShiftBrkMatching(tmp, all_ties_m=all_ties_m, all_ties_w=all_ties_w)
class StandardSMP: def __init__(self, matching, mode="m_opt"): self.mode = mode if mode == "m_opt": self.matching = matching elif mode == "w_opt": self.matching = Matching(matching.females, matching.males, matching.females_pref, matching.males_pref) else: raise Exception(f"unknown mode: {mode}") def get_active(self): return self.matching.males def is_better_partner(self, p_1, p_2, p_3): """ Check if p_2 would be a better partner for p_1 in comparison to p_3 :param p_1: :param p_2: :param p_3: :return: """ return self.matching.prefers(p_1, p_2, p_3) and self.matching.is_acceptable(p_1, p_2) def solve(self): matches_m = {} matches_w = {} proposal_m = {m: [] for m in self.matching.males} unmatched_males = deque(self.get_active()) m_pref = deepcopy(self.matching.males_pref) while not len(unmatched_males) == 0: m_alone = unmatched_males[0] most_desired = _get_most_desired(m_pref[m_alone], proposal_m[m_alone]) if most_desired is None: unmatched_males.remove(m_alone) continue proposal_m[m_alone].append(most_desired) if most_desired not in matches_w.keys(): if self.matching.is_acceptable(m_alone, most_desired): matches_w[most_desired] = m_alone matches_m[m_alone] = most_desired unmatched_males.remove(m_alone) else: if self.is_better_partner(most_desired, m_alone, matches_w[most_desired]): unmatched_males.remove(m_alone) unmatched_males.append(matches_w[most_desired]) proposal_m[matches_w[most_desired]].append(most_desired) del matches_m[matches_w[most_desired]] matches_w[most_desired] = m_alone matches_m[m_alone] = most_desired else: unmatched_males.rotate(1) if self.mode == "m_opt": return Solution(self.matching, matches_m) elif self.mode == "w_opt": matching = Matching(self.matching.females, self.matching.males, self.matching.females_pref, self.matching.males_pref) return Solution(matching, matches_w) else: raise Exception(f"unknown mode: {self.mode}")
def mock_matching_smp(): return Matching(deepcopy(males), deepcopy(females), deepcopy(males_pref_smp), deepcopy(females_pref_smp))