def Egalitarian_Sexequal_3(mpref, wpref, algo): mrank, wrank = changeStructure(mpref, wpref, n1, n2) #Initialize M M, f = LTIU2(mpref, wpref) Mbest = M bestCost = 2 * n1 * n2 iters = 500 clist = [] start = time.time() while iters and time.time() - start < 2000: f = F(M, mpref, wpref, mrank, wrank) if f != 0: M, f = LTIU2(mpref, wpref) else: cost = eg_cost(M, mrank, wrank) if algo == "eg" else se_cost( M, mrank, wrank) clist.append(cost) if cost < bestCost: bestCost = cost Mbest = M if cost == 0: return M, cost else: neighbors = BreakMarriageSMTI(M, mrank, wrank, mpref, wpref) print("neigbors") for ne in neighbors: print(ne) randwalk = True if random.random() <= 0.2 else False if randwalk: M = neighbors[random.randint(0, len(neighbors) - 1)] else: costs = [eg_cost(nei, mrank, wrank) for nei in neighbors] if algo == "eg" else [ se_cost(nei, mrank, wrank) for nei in neighbors ] min_cost = min(costs) if min_cost < cost: indices = [ i for i, v in enumerate(costs) if v == min_cost ] M = neighbors[random.choice(indices)] else: M = neighbors[random.randint(0, len(neighbors) - 1)] iters -= 1 plt.plot(clist) plt.show() return_cost = eg_cost(Mbest, mrank, wrank) if algo == "eg" else se_cost( Mbest, mrank, wrank) return Mbest, return_cost
def LCV_deney(n1, n2, mpref, wpref, iters): n = n1 mrank, wrank = changeStructure(mpref, wpref, n, n) arraysize = 2 * n M = [-1] * arraysize M = random_match2(M, mrank, n) Mbest = M iterstart = iters y = [] while iters: if ns2(Mbest) == 0: break X = findbps2(M, mrank, wrank, n) y.append(len(X) + ns2(Mbest)) if len(X) == 0: #M is stable #random restart if ns2(M) < ns2(Mbest): Mbest = M M = [-1] * arraysize M = random_match2(M, mrank, n) else: m = man_that_generates_max_bp(M, mrank, wrank, n) randWalk = random.random() if randWalk <= 0.2: pIndex = random.randint(0, len(mpref[m]) - 1) wIndex = random.randint(0, len(mpref[m][pIndex]) - 1) w = mpref[m][pIndex][wIndex] else: w = random_best_woman_for_m(mpref, m) M = RemoveBP2(M, m, w, n) iters -= 1 ns_ = ns2(Mbest) nbp_ = nbp2(Mbest, mrank, wrank, n) steptotal = iterstart - iters return ns_ + nbp_, nbp_, ns_, steptotal, y
def LTIU2(mpref, wpref): n1 = len(mpref) n2 = len(wpref) mrank, wrank = changeStructure(mpref, wpref, n1, n2) arraysize = (n1 + n2) M = [-1] * arraysize M = random_match(M, mrank, n1, n2) Fprev = F(M, mpref, wpref, mrank, wrank) Fbest = Fprev stableFound = False NSbest = 2 * n1 * n2 Mbest = M steps = 5000 print("Random Restart (LTIU)") while steps: nbp, ns = NBP_NS(M, mpref, wpref, mrank, wrank) #nbp = NBP(M, mrank, wrank) #ns = NS(M) f = nbp + ns if stableFound == False and f < Fbest: Fbest = f Mbest = M #If a perfect matching found if f == 0: Mbest = M Fbest = 0 #f break #If a stable (but not perfect) matching found if nbp == 0: stableFound = True #Is it the best Stable matching among stable matchings found so far? if ns < NSbest: Mbest = M NSbest = ns Fbest = f # = ns M = random_match(M, mrank, n1, n2) #If unstable else: #Find neighbors undominated_bps = UND(M, mrank, wrank, steps % 2) neis = [] for un in undominated_bps: copyM = M[:] copyM = RemoveBP(copyM, un, n1) neis.append(copyM) random_walk = True if random.random() <= 0.2 else False if random_walk: M = neis[random.randint(0, len(neis) - 1)] #Choose a random neighbor else: #Choose a neighbor with the minimum evaluation value evaluations = [ F(nei, mpref, wpref, mrank, wrank) for nei in neis ] min_eval = min(evaluations) if min_eval <= f: #if there is an improvement indices = [ i for i, v in enumerate(evaluations) if v == min_eval ] M = neis[random.choice(indices)] else: #no improvement, choose a random neighbor M = neis[random.randint(0, len(neis) - 1)] steps -= 1 nbp, ns = NBP_NS(Mbest, mpref, wpref, mrank, wrank) f = ns + nbp return Mbest, f
evaluations = [F(nei, mpref, wpref, mrank, wrank) for nei in neis] min_eval = min(evaluations) if min_eval <= f: #if there is an improvement indices = [i for i, v in enumerate(evaluations) if v == min_eval] M = neis[random.choice(indices)] else: #no improvement, choose a random neighbor M = neis[random.randint(0, len(neis)-1)] steps -= 1 nbp, ns = NBP_NS(Mbest, mpref, wpref, mrank, wrank) f = ns + nbp return Mbest, f n1 = 20 n2 = n1 mpref, wpref = GentProsser(n1, n2, 0.2, 0.5) mrank, wrank = changeStructure(mpref, wpref, n1, n2) #Initialize M M, f = LTIU2(mpref, wpref) iters = 1000 Mbest = M best_cost = 2*n1*n2 while iters: f = F(M, mpref, wpref, mrank, wrank) if f != 0: M, f = LTIU2(mpref, wpref) else: cost = eg_cost(M, mrank, wrank) if cost == 0: print(M) #return M
def LTIU(mpref, wpref): n1 = len(mpref) n2 = len(wpref) mrank, wrank = changeStructure(mpref, wpref, n1, n2) arraysize = (n1 + n2) M = [-1] * arraysize M = random_match(M, mrank, n1, n2) Fprev = F(M, mpref, wpref, mrank, wrank) Fbest = Fprev stableFound = False NSbest = 2 * n1 * n2 Mbest = M steps = 10000 begin = steps y = [] while steps: print("| LTIU") print("| step:", begin - steps) nbp, ns = NBP_NS(M, mpref, wpref, mrank, wrank) #nbp = NBP(M, mrank, wrank) #ns = NS(M) f = nbp + ns print("| f:", f) print("-------------") y.append(f) if stableFound == False and f < Fbest: Fbest = f Mbest = M #If a perfect matching found if f == 0: Mbest = M Fbest = 0 #f break #If a stable (but not perfect) matching found if nbp == 0: stableFound = True #Is it the best Stable matching among stable matchings found so far? if ns < NSbest: Mbest = M NSbest = ns Fbest = f # = ns M = random_match(M, mrank, n1, n2) #If unstable else: #Find neighbors undominated_bps = UND(M, mrank, wrank, steps % 2) neis = [] for un in undominated_bps: copyM = M[:] copyM = RemoveBP(copyM, un, n1) neis.append(copyM) random_walk = True if random.random() <= 0.2 else False if random_walk: M = neis[random.randint(0, len(neis) - 1)] #Choose a random neighbor else: #Choose a neighbor with the minimum evaluation value evaluations = [ F(nei, mpref, wpref, mrank, wrank) for nei in neis ] min_eval = min(evaluations) if min_eval <= f: #if there is an improvement indices = [ i for i, v in enumerate(evaluations) if v == min_eval ] M = neis[random.choice(indices)] else: #no improvement, choose a random neighbor M = neis[random.randint(0, len(neis) - 1)] steps -= 1 """ plt.plot(y) plt.title("LTIU n:" + str(n1) + ", p1:" + str(p1) + ", p2:"+ str(p2)) plt.xlabel("steps") plt.ylabel("f = nbp + ns") plt.show() """ if Fbest == 0: print("Perfect matching found") elif stableFound == True: print("Stable matching found") else: print("Nonstable matching found") #print(Mbest) nbp, ns = NBP_NS(Mbest, mpref, wpref, mrank, wrank) f = ns + nbp print("ns:", ns, " nbp:", nbp, " f:", f, " steps:", begin - steps) print("------------------------------") return f, nbp, ns, begin - steps, y
def Egalitarian_SexEqual(mpref, wpref, steps, algo): n1 = len(mpref) n2 = len(wpref) mrank, wrank = changeStructure(mpref, wpref, n1, n2) arraysize = (n1 + n2) M = [-1] * arraysize M = random_match(M, mrank, n1, n2) stableFound = False Mbest = M begin = steps fs_return = [] costs_return = [] perfectFound = False stableFound = False while steps: print("| step:", begin - steps) nbp, ns = NBP_NS(M, mpref, wpref, mrank, wrank) cost_val = se_cost(M, mrank, wrank) if algo == "se" else eg_cost( M, mrank, wrank) f = nbp + ns #print("| f:", f) fs_return.append(f) costs_return.append(cost_val) if f == 0 and cost_val == 0: Mbest = M break if nbp == 0: if ns == 0: if perfectFound == True: compare_cost = se_cost(Mbest, mrank, wrank) if algo == "se" else eg_cost( Mbest, mrank, wrank) if compare_cost < cost_val: Mbest = M else: Mbest = M perfectFound = True else: if perfectFound == False: if stableFound == True: if ns < F(Mbest, mpref, wpref, mrank, wrank): Mbest = M else: Mbest = M stableFound = True M = random_match(M, mrank, n1, n2) else: undominated_bps = UND(M, mrank, wrank, steps % 2) #print(undominated_bps) neis = [] for un in undominated_bps: copyM = M[:] copyM = RemoveBP(copyM, un, n1) neis.append(copyM) random_walk = True if random.random() <= 0.2 else False if random_walk: M = neis[random.randint(0, len(neis) - 1)] #Choose a random neighbor else: #Choose a neighbor with the minimum evaluation value f_evals = [F(nei, mpref, wpref, mrank, wrank) for nei in neis] min_eval = min(f_evals) indices = [i for i, v in enumerate(f_evals) if v == min_eval] cost_evals = [se_cost(nei, mrank, wrank) for nei in neis] if algo == "se" else [ eg_cost(nei, mrank, wrank) for nei in neis ] min_cost = min(cost_evals) compare_cost2 = se_cost(M, mrank, wrank) if algo == "se" else eg_cost( M, mrank, wrank) indices2 = [ i for i, v in enumerate(cost_evals) if v == min_cost ] if min_eval < f: #if there is an improvement if min_cost <= compare_cost2: indices3 = [] for i in indices: for j in indices2: if i == j: indices3.append(i) if len(indices3) != 0: M = neis[random.choice(indices3)] else: M = neis[random.choice(indices)] else: #M = neis[random.randint(0, len(neis)-1)] M = neis[random.choice(indices2)] else: M = neis[random.choice(indices2)] #M = neis[random.randint(0, len(neis)-1)] steps -= 1 nbp_val, ns_val = NBP_NS(Mbest, mpref, wpref, mrank, wrank) f_val = nbp_val + ns_val cost_val = se_cost(M, mrank, wrank) if algo == "se" else eg_cost( M, mrank, wrank) return f_val, cost_val, nbp_val, ns_val, fs_return, costs_return, begin - steps
def LTIU_always_min_neighbor(n1, n2, mpref, wpref, steps): mrank, wrank = changeStructure(mpref, wpref, n1, n2) arraysize = (n1 + n2) M = [-1] * arraysize M = random_match(M, mrank, n1, n2) Fprev = F(M, mpref, wpref, mrank, wrank) Fbest = Fprev stableFound = False NSbest = 2 * n1 * n2 Mbest = M begin = steps y = [] while steps: nbp, ns = NBP_NS(M, mpref, wpref, mrank, wrank) #nbp = NBP(M, mrank, wrank) #ns = NS(M) f = nbp + ns y.append(f) if stableFound == False and f < Fbest: Mbest = M #If a perfect matching found if f == 0: Mbest = M Fbest = 0 #f break #If a stable (but not perfect) matching found if nbp == 0: stableFound = True #Is it the best Stable matching among stable matchings found so far? if ns < NSbest: Mbest = M NSbest = ns Fbest = f # = ns M = random_match(M, mrank, n1, n2) #If unstable else: if stableFound == False and f < Fbest: Fbest = f Mbest = M #Find neighbors undominated_bps = UND(M, mrank, wrank, steps % 2) #undominated_bps = UND_BP_MFWS(M, mpref, wpref, mrank, wrank) #undominated_bps = UND_BP_WFMS(M, mpref, wpref, mrank, wrank) #print(undominated_bps) neis = [] for un in undominated_bps: copyM = M[:] copyM = RemoveBP(copyM, un, n1) neis.append(copyM) random_walk = 1 if random.random() <= 0.2 else 0 if random_walk: M = neis[random.randint(0, len(neis) - 1)] #Choose a random neighbor else: #Choose a neighbor with the minimum evaluation value evaluations = [ F(nei, mpref, wpref, mrank, wrank) for nei in neis ] min_eval = min(evaluations) if min_eval < f: #if there is an improvement indices = [ i for i, v in enumerate(evaluations) if v == min_eval ] M = neis[random.choice(indices)] else: #no improvement, random restart #M = random_match(M, mrank, n1, n2) indices = [ i for i, v in enumerate(evaluations) if v == min_eval ] M = neis[random.choice(indices)] steps -= 1 #print(Mbest) nbp, ns = NBP_NS(Mbest, mpref, wpref, mrank, wrank) f = ns + nbp return f, nbp, ns, begin - steps, y