示例#1
0
    def flat_varset(self, varset, grouped=False):
        # pprint(varset)
        vs = {v: 0 for v in varset}
        self.graphs = {
            v0: {
                self.paths[v0][i]: {
                    self.paths[v0][i + 1]: None
                }
                for i in range(len(self.paths[v0]) - 1)
            }
            for v0 in self.paths
        }
        stop_to_route = {}

        for v0 in self.graphs:
            vs[vn('RouteActive', self.data.v_index(v0))] = 1
            for v in self.graphs[v0]:
                vs[vn('Stop', self.data.v_index(v))] = 1
                stop_to_route[v] = v0
                for v2 in self.graphs[v0][v]:
                    vs[vn('Edge', self.data.v_index(v),
                          self.data.v_index(v2))] = 1

        assignment = assign_students_mip(self.data, self.graphs)
        for s in assignment:
            v = assignment[s]
            c = self.data.student_to_stop[s]
            v0 = stop_to_route[v]
            if grouped:
                vs[vn('StopCluster', self.data.v_index(v),
                      sorted(list(map(self.data.v_index, c))))] += 1
            else:
                vs[vn('StopStudent', self.data.v_index(v),
                      self.data.s_index(s))] = 1
            vs[vn('StopLoad', self.data.v_index(v))] += 1

        for v0 in self.paths:
            for i in range(1, len(self.paths[v0])):
                v1 = self.paths[v0][i - 1]
                v2 = self.paths[v0][i]
                vs[vn('EdgeLoad', self.data.v_index(v1),
                      self.data.v_index(v2))] = vs[vn('StopLoad',
                                                      self.data.v_index(v1))]
                vs[vn('StopLoad',
                      self.data.v_index(v2))] += vs[vn('StopLoad',
                                                       self.data.v_index(v1))]
        # pprint(vs)
        res = [varset, [vs[v] for v in varset]]
        # exit()
        return res
示例#2
0
        def __call__(self):
            sols = self.get_values()
            dsol = {variables[i][0]: sols[i]
                    for i in range(len(sols)) if sols[i] > 0.5}
            gs = {data.v_index(v0): defaultdict(lambda: [])
                  for v0 in data.depots}
            for vname in dsol:
                sp = vname.split("_")
                if sp[0] == 'RoEd':
                    v0, i, j = map(int, sp[1:])
                    gs[v0][i].append(j)

            for v0, g in gs.items():
                main_tour = bfs(g, v0)
                loops = set([v for v in g]).difference(main_tour)
                while len(loops) > 0:
                    loop = bfs(g, loops.pop())
                    for v00 in data.depots:
                        rhs = len(loop) - 1
                        sense = 'L'
                        constraint = [
                            [vn('RoEd', data.v_index(v00), v1, v2)
                             for v1 in loop for v2 in loop if v1 != v2],
                            [1 for v1 in loop for v2 in loop if v1 != v2]
                        ]
                        self.add(constraint=constraint,
                                 sense=sense,
                                 rhs=rhs)
                    loops.difference_update(loop)
示例#3
0
    def direct_varset(self, varset, grouped=False):
        # pprint(varset)
        vs = {v: 0 for v in varset}
        self.graphs = {
            v0: {
                self.paths[v0][i]: {
                    self.paths[v0][i + 1]: None
                }
                for i in range(len(self.paths[v0]) - 1)
            }
            for v0 in self.paths
        }
        stop_to_route = {}

        for v0 in self.graphs:
            vs[vn('RoA', self.data.v_index(v0))] = 1
            for v in self.graphs[v0]:
                vs[vn('RoSto', self.data.v_index(v0),
                      self.data.v_index(v))] = 1
                stop_to_route[v] = v0
                for v2 in self.graphs[v0][v]:
                    smallpath = self.data.path[v][v2]
                    for j in range(len(smallpath) - 1):
                        vs[vn('RoEd', self.data.v_index(v0),
                              self.data.v_index(smallpath[j]),
                              self.data.v_index(smallpath[j + 1]))] += 1

        assignment = assign_students_mip(self.data, self.graphs)
        for s in assignment:
            v = assignment[s]
            c = self.data.student_to_stop[s]
            v0 = stop_to_route[v]
            if grouped:
                vs[vn('RoStoCl', self.data.v_index(v0), self.data.v_index(v),
                      sorted(list(map(self.data.v_index, c))))] += 1
            else:
                vs[vn('RoSoSu', self.data.v_index(v0), self.data.v_index(v),
                      self.data.s_index(s))] = 1
        # pprint(vs)
        res = [varset, [vs[v] for v in varset]]
        # exit()
        return res
