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
Exemple #5
0
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
Exemple #6
0
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