Beispiel #1
0
def test_can_get_better_than_1():
    preferences = read_instance(60, 25, 5, 0)
    file = "C:\\Users\\Sofia\\Documents\\level5project\\SRI_IP\\data\\outputs\\ASP\\almost-SRI\\output-almost-60-25.txt"
    solution = parse_answers(file)[4]
    better_options = can_get_better_than_current_partner(
        preferences, get_partners(solution), 41)
    assert set(better_options) == set([23])
Beispiel #2
0
def test_feasibility_checker():
    for size in [40, 60, 80]:
        for density in [25, 50, 75, 100]:
            if size == 40 and density == 25:
                continue
            blocking_pairs = parse_blocking_pairs(size, density, True)
            answers = parse_answers(
                "C:\\Users\\Sofia\\Documents\\level5project\\SRI_IP\\data\\outputs\\ASP\\almost-SRI\\output-almost-%d-%d.txt"
                % (size, density))
            if size == 40 and density == 50:
                answers = [None] + answers
                blocking_pairs = [None] + blocking_pairs
            for i, answer in enumerate(answers):
                # Known non-existing/weird answers
                if (size == 40 and density == 50
                        and i == 0) or (size == 60 and density == 25
                                        and i == 19):
                    continue
                preferences = read_instance(size, density, i + 1, 0)
                print(size, density, i + 1)
                feasibility = check_feasibility(preferences, answer)
                assert (not feasibility and not blocking_pairs[i]) or (set(
                    feasibility[0]) == blocking_pairs[i])