示例#4
0
        def __call__(self):
            global times

            sols = self.get_values()
            dsol = {variables[i][0]: sols[i]
                    for i in range(len(sols)) if sols[i] > 0.5}
            gs = {data.v_index(v0): defaultdict(lambda: []) for v0 in data.depots}
            for vname in dsol:
                sp = vname.split("_")
                if sp[0] == 'RoEd':
                    v0, i, j = map(int, sp[1:])
                    gs[v0][i].append(j)

            sloops = []
            for v0, g in gs.items():
                main_tour = bfs(g, v0)
                loops = set([v for v in g]).difference(main_tour)
                while len(loops) > 0:
                    loop = bfs(g, loops.pop())
                    sloops.append(loop)
                    loops.difference_update(loop)
            # print(sloops)
            for loop in sloops:
                # print(loop)
                for v in loop:
                    if data.vdictinv[v] not in data.stops:
                        continue
                    for v0 in data.depots:
                        rhs = 0
                        sense = 'G'
                        constraint = [
                            [vn('RoEd', data.v_index(v0), v1, data.v_index(v2))
                            for v1 in loop for v2 in data.original_graph[data.vdictinv[v1]]
                            if data.v_index(v2) not in loop] +
                            [vn('RoSto', data.v_index(v0), v)],
                            [1 for v1 in loop for v2 in data.original_graph[data.vdictinv[v1]]
                            if data.v_index(v2) not in loop] + [-1]
                        ]
                        self.add(constraint=constraint,
                                sense=sense,
                                rhs=rhs)
示例#5
0
def insertion_precalc_wrapper(data, vnames):
    try:
        heur = InsertionHeuristic(data)
    except KeyError:
        return
    onvars = []
    stop_route = {}
    for p in heur.paths:
        onvars.append(vn('RouteActive', data.v_index(p[0])))
        for i in range(len(p) - 1):
            onvars.append(vn('RouteEdge', data.v_index(p[0]),
                             data.v_index(p[i]), data.v_index(p[i+1])))
        for i in range(len(p)):
            onvars.append(vn('RouteStop', data.v_index(p[0]), data.v_index(p[i])))
            stop_route[p[i]] = p[0]

    for v in heur.stops:
        for s in heur.stops[v]:
            onvars.append(vn('RouteStopStudent', data.v_index(stop_route[v]),
                            data.v_index(v), data.s_index(s)))

    return (vnames, [1 if v in onvars else 0 for v in vnames])
示例#6
0
        def __call__(self):

            # Generamos diccionarios para obtener rapidamente las variables
            val_dict = {x[0][0]: x[1]
                        for x in zip(variables, self.get_values())}
            # pprint(val_dict)
            stop_route = defaultdict(lambda: [])
            student_stop_route = defaultdict(lambda: [])
            edges_cost = defaultdict(lambda: defaultdict(lambda: {}))
            for vname in val_dict:
                sp = vname.split("_")
                if sp[0] == 'RoSto':
                    v0, s = map(int, sp[1:])
                    stop_route[s].append((val_dict[vname], v0))
                if sp[0] == 'RoStoStu':
                    v0, s, st = map(int, sp[1:])
                    student_stop_route[st].append((val_dict[vname], v0, s))
                if sp[0] == 'RoEd':
                    v0, s1, s2 = map(int, sp[1:])
                    edges_cost[v0][s1][s2] = (1 - val_dict[vname]) * \
                        data.dist[data.vdictinv[s1]][data.vdictinv[s2]]

            # Shuffleando para no tener sesgo hacia ciertas paradas/estudiantes
            for s in stop_route:
                shuffle(stop_route[s])
            for st in student_stop_route:
                shuffle(student_stop_route[st])
            # pprint(stop_route)
            # pprint(student_stop_route)

            rvars = defaultdict(lambda: 0)
            stop_route_choice = {}
            routes = defaultdict(lambda: {})
            # De cada parada, elegimos la ruta que tenga mayor de asociación entre
            # ruta y parada. Si todas son 0, entonces la dejamos afuera. Al mismo
            # tiempo, activamos las rutas
            for s in stop_route:
                highest = 0.0
                best = None
                for val, v0 in stop_route[s]:
                    if val > highest:
                        highest = val
                        best = v0
                stop_route_choice[s] = best
                if best is not None:
                    rvars[vn('RoSto', best, s)] = 1
                    rvars[vn('RoA', best)] = 1
                    # Agrego la parada a la ruta, todavía no sabemos como se
                    # conectan
                    routes[best][s] = None
            # pprint(stop_route_choice)
            # pprint(rvars)
            # pprint(routes)

            # De cada estudiante, nos fijamos que combinación de parada y ruta tiene
            # mayor valor, y la asignamos ahí
            load = defaultdict(lambda: 0)
            student_stop_route_choice = {}
            for st in student_stop_route:
                # print(st, student_stop_route[st])
                highest = -0.1
                for val, v0, s in student_stop_route[st]:
                    # print(val, v0, s)
                    if val > highest and stop_route_choice[s] == v0:
                        highest = val
                        best = (v0, s)
                # print(best)
                student_stop_route_choice[st] = best
                # print(student_stop_route_choice)
                rvars[vn('RoStoStu', best[0], best[1], st)] = 1
                load[best[0]] += 1
                if load[best[0]] > data.capacity:
                    return
            # pprint(student_stop_route_choice)
            # pprint(onvars)

            # pprint(route_edges)
            school = data.v_index(data.school)
            total_cost = 0
            rank = defaultdict(lambda: 0)
            for v0 in edges_cost:
                routes[v0][v0] = school
                # print(routes[v0])
                out_of_tour = set(routes[v0].keys())
                out_of_tour.difference_update([v0])
                # print(out_of_tour)

                while len(out_of_tour) > 0:
                    best = (float('+inf'), 0, 0)
                    for v in out_of_tour:
                        vi = v0
                        while vi != school:
                            vnext = routes[v0][vi]
                            new_cost = (
                                edges_cost[v0][vi][v] + edges_cost[v0][v][vnext] -
                                edges_cost[v0][v][vnext],
                                vi, v)
                            # print(new_cost)
                            best = min(best, new_cost)
                            vi = routes[v0][vi]
                    # print(best)
                    _, vi, v = best
                    vnext = routes[v0][vi]
                    # print("AGREGO", v, "DESPUES DE", vi, "ANTES DE", vnext)
                    routes[v0][v] = vnext
                    routes[v0][vi] = v
                    out_of_tour.remove(v)

                rvars[vn('Rank', v0, v0)] = 1
                v = v0
                while v != data.v_index(data.school):
                    rvars[vn("RoEd", v0, v, routes[v0][v])] = 1
                    rvars[vn('Rank', v0, routes[v0][v])
                          ] = rvars[vn('Rank', v0, v)] + 1
                    total_cost += data.dist[data.vdictinv[v]
                                            ][data.vdictinv[routes[v0][v]]]
                    if total_cost >= self.get_incumbent_objective_value()-.01:
                        return
                    v = routes[v0][v]
                # print(v0, routes[v0])

            # pprint(rvars)
            res = [[v[0] for v in variables], [
                rvars[v[0]] for v in variables]]
            print(total_cost, self.get_incumbent_objective_value())
            self.set_solution(res, objective_value=total_cost)