Beispiel #3
0
def create_SRI(preferences,
               density=None,
               index=None,
               optimisation=OptimalityCriteria.NONE):
    if density is not None:
        if index is not None:
            preferences = read_instance(preferences, density, index)
        else:
            raise (ValueError("Too few arguments", preferences, density,
                              index))
    elif type(preferences) == type(""):
        preferences = read_instance(preferences)
    h = PreferenceHelper(preferences)
    m = Model("SRI")

    n = len(preferences)
    # Create the initial matching matrix
    x = m.addVars(n, n, vtype=GRB.BINARY)

    # \sum_{u \in N(v)} x_{u, v} <= 1 for each  v \in V
    m.addConstrs(
        x.sum([u for u in h.get_neighbours(v)], v) <= 1 for v in range(n))

    # x_{u, v} = 0 for each {u, v} \notin E
    m.addConstrs(x.sum(u, v) == 0 for u, v in h.get_non_edges())

    #\sum_{i \in \{ N(u): i >_u v\}} x_{u, i} +
    #\sum_{j \in { N(v): i >_v u}} x_{v, j} +
    # x_{u, v} <= 1 for each {u, v} \in E
    if not optimisation == OptimalityCriteria.ALMOST_STABLE:
        m.addConstrs(
            x.sum(u, [i for i in h.get_preferred_neighbours(u, v)]) +
            x.sum([i for i in h.get_preferred_neighbours(v, u)], v) +
            x[u, v] >= 1 for u, v in h.get_edges())

    # x_{u, v} = x_{v, u} for each {u, v} \notin E
    m.addConstrs(x[u, v] == x[v, u] for u in range(n) for v in range(n))

    has_solution = True

    if optimisation == OptimalityCriteria.EGALITARIAN:
        # \sum_{u, v \in V} rank(u, v)x_{u,v}
        m.setObjective(x.prod(h.ranks))
    elif optimisation == OptimalityCriteria.FIRST_CHOICE_MAXIMAL:
        # \sum_{u, v \in V} \delta^1(u,v)x_{u,v}
        m.setObjective(x.prod(h.delta(1)), GRB.MAXIMIZE)
    elif optimisation == OptimalityCriteria.RANK_MAXIMAL:

        for i in range(1, h.max_pref_length // 2 - 1):
            delta_i = h.delta(i)
            m.setObjective(x.prod(delta_i), GRB.MAXIMIZE)
            m.optimize()
            if not hasattr(m, "ObjVal"):
                has_solution = False
                break
            m.addConstr(x.prod(delta_i) >= m.ObjVal)
        m.setObjective(x.prod(h.delta(h.max_pref_length - 1)), GRB.MAXIMIZE)
    elif optimisation == OptimalityCriteria.GENEROUS:
        for i in range(h.max_pref_length, h.max_pref_length // 2, -1):
            delta_i = h.delta(i)
            m.setObjective(x.prod(delta_i))
            m.optimize()
            if not hasattr(m, "ObjVal"):
                has_solution = False
                break
            m.addConstr(x.prod(delta_i) <= m.ObjVal)
        m.setObjective(x.prod(h.delta(1)))
    elif optimisation == OptimalityCriteria.ALMOST_STABLE:
        b = m.addVars(n, n, vtype=GRB.BINARY)
        m.addConstrs(
            x.sum(u, [i for i in h.get_preferred_neighbours(u, v)]) +
            x.sum([i for i in h.get_preferred_neighbours(v, u)], v) + x[u, v] +
            b[u, v] >= 1 for u, v in h.get_edges())
        m.setObjective(b.sum())
    elif optimisation != OptimalityCriteria.NONE:
        raise (ValueError("Unsupported criteria", optimisation))
    return m
Beispiel #4
0
from GA import PRP_Genetic, genetic_algorithm_solver
from utils import read_instance

if __name__ == '__main__':
    random.seed(42)


    for instance_size in [100]:
        # for ref_cost in [578.7815538, 643.0906153]:
        for ref_cost in [2175.292804, 2619.790834]:
            results = {'time': [], 'result': [], 'fleet size': []}
            for i in range(1, 150):
                instance_name = "UK{}_01".format(instance_size)
                #config T7
                instance = read_instance(inst_name=instance_name)
                prp = PRP_Genetic(instance)
                ngen = 1000
                final_mutation_rate = 1 / instance_size
                mutation_rate_decay = (1 - final_mutation_rate) / ngen
                start = time.time()
                fitness_scores, best_chromosome, target_time = genetic_algorithm_solver(prp,
                                                                           population_size=100,
                                                                           ngen=ngen,
                                                                           crossover_rate_decay=1,
                                                                           mutation_rate_decay=mutation_rate_decay,
                                                                           route_mutation_rate=1,
                                                                           min_route_mutation_rate=1 / instance_size,
                                                                           speed_mutation_rate=1 / instance_size,
                                                                           elitism_rate=0.15,
                                                                           maintain_diversity=False,
Beispiel #5
0
from utils import read_instance


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--filename",
        type=str,
        default="instances/instance.txt",
        help="Filename with offline instance",
    )
    parser.add_argument("--search", type=str, default="n",
                        help="Apply search? [y|n]")
    args = parser.parse_args()

    a = Seating(*read_instance(args.filename))
    start = time.time()
    seats, no_seat = a.greedy()
    print()
    print("Output (greedy) (2=person seated)")
    print(seats)
    print("Not seated", no_seat, "out of", a.totalpeople)
    print("Execution time %s" % (time.time() - start))
    if no_seat > 0 and args.search == "y":
        print("Not everyone seated... Starting branch and bound search...")
        a = Seating(*read_instance(args.filename))
        start = time.time()

        a.dfs()
        print("Execution time %s" % (time.time() - start))
Beispiel #6
0
def solve_SRI(preferences,
              density=None,
              index=None,
              optimisation=OptimalityCriteria.NONE):
    start_read_time = time.time_ns()
    start_total_time = start_read_time
    if density is not None:
        if index is not None:
            preferences = read_instance(preferences, density, index)
        else:
            raise (ValueError("Too few arguments", preferences, density,
                              index))
    elif type(preferences) == type(""):
        preferences = read_instance(preferences)
    h = PreferenceHelper(preferences)
    print("Readtime: " + str((time.time_ns() - start_read_time)) + " ns")
    start_build_time = time.time_ns()
    m = Model("SRI")

    n = len(preferences)
    # Create the initial matching matrix
    x = m.addVars(n, n, vtype=GRB.BINARY)

    # \sum_{u \in N(v)} x_{u, v} <= 1 for each  v \in V
    m.addConstrs(
        x.sum([u for u in h.get_neighbours(v)], v) <= 1 for v in range(n))

    # x_{u, v} = 0 for each {u, v} \notin E
    m.addConstrs(x.sum(u, v) == 0 for u, v in h.get_non_edges())

    #\sum_{i \in \{ N(u): i >_u v\}} x_{u, i} +
    #\sum_{j \in { N(v): i >_v u}} x_{v, j} +
    # x_{u, v} <= 1 for each {u, v} \in E
    if not optimisation == OptimalityCriteria.ALMOST_STABLE:
        m.addConstrs(
            x.sum(u, [i for i in h.get_preferred_neighbours(u, v)]) +
            x.sum([i for i in h.get_preferred_neighbours(v, u)], v) +
            x[u, v] >= 1 for u, v in h.get_edges())

    # x_{u, v} = x_{v, u} for each {u, v} \notin E
    m.addConstrs(x[u, v] == x[v, u] for u in range(n) for v in range(n))

    has_solution = True

    if optimisation == OptimalityCriteria.EGALITARIAN:
        m.Params.BranchDir = -1
        m.Params.Heuristics = 0
        m.Params.PrePasses = 2
        m.setObjective(x.prod(h.ranks))
    elif optimisation == OptimalityCriteria.FIRST_CHOICE_MAXIMAL:
        m.Params.Heuristics = 0
        m.Params.MIPFocus = 3
        m.Params.NoRelHeurWork = 60
        # \sum_{u, v \in V} \delta^1(u,v)x_{u,v}
        m.setObjective(x.prod(h.delta(1)), GRB.MAXIMIZE)
    elif optimisation == OptimalityCriteria.RANK_MAXIMAL:
        m.Params.ScaleFlag = 1
        m.Params.Heuristics = 0
        m.Params.BranchDir = 1
        m.params.PrePasses = 5
        m.Params.MIPFocus = 3
        for i in range(1, h.max_pref_length - 1):
            delta_i = h.delta(i)
            m.setObjective(x.prod(delta_i), GRB.MAXIMIZE)
            m.optimize()
            if not hasattr(m, "ObjVal"):
                has_solution = False
                break
            m.addConstr(x.prod(delta_i) >= m.ObjVal)
        m.setObjective(x.prod(h.delta(h.max_pref_length - 1)), GRB.MAXIMIZE)
    elif optimisation == OptimalityCriteria.GENEROUS:
        m.Params.DegenMoves = 4
        m.Params.Heuristics = 0
        m.Params.PrePasses = 5
        m.Params.BranchDir = -1
        m.Params.MIPFocus = 2
        for i in range(h.max_pref_length, 1, -1):
            delta_i = h.delta(i)
            m.setObjective(x.prod(delta_i))
            m.optimize()
            if not hasattr(m, "ObjVal"):
                has_solution = False
                break
            m.addConstr(x.prod(delta_i) <= m.ObjVal)
        m.setObjective(x.prod(h.delta(1)))
    elif optimisation == OptimalityCriteria.ALMOST_STABLE:
        m.Params.NormAdjust = 0
        m.Params.Heuristics = 0.001
        m.Params.VarBranch = 1
        m.Params.GomoryPasses = 15
        m.Params.PreSparsify = 0
        b = m.addVars(n, n, vtype=GRB.BINARY)
        m.addConstrs(
            x.sum(u, [i for i in h.get_preferred_neighbours(u, v)]) +
            x.sum([i for i in h.get_preferred_neighbours(v, u)], v) + x[u, v] +
            b[u, v] >= 1 for u, v in h.get_edges())
        m.setObjective(b.sum())
    elif optimisation != OptimalityCriteria.NONE:
        raise (ValueError("Unsupported criteria", optimisation))
    print("Buildtime: " + str(time.time_ns() - start_build_time) + " ns")
    if has_solution:
        m.optimize()
    print("Totaltime: " + str((time.time_ns() - start_total_time)) + " ns")
    n = len(preferences)
    matches = set()
    if not hasattr(x[0, 0], "x"):
        return None
    for u in range(n):
        for v in range(n):
            if x[u, v].x > 0 and u < v:
                matches.add((u + 1, v + 1))
    return matches
Beispiel #7
0
def make_and_solve_ILP(filename, optimized=False, configFile=""):
    """
    Encodes and solves ILP
    """
    # Prepare our problem instance
    cinema, people, ys, xs = read_instance(filename)

    # Filter all the people that cannot be seated.
    # This will mean less variables in our ILP problem
    people = filter_people(cinema, people)

    group_amount = int(np.sum([z for _, z in people.items()]))
    group_sizes = np.concatenate(
        [np.array(n * [i + 1], dtype=int) for i, n in people.items()])
    max_group_size = np.max(group_sizes)
    people_amount = np.sum(group_sizes)
    print(
        group_amount,
        " groups with sizes: ",
        group_sizes,
        "total people waiting:",
        people_amount,
    )
    start = time.time()

    # Collect legal positions per group size only once
    legals = dict()
    for size, amt in people.items():
        if amt > 0:
            legals[size + 1] = find_legal_start_positions(size + 1, cinema)

    # Collect group sizes
    size_to_group = defaultdict(list)
    for i, group_size in enumerate(group_sizes):
        size_to_group[group_size].append(i)
    # sys.exit(0)
    print(size_to_group)
    # Instantiate a gurobi ILP model
    model = gp.Model()

    if not configFile == "":
        model.read(configFile)

    # Each group has a binary variable per possible seat
    seated = model.addVars(xs,
                           ys,
                           group_amount,
                           vtype=GRB.BINARY,
                           name="seated")

    # Every group has a constant size
    size = model.addVars(
        group_amount,
        lb=tuple(group_sizes),
        ub=tuple(group_sizes),
        vtype=GRB.INTEGER,
        name="groupsize",
    )

    # Only one position per group
    for g in range(group_amount):
        model.addConstr(
            gp.quicksum(
                [seated[x, y, g] for x in range(xs) for y in range(ys)]),
            GRB.LESS_EQUAL,
            1,
        )

    # Check for non-seats and out-of-bounds groups
    # Do not seat a group when it will overlap with a 0-position/the end of the cinema
    for x in range(xs):
        for y in range(ys):
            for g in range(group_amount):
                # Loop over all positions from here to here + group_size
                any_zeros = False
                for i in range(0, group_sizes[g]):
                    if x + i >= xs or cinema[y, x + i] == 0:
                        any_zeros = True
                        break

                # If any positions were zero, the starting position was illegal
                if any_zeros:
                    model.addConstr(seated[x, y, g], GRB.EQUAL, 0)

    if optimized:
        for size1 in tqdm(range(1, max_group_size + 1)):
            for size2 in range(1, max_group_size + 1):
                # Look for all illegal combinations
                # Start with every possible position where g1 can be seated using the legals dictionary
                for (y1, x1) in legals[size1]:
                    # Calculate illegal seats for g2 given this start position
                    invalid_seats = get_invalid_seats(x1, y1, size1, size2, xs,
                                                      ys)
                    # Add a constraint, only one group can be seated in this area (<= 1)
                    for (x2, y2) in invalid_seats:
                        # For every combination of groups with these specific sizes
                        for g1 in size_to_group[size1]:
                            for g2 in size_to_group[size2]:
                                if g1 != g2:
                                    model.addConstr(
                                        seated[x1, y1, g1] +
                                        seated[x2, y2, g2],
                                        GRB.LESS_EQUAL,
                                        1,
                                    )
    else:
        # For every combination of groups g1, g2
        for g1 in tqdm(range(group_amount)):
            for g2 in range(group_amount):
                if g1 > g2:
                    size1 = group_sizes[g1]
                    size2 = group_sizes[g2]
                    for (y1, x1) in legals[size1]:
                        # Calculate illegal seats for g2 given this start position
                        invalid_seats = get_invalid_seats(
                            x1, y1, size1, size2, xs, ys)
                        # Add a constraint, only one group can be seated in this area (<= 1)
                        for (x2, y2) in invalid_seats:
                            model.addConstr(
                                seated[x1, y1, g1] + seated[x2, y2, g2],
                                GRB.LESS_EQUAL,
                                1,
                            )
                        del invalid_seats

    # TODO: Add more constraints that will help fastness of solver

    # Maximize number of people seated = seated_g * group_size_g
    # TODO: Set objective maximum manually to help gurobi.
    model.setObjective(
        gp.quicksum([
            seated[x, y, g] * size[g] for x in range(xs) for y in range(ys)
            for g in range(group_amount)
        ]),
        GRB.MAXIMIZE,
    )

    constraintTime = time.time() - start

    print("DONE ENCODING IN %s seconds.. STARTING OPTIMIZATION... " %
          (time.time() - start))
    start = time.time()

    model.optimize()

    optimizeTime = time.time() - start

    # Get the solution
    solution = cinema.copy()
    for x in range(xs):
        for y in range(ys):
            for g in range(group_amount):
                if seated[x, y, g].x > 0:
                    solution[y, x:x +
                             group_sizes[g]] = np.zeros(group_sizes[g]) + 2

    print(cinema)
    print("--- Was solved in %s seconds ---" % (time.time() - start))
    print(solution)
    print("Not seated", people_amount - count_seated(solution), "out of",
          people_amount)

    valid = verify_cinema(solution, xs, ys)

    return (filename, configFile, constraintTime, optimizeTime, group_amount,
            people_amount, valid, people_amount - count_seated(solution))
Beispiel #8
0
def test_verifier():
    preferences = read_instance(40, 50, 2, 0)
    file = "C:\\Users\\Sofia\\Documents\\level5project\\SRI_IP\\data\\outputs\\ASP\\almost-SRI\\output-almost-40-50.txt"
    solution = parse_answers(file)[0]
    blocking_pairs = get_blocking_pairs(preferences, solution)
    assert set(blocking_pairs) == set()
Beispiel #9
0
def test_verifier():
    preferences = read_instance(60, 25, 5, 0)
    file = "C:\\Users\\Sofia\\Documents\\level5project\\SRI_IP\\data\\outputs\\ASP\\almost-SRI\\output-almost-60-25.txt"
    solution = parse_answers(file)[4]
    blocking_pairs = get_blocking_pairs(preferences, solution)
    assert set(blocking_pairs) == set([(41, 23), (23, 41)])