示例#7
0
parser.add_option("--nodeheur", dest="node_heur", action="store_true")

(options, args) = parser.parse_args()

# INPUT
data = ProblemData(options.in_file)

problem = cplex.Cplex()
problem.objective.set_sense(problem.objective.sense.minimize)
# problem.parameters.dettimelimit.set(1000000)
problem.parameters.timelimit.set(3600)
problem.parameters.workmem.set(20000)


variables = [
    (vn('RoEd', data.v_index(v0), data.v_index(
        v1), data.v_index(v2)), 'B', data.dist[v1][v2])
    for v0 in data.depots for v1 in data.stops for v2 in data.stops if v1 != v2] + \
    [(vn('RoSto', data.v_index(v0), data.v_index(v1)), 'B', 0)
     for v0 in data.depots for v1 in data.stops[1:]] + \
    [(vn('RoA', data.v_index(v0)), 'B', 0) for v0 in data.depots]

if True:
    variables += [(vn('RoStoCl', data.v_index(v0), data.v_index(v1), sorted(list(map(data.v_index, c)))), 'I', 0)
                  for v0 in data.depots for v1 in data.stops for c in data.stop_to_clusters[v1]]
else:
    variables += [(vn('RoStoStu', data.v_index(v0), data.v_index(v1), data.s_index(s)), 'B', 0)
                  for s in data.students for v0 in data.depots for v1 in data.student_to_stop[s]]

if True:
    variables += [(vn('Rank', data.v_index(v0), data.v_index(v)), 'C', 0)
                  for v0 in data.depots for v in data.stops]
示例#8
0
    def feasible_aux(self, paths, wont_be_routed):
        problem = cplex.Cplex()
        problem.parameters.emphasis.mip.set(1)
        problem.parameters.mip.display.set(0)
        problem.set_log_stream(None)
        problem.set_error_stream(None)
        problem.set_warning_stream(None)
        problem.set_results_stream(None)

        variables = [(vn('RouteStop', self.data.v_index(v0), self.data.v_index(v1)), 'B', 0)
                     for v0 in paths for v1 in self.data.stops[1:]] + \
            [(vn('RouteStopCluster', self.data.v_index(v0), self.data.v_index(v1), list(map(self.data.v_index, c))), 'I', 1)
             for v0 in paths for v1 in self.data.stops for c in self.data.stop_to_clusters[v1]]

        problem.variables.add(types=[v[1] for v in variables],
                              names=[v[0] for v in variables])

        # All stops can be visited at most one time
        rhs = [1 for v in self.data.stops[1:]]
        sense = ['L' for v in self.data.stops[1:]]
        constraint = [[[
            vn('RouteStop', self.data.v_index(v0), self.data.v_index(v))
            for v0 in paths
        ], [1 for v0 in paths]] for v in self.data.stops[1:]]
        problem.linear_constraints.add(lin_expr=constraint,
                                       senses=sense,
                                       rhs=rhs)

        # Cluster choices add to cluster size
        rhs = [self.data.clusters[c] for c in self.data.clusters]
        sense = ['E' for c in self.data.clusters]
        constraint = [[[
            vn('RouteStopCluster',
               self.data.v_index(v0), self.data.v_index(v1),
               list(map(self.data.v_index, c))) for v0 in paths for v1 in c
        ], [1 for v0 in paths for v1 in c]] for c in self.data.clusters]
        problem.linear_constraints.add(lin_expr=constraint,
                                       senses=sense,
                                       rhs=rhs)

        # If cluster to stop, route is larger than 1, stop,route must be active
        rhs = [
            0 for v0 in paths for v1 in self.data.stops
            for c in self.data.stop_to_clusters[v1]
        ]
        sense = [
            'L' for v0 in paths for v1 in self.data.stops
            for c in self.data.stop_to_clusters[v1]
        ]
        constraint = [[[
            vn('RouteStopCluster', self.data.v_index(v0),
               self.data.v_index(v1), list(map(self.data.v_index, c))),
            vn('RouteStop', self.data.v_index(v0), self.data.v_index(v1))
        ], [1, -self.data.clusters[c]]] for v0 in paths
                      for v1 in self.data.stops
                      for c in self.data.stop_to_clusters[v1]]
        problem.linear_constraints.add(lin_expr=constraint,
                                       senses=sense,
                                       rhs=rhs)

        # Capacities are kept
        rhs = [self.data.capacity for v0 in paths]
        sense = ['L' for v0 in paths]
        constraint = [[[
            vn('RouteStopCluster',
               self.data.v_index(v0), self.data.v_index(v1),
               list(map(self.data.v_index, c))) for v1 in self.data.stops
            for c in self.data.stop_to_clusters[v1]
        ], [
            1 for v1 in self.data.stops for c in self.data.stop_to_clusters[v1]
        ]] for v0 in paths]
        problem.linear_constraints.add(lin_expr=constraint,
                                       senses=sense,
                                       rhs=rhs)

        rhs = []
        sense = []
        constraint = []
        for v0 in paths:
            for v in paths[v0][:-1]:
                rhs.append(1)
                sense.append('E')
                constraint.append([[
                    vn('RouteStop', self.data.v_index(v0),
                       self.data.v_index(v))
                ], [1]])
        for v in wont_be_routed:
            rhs.append(0)
            sense.append('E')
            constraint.append([[
                vn('RouteStop', self.data.v_index(v0), self.data.v_index(v))
                for v0 in paths
            ], [1 for v0 in paths]])
        problem.linear_constraints.add(lin_expr=constraint,
                                       senses=sense,
                                       rhs=rhs)

        problem.solve()
        return problem.solution.is_primal_feasible()
示例#9
0
parser.add_option("--of", dest="out_file")
parser.add_option("--grouped", dest="grouped", action="store_true")
parser.add_option("--optcut", dest="optcut", action="store_true")
parser.add_option("--heur", dest="heur", action="store_true")
parser.add_option("--flow", dest="flow",action="store_true")
(options, args) = parser.parse_args()

# INPUT
data = ProblemData(options.in_file)
problem = cplex.Cplex()
problem.objective.set_sense(problem.objective.sense.minimize)
# problem.parameters.dettimelimit.set(1000000)
problem.parameters.timelimit.set(3600)
problem.parameters.workmem.set(20000)

variables = [(vn('RoEd', data.v_index(v0), data.v_index(v1), data.v_index(v2)), 'I', data.original_graph[v1][v2][0])
             for v0 in data.depots for v1 in data.original_graph for v2 in data.original_graph[v1]] + \
    [(vn('RoSto', data.v_index(v0), data.v_index(v1)), 'B', 0)
     for v0 in data.depots for v1 in data.stops[1:]] + \
    [(vn('RoA', data.v_index(v0)), 'B', 0) for v0 in data.depots]

if True:
    variables += [(vn('RoEdFlo', data.v_index(v0), data.v_index(v1), data.v_index(v2)), 'C', 0)
     for v0 in data.depots for v1 in data.original_graph for v2 in data.original_graph[v1]]
    

if True:
    variables += [(vn('RoStoCl', data.v_index(v0), data.v_index(v1),
                      sorted(list(map(data.v_index, c)))), 'I', 0)
                  for v0 in data.depots for v1 in data.stops for c in data.stop_to_clusters[v1]]
else:
示例#10
0
parser.add_option("--if", dest="in_file")
parser.add_option("--of", dest="out_file")
parser.add_option("--grouped", dest="grouped", action="store_true")
parser.add_option("--heur", dest="heur", action="store_true")
(options, args) = parser.parse_args()

# INPUT
data = ProblemData(options.in_file)

problem = cplex.Cplex()
problem.objective.set_sense(problem.objective.sense.minimize)
# problem.parameters.dettimelimit.set(1000000)
problem.parameters.timelimit.set(3600)
# problem.parameters.mip.display.set(1)

variables = [(vn('Edge', data.v_index(v1), data.v_index(v2)), 'B', data.dist[v1][v2])
             for v1 in data.stops for v2 in data.stops if v1 != v2] + \
    [(vn('EdgeLoad', data.v_index(v1), data.v_index(v2)), 'C', 0)
     for v1 in data.stops
     for v2 in data.stops if v1 != v2] + \
    [(vn('Stop', data.v_index(v1)), 'B', 0)
     for v1 in data.stops[1:]] + \
    [(vn('StopLoad', data.v_index(v1)), 'C', 0)
     for v1 in data.stops] + \
    [(vn('RouteActive', data.v_index(v0)), 'B', 0)
     for v0 in data.depots]

if options.grouped:
    variables += [(vn('StopCluster', data.v_index(v1),
                      sorted(list(map(data.v_index, c)))), 'I', 0)
                  for v1 in data.stops for c in data.stop_to_clusters[v1]]
示例#11
0
def assign_students_mip(data, gs):

    vset = set()
    for v0 in gs:
        vset.update(gs[v0].keys())

    problem = cplex.Cplex()
    problem.objective.set_sense(problem.objective.sense.minimize)
    problem.set_log_stream(None)
    problem.set_error_stream(None)
    problem.set_warning_stream(None)
    problem.set_results_stream(None)

    variables = [(vn('StopStudent', data.v_index(v1),
                     data.s_index(s)), 'B', haversine_dist(s, v1))
                 for s in data.students for v1 in data.student_to_stop[s]
                 if v1 in vset]

    problem.variables.add(obj=[v[2] for v in variables],
                          types=[v[1] for v in variables],
                          names=[v[0] for v in variables])

    # for s in data.students:
    #     print(data.s_index(s), list(map(data.v_index, data.student_to_stop[s])))
    # Choice adds to one
    rhs = [1 for s in data.students]
    sense = ['E' for s in data.students]
    constraint = [[[
        vn('StopStudent', data.v_index(v1), data.s_index(s))
        for v1 in data.student_to_stop[s] if v1 in vset
    ], [1 for v1 in data.student_to_stop[s] if v1 in vset]]
                  for s in data.students]
    # pprint(constraint)
    names = ['choice_addition_' + str(data.s_index(s)) for s in data.students]
    problem.linear_constraints.add(lin_expr=constraint,
                                   senses=sense,
                                   rhs=rhs,
                                   names=names)

    # Capacities are respected
    rhs = [data.capacity for v0 in gs]
    sense = ['L' for v0 in gs]
    constraint = [[[
        vn('StopStudent', data.v_index(v), data.s_index(s)) for v in gs[v0]
        if v in data.stops for s in data.stop_to_students[v]
    ], [
        1 for v in gs[v0] if v in data.stops for s in data.stop_to_students[v]
    ]] for v0 in gs]
    problem.linear_constraints.add(lin_expr=constraint, senses=sense, rhs=rhs)

    problem.solve()
    print("BEST STUDENT ASSIGNMENT WALKING DISTANCE: ",
          problem.solution.get_objective_value())

    sol = problem.solution.get_values()
    dsol = {variables[i][0]: sol[i] for i in range(len(sol)) if sol[i] > 0.5}
    assignment = {}
    for vname in dsol:
        if dsol[vname] < 0.5:
            continue
        sp = vname.split("_")
        if sp[0] == 'StopStudent':
            v, s = map(int, sp[1:])
            assignment[data.students[s]] = data.vdictinv[v]
    return assignment