Esempio n. 1
0
 def to_dict(self):
     routes = pt.SuperDict()
     for k, v in self.data["routes"].items():
         routes[k] = pt.TupList(v).kvapply(lambda k, v: (k, v))
     routes = routes.to_tuplist().vapply(
         lambda v: dict(route=v[0], pos=v[1], node=v[2]))
     return pt.SuperDict(routes=routes)
Esempio n. 2
0
 def from_json(cls, path):
     with open(path, 'r') as f:
         data_json = json.load(f)
     data = pt.SuperDict({v['job']:
                              pt.SuperDict(period=v['period'],
                                           mode=v['mode']) for v in data_json}
                         )
     return cls(data)
Esempio n. 3
0
 def from_json(cls, path):
     with open(path, 'r') as f:
         data_json = json.load(f)
     jobs = pt.SuperDict({v['id']: v for v in data_json['jobs']})
     res = pt.SuperDict({v['id']: v for v in data_json['resources']})
     needs = pt.SuperDict({(v['job'], v['mode'], v['resource']): v['need'] for v in data_json['needs']})
     durations = pt.SuperDict({(v['job'], v['mode']): v['duration'] for v in data_json['durations']})
     data = pt.SuperDict(jobs=jobs, resources=res, needs=needs.to_dictdict(), durations=durations.to_dictdict())
     return cls(data)
Esempio n. 4
0
 def from_dict(cls, data_json: _solutionHint) -> "Solution":
     check_solution(data_json)
     data = pt.SuperDict(
         {
             v["job"]: pt.SuperDict(period=v["period"], mode=v["mode"])
             for v in data_json["assignment"]
         }
     )
     return cls(data)
Esempio n. 5
0
    def from_mm(cls, path, content=None):
        if content is None:
            with open(path, 'r') as f:
                content = f.readlines()

        content = pt.TupList(content)
        index_prec = \
            content. \
            index('PRECEDENCE RELATIONS:\n')

        index_requests = \
            content.index('REQUESTS/DURATIONS:\n')

        index_avail = \
            content.\
            index('RESOURCEAVAILABILITIES:\n')

        # precedence.
        precedence = content[index_prec + 2:index_requests - 1]
        successors = pt.SuperDict()
        for line in precedence:
            _, job, modes, num_succ, *jobs, _ = re.split('\s+', line)
            successors[int(job)] = pt.TupList(jobs).vapply(int)
        successors = successors.kvapply(lambda k, v: dict(successors=v, id=k))

        # requests/ durations
        requests = content[index_requests + 3:index_avail - 1]
        resources = re.findall(r'[RN] \d', content[index_requests + 1])
        needs = pt.SuperDict()
        durations = pt.SuperDict()
        last_job = ''
        for line in requests:
            if line[2] == ' ':
                job = last_job
                _, mode, duration, *consumption, _ = re.split('\s+', line)
            else:
                _, job, mode, duration, *consumption, _ = re.split('\s+', line)
                last_job = job
            key = int(job), int(mode)
            needs[key] = \
                {v: int(consumption[k]) for k, v in enumerate(resources)}
            needs[key] = pt.SuperDict(needs[key])
            durations[key] = int(duration)

        # resources / availabilities
        line = content[index_avail + 2]
        _, *avail, _ = re.split('\s+', line)
        availability = {k: int(avail[i]) for i, k in enumerate(resources)}
        availability = pt.SuperDict(availability).kvapply(
            lambda k, v: dict(available=v, id=k))
        data = dict(resources=availability,
                    jobs=successors,
                    durations=durations.to_dictdict(),
                    needs=needs.to_dictdict())
        return cls(data)
Esempio n. 6
0
 def from_dict(cls, data_json):
     jobs = pt.SuperDict({v['id']: v for v in data_json['jobs']})
     res = pt.SuperDict({v['id']: v for v in data_json['resources']})
     needs = pt.SuperDict({(v['job'], v['mode'], v['resource']): v['need']
                           for v in data_json['needs']})
     durations = pt.SuperDict({(v['job'], v['mode']): v['duration']
                               for v in data_json['durations']})
     data = pt.SuperDict(jobs=jobs,
                         resources=res,
                         needs=needs.to_dictdict(),
                         durations=durations.to_dictdict())
     return cls(data)
Esempio n. 7
0
    def to_json(self, path):
        res = self.data['resources'].values_l()
        job = self.data['jobs'].values_l()
        duration =self.data['durations'].to_dictup().to_tuplist().vapply(lambda v: pt.SuperDict(job=v[0], mode=v[1], duration=v[2]))
        needs = \
            self.data['needs'].to_dictup().to_tuplist().\
            vapply(lambda v: pt.SuperDict(job=v[0], mode=v[1],
                                          resource=v[2],
                                          need=v[3]))

        data = pt.SuperDict(jobs=job, resources=res, needs=needs, durations=duration)
        with open(path, 'w') as f:
            json.dump(data, f, indent=4, sort_keys=True)
Esempio n. 8
0
    def to_dict(self) -> dict:

        res = self.data["resources"].values_l()
        job = self.data["jobs"].values_l()
        duration = (self.data["durations"].to_dictup().to_tuplist().vapply(
            lambda v: pt.SuperDict(job=v[0], mode=v[1], duration=v[2])))
        needs = (self.data["needs"].to_dictup().to_tuplist().vapply(
            lambda v: pt.SuperDict(
                job=v[0], mode=v[1], resource=v[2], need=v[3])))

        data = pt.SuperDict(jobs=job,
                            resources=res,
                            needs=needs,
                            durations=duration)

        return data
Esempio n. 9
0
    def solve(self, options):
        # takes into account successors
        jobs = copy.deepcopy(self.instance.data["jobs"])
        all_jobs = set(jobs.keys())
        solution = pt.SuperDict()
        succ = jobs.get_property("successors")
        durations = self.instance.data["durations"]

        # algorithm
        period = 0
        job = 1
        succ.pop(job)
        mode = 1  # we always chose the first mode
        solution[job] = dict(period=period, mode=mode)
        period = period + durations[job][mode]

        while len(succ):
            reverse = succ.list_reverse()
            possible = all_jobs - reverse.keys() - solution.keys()
            for job in possible:
                succ.pop(job)
                solution[job] = dict(period=period, mode=mode)
                period = period + durations[job][mode]
        self.solution = Solution(solution)
        return 2
Esempio n. 10
0
def get_info_object(tables, day_of_week='monday', min_hour='11:00:00', max_hour='12:00:00',
                    max_dist_km_walk = 0.5, **kwargs):

    trips = tables['trips']
    calendar = tables['calendar']
    calendar_r = calendar[calendar[day_of_week] == '1']
    trips = trips.merge(calendar_r, on='service_id')
    trip_info = trips.\
        set_index('trip_id')[['route_id', 'direction_id']].\
        to_dict(orient='index')
    trip_info = pt.SuperDict.from_dict(trip_info)

    stop_times = tables['stop_times']
    # TODO: fix this so we do not need to chop the end of the day
    stop_times_info = \
        stop_times\
            [stop_times.arrival_time.str.slice(stop=2) < '24'].\
            merge(trips, on='trip_id')
    stop_times_info = \
        stop_times_info[
            stop_times_info.arrival_time.
            between(min_hour, max_hour)].\
            copy()
    stop_times_info.arrival_time = pd.to_datetime(stop_times_info.arrival_time, format='%H:%M:%S')
    stop_times_info.stop_sequence = stop_times_info.stop_sequence.astype(int)
    stop_times_info_1 = \
        stop_times_info.\
        set_index(['trip_id', 'stop_sequence'])\
        [['arrival_time', 'stop_id']].\
        to_dict(orient='index')
    stop_times_info_1 = pt.SuperDict.from_dict(stop_times_info_1).to_dictdict()

    stop_times_2_info = \
        stop_times_info. \
        set_index('stop_id')[['arrival_time', 'trip_id', 'route_id', 'stop_sequence']]

    # we want the backup in the table. This is becuase R has problems with no-unique indeces.
    stop_times_2_info['stop_id_backup'] = stop_times_2_info.index

    route_info = tables['routes'].set_index('route_id').to_dict(orient='index')
    route_info = pt.SuperDict.from_dict(route_info)

    stops_neighbors = get_positions_table(tables['stops'], stop_times_2_info)

    complete_graph = \
        stops_neighbors.\
        merge(stops_neighbors, on=['stop_lon_g', 'stop_lat_g'])

    stops_neighbors = get_distance_dict(complete_graph, max_dist_km_walk)

    stops_info = tables['stops'].set_index('stop_id').to_dict(orient='index')
    stops_info = pt.SuperDict.from_dict(stops_info)

    return pt.SuperDict(trips=trip_info,  # trip: {info}
                        stop_times=stop_times_info_1,  # (route, sequence): time and stop
                        stop_times_2=stop_times_2_info,  # indexed table
                        routes=route_info,  # route: {info}
                        stops=stops_info,  # stop: {info}
                        stops_neigh=stops_neighbors  # stop: {stop: dist}
                        )
    def format_solution(self):

        instance = self.model_solution
        dict_start = dict()

        for j in instance.sJobs:
            for s in instance.sSlots:
                if value(instance.v01Start[j, s]) == 1:
                    dict_start[j] = int(s)

        dict_mode = var_to_dict(instance.v01JobMode)
        set_jobs = [i for i in instance.sJobs]

        mode_no_denso = dict()
        for a, b in dict_mode.keys():
            if dict_mode[a, b] == 1:
                mode_no_denso.update({a: b})

        if len(mode_no_denso) == 0:
            return {}

        final = pt.SuperDict()
        for j in set_jobs:
            final[j] = dict()
            final[j].update({
                "period": int(dict_start[j]),
                "mode": int(mode_no_denso[j])
            })
        return final
Esempio n. 12
0
    def from_dict(cls, data) -> "Instance":
        demand = pt.SuperDict({v["n"]: v for v in data["demand"]})

        weights = (pt.TupList(data["arcs"]).vapply(
            lambda v: v.values()).vapply(lambda x: list(x)).to_dict(
                result_col=2, is_list=False))
        datap = {**data, **dict(demand=demand, arcs=weights)}
        return cls(datap)
Esempio n. 13
0
    def from_dict(cls, data_json: dict) -> "Instance":
        check_instance(data_json)

        jobs = pt.SuperDict({v["id"]: v for v in data_json["jobs"]})
        res = pt.SuperDict({v["id"]: v for v in data_json["resources"]})
        needs = pt.SuperDict({(v["job"], v["mode"], v["resource"]):
                              round(v["need"])
                              for v in data_json["needs"]})
        durations = pt.SuperDict({(v["job"], v["mode"]): round(v["duration"])
                                  for v in data_json["durations"]})
        data = pt.SuperDict(
            jobs=jobs,
            resources=res,
            needs=needs.to_dictdict(),
            durations=durations.to_dictdict(),
        )
        return cls(data)
Esempio n. 14
0
    def to_dict(self):
        res = self.data['resources'].values_l()
        job = self.data['jobs'].values_l()
        duration =self.data['durations'].to_dictup().to_tuplist().\
            vapply(lambda v: pt.SuperDict(job=v[0], mode=v[1], duration=v[2]))
        needs = \
            self.data['needs'].to_dictup().to_tuplist().\
            vapply(lambda v: pt.SuperDict(job=v[0], mode=v[1],
                                          resource=v[2],
                                          need=v[3]))

        data = pt.SuperDict(jobs=job,
                            resources=res,
                            needs=needs,
                            durations=duration)

        return data
Esempio n. 15
0
 def check_solution(self, list_tests=None, **params):
     func_list = dict(
         successors=self.check_successors,
         resources_nr=self.check_resources_nonrenewable,
         resources_r=self.check_resources_renewable,
         all_jobs_once=self.all_jobs_once,
     )
     if list_tests is None:
         list_tests = func_list.keys()
     result = {k: func_list[k](**params) for k in list_tests}
     return pt.SuperDict({k: v for k, v in result.items() if v})
Esempio n. 16
0
 def check_successors(self, **params) -> pt.SuperDict[Tuple[int, int], int]:
     succ = self.instance.data["jobs"].get_property("successors")
     durations = self.instance.data["durations"]
     solution = (
         self.solution.data.to_dictup()
         .to_tuplist()
         .to_dict(result_col=2, indices=[1, 0], is_list=False)
         .to_dictdict()
     )
     sol_start = solution.get("period", pt.SuperDict())
     sol_mode = solution.get("mode", pt.SuperDict())
     sol_finished = sol_start.kvapply(lambda k, v: v + durations[k][sol_mode[k]])
     errors = pt.SuperDict()
     for job, post_jobs in succ.items():
         if job not in sol_finished:
             continue
         for job2 in post_jobs:
             if job2 not in sol_start:
                 continue
             if sol_finished[job] > sol_start[job2]:
                 errors[job, job2] = sol_finished[job] - sol_start[job2]
     return errors
Esempio n. 17
0
 def check_successors(self, **params):
     succ = self.instance.data['jobs'].get_property('successors')
     durations = self.instance.data['durations']
     solution = self.solution.data.to_dictup().to_tuplist().\
         to_dict(result_col=2, indices=[1, 0], is_list=False).\
         to_dictdict()
     sol_start = solution['period']
     sol_mode = solution['mode']
     sol_finished = sol_start.kvapply(
         lambda k, v: v + durations[k][sol_mode[k]])
     errors = pt.SuperDict()
     for job, post_jobs in succ.items():
         for job2 in post_jobs:
             if sol_finished[job] > sol_start[job2]:
                 errors[job, job2] = sol_finished[job] - sol_start[job2]
     return errors
Esempio n. 18
0
    def solve(self, options: dict):
        model = cp_model.CpModel()
        input_data = pt.SuperDict.from_dict(self.instance.data)
        pairs = input_data["pairs"]
        n1s = pt.TupList(pairs).vapply(lambda v: v["n1"])
        n2s = pt.TupList(pairs).vapply(lambda v: v["n2"])
        nodes = (n1s + n2s).unique2()
        max_colors = len(nodes) - 1

        # variable declaration:
        color = pt.SuperDict({
            node: model.NewIntVar(0, max_colors, "color_{}".format(node))
            for node in nodes
        })
        # TODO: identify maximum cliques and apply constraint on the cliques instead of on pairs
        for pair in pairs:
            model.Add(color[pair["n1"]] != color[pair["n2"]])

        obj_var = model.NewIntVar(0, max_colors, "total_colors")
        model.AddMaxEquality(obj_var, color.values())
        model.Minimize(obj_var)
        solver = cp_model.CpSolver()
        solver.parameters.max_time_in_seconds = options.get("timeLimit", 10)
        status = solver.Solve(model)
        status_conv = {
            cp_model.OPTIMAL: STATUS_OPTIMAL,
            cp_model.INFEASIBLE: STATUS_INFEASIBLE,
            cp_model.UNKNOWN: STATUS_UNDEFINED,
            cp_model.MODEL_INVALID: STATUS_UNDEFINED,
        }
        if status not in [cp_model.OPTIMAL, cp_model.FEASIBLE]:
            return dict(status=status_conv.get(status),
                        status_sol=SOLUTION_STATUS_INFEASIBLE)
        color_sol = color.vapply(solver.Value)

        assign_list = color_sol.items_tl().vapply(
            lambda v: dict(node=v[0], color=v[1]))
        self.solution = Solution(dict(assignment=assign_list))

        return dict(status=status_conv.get(status),
                    status_sol=SOLUTION_STATUS_FEASIBLE)
    def format_solution(self):
    
        instance = self.model_solution
        dict_start = var_to_dict(instance.vStart)
        dict_mode = var_to_dict(instance.v01Mode)
        set_jobs = [i for i in instance.sJobs]
    
        mode_no_denso = dict()
        for a, b in dict_mode.keys():
            if dict_mode[a, b] == 1:
                mode_no_denso.update({a: b})
    
        if len(mode_no_denso) == 0:
            return {}

        # final = dict()
        final = pt.SuperDict()
        for j in set_jobs:
            final[j] = dict()
            final[j].update({'period': int(dict_start[j]), 'mode': int(mode_no_denso[j])})
        return final
        
Esempio n. 20
0
 def check_resources_renewable(self, **params):
     sol_mode = self.get_modes()
     usage = self.instance.data['needs']
     resource_usage = sol_mode.kvapply(lambda k, v: usage[k][v])
     avail = self.instance.data['resources'].get_property('available')
     renewable_res = self.instance.get_renewable_resources()
     sol_start = self.get_start_times()
     sol_finished = self.get_finished_times()
     job_periods = sol_start.sapply(func=range, other=sol_finished)
     makespan = self.get_objective()
     consumption_rt = \
         pt.SuperDict({(r, t): 0 for r in renewable_res for t in range(makespan+1)})
     for job, periods in job_periods.items():
         for period in periods:
             # print(period)
             # print(job)
             for resource, value in resource_usage[job].items():
                 if resource in renewable_res:
                     consumption_rt[resource, period] += value
     errors_R = consumption_rt.kvapply(
         lambda k, v: avail[k[0]] - v).vfilter(lambda v: v < 0)
     return errors_R
Esempio n. 21
0
def graph_from_node(current, max_hour, max_hops=1):
    arcs = pt.SuperDict()
    max_time = pd.to_datetime(max_hour, format="%H:%M:%S")
    # nodes that I have not yet seen neighbors
    remaining = [current]
    iter = 0
    while len(remaining) > 0 and iter < 10000:
        iter += 1
        current = remaining.pop()
        if current in arcs:
            # if I've seen this node before:
            # it means I already added all arcs
            continue
        print('iter={}, current={}'.format(iter, current))
        neighbors  = current.get_neighbors_in_trip(max_time)
        if current.hops < max_hops:
            # if we have not yet reached the max number of trips,
            # we can search for a change of trip
            neighbors += current.get_neighbors_in_stop(max_time)
        for node in neighbors:
            arcs.set_m(current, node, value=1)
            remaining.append(node)
    return arcs
Esempio n. 22
0
 def from_dict(cls, data_json):
     data = pt.SuperDict({
         v['job']: pt.SuperDict(period=v['period'], mode=v['mode'])
         for v in data_json
     })
     return cls(data)
    def solve(self, options):
        model = cp_model.CpModel()
        input_data = pt.SuperDict.from_dict(self.instance.data)
        max_dur_job = input_data['durations'].vapply(lambda v: max(v.values()))
        horizon = sum(max_dur_job) + 1
        jobs_data = input_data['jobs']
        durations_data = pt.SuperDict.from_dict(input_data['durations'])
        needs_data = pt.SuperDict.from_dict(input_data['needs'])
        mode_dictionary_to_values = lambda v: v.to_tuplist().sorted(
            key=lambda x: x[0]).take(1)

        # variable declaration:
        starts = pt.SuperDict({
            job: model.NewIntVar(0, horizon, 'start_{}'.format(job))
            for job in jobs_data
        })
        ends = pt.SuperDict({
            job: model.NewIntVar(0, horizon, 'end_{}'.format(job))
            for job in jobs_data
        })
        job_mode = pt.SuperDict({
            job: model.NewIntVar(0,
                                 len(modes) - 1, 'mode_{}'.format(job))
            for job, modes in durations_data.items()
        })
        job_duration = pt.SuperDict({
            job: model.NewIntVar(min(modes.values()), max(modes.values()),
                                 'duration_{}'.format(job))
            for job, modes in durations_data.items()
        })
        interval = pt.SuperDict({
            job: model.NewIntervalVar(starts[job], job_duration[job],
                                      ends[job], 'interval_{}'.format(job))
            for job in jobs_data
        })
        mode_duration_perjob = durations_data.vapply(mode_dictionary_to_values)
        # definition of job duration
        [
            model.AddElement(job_mode[job], mode_duration_perjob[job],
                             job_duration[job]) for job in jobs_data
        ]

        # for each job and resource:
        # an array of consumptions (one per mode in order)
        needs_data_perjob = \
            needs_data. \
                to_dictup(). \
                to_tuplist(). \
                take([0, 2, 1, 3]). \
                to_dict([2, 3]). \
                vapply(sorted). \
                vapply(pt.TupList).vapply(lambda v: v.take(1))

        # for each job and resource:
        # a variable with the consumption
        job_consumption = needs_data_perjob.kvapply(
            lambda k, v: model.NewIntVar(min(v), max(v), 'consumption_{}_{}'.
                                         format(*k)))
        # definition of job consumption
        for (job, res), needs in needs_data_perjob.items():
            model.AddElement(job_mode[job], needs, job_consumption[job, res])

        # succession needs to be guaranteed
        for job, job_data in input_data['jobs'].items():
            for successor in job_data['successors']:
                model.Add(starts[successor] >= ends[job])

        # resource usage
        job_consumption_per_res = job_consumption.to_tuplist().take(
            [1, 0, 2]).to_dict(2, is_list=False).to_dictdict()
        for resource, res_data in input_data['resources'].items():
            # we get jobs that consume that resource and how much
            jobs, consumptions = zip(
                *job_consumption_per_res[resource].items_tl())
            relevant_intervals = [interval[j] for j in jobs]
            if resource in self.instance.get_renewable_resources():
                # renewable resources we use intervals to check them
                model.AddCumulative(intervals=relevant_intervals,
                                    demands=consumptions,
                                    capacity=res_data['available'])
            else:  # non renewable resources we sum all
                model.Add(sum(consumptions) <= res_data['available'])

        # we set the objective as the makespan
        obj_var = model.NewIntVar(0, horizon, 'makespan')
        model.AddMaxEquality(obj_var, ends.values())
        model.Minimize(obj_var)

        solver = cp_model.CpSolver()
        solver.parameters.max_time_in_seconds = options.get('timeLimit', 10)
        status = solver.Solve(model)
        if status not in [cp_model.OPTIMAL, cp_model.FEASIBLE]:
            return status
        start_sol = starts.vapply(solver.Value)
        mode_sol = job_mode.vapply(lambda v: solver.Value(v) + 1)
        _func = lambda x, y: dict(period=x, mode=y)
        solution = start_sol.sapply(func=_func, other=mode_sol)
        self.solution = Solution(solution)
        return status
Esempio n. 24
0
# one and only one start per task
for j in tasks:
    model += pl.lpSum(X[j, k] for k in K_j[j]) == 1

# only one task is active at any moment:
for k2 in periods:
    model += pl.lpSum(X[j, k] for j, k in JK_k2[k2]) == 1

# solve model:
solver = pl.PULP_CBC_CMD(msg=True)
# solver = pl.CPLEX_CMD(msg=True)
model.solve(solver)

# get tasks starts
starts_out = pt.SuperDict(X).vapply(pl.value).clean().keys_l()

solution = [-1 for p in periods]
for j, k in starts_out:
    for p2 in K2_jk[j, k]:
        solution[p2] = j

print("solution is \n{}".format(solution))

# verify that all periods are filled:
# counting if there is any with a minus -1
pt.TupList(solution).vfilter(lambda v: v == -1)

# verify that each task t appears exactly duration[t] times
task_count = pt.SuperDict().fill_with_default(keys=duration.keys())
for period, task in enumerate(solution):
Esempio n. 25
0
 def from_dict(cls, data):
     data_p = (data["routes"].to_dict(
         result_col=["pos", "node"],
         indices=["route"
                  ]).vapply(lambda r: r.sorted(key=lambda t: t[0]).take(1)))
     return cls(pt.SuperDict(routes=data_p))
Esempio n. 26
0
 def get_assignments(self):
     return pt.SuperDict({v["node"]: v["color"] for v in self.data["assignment"]})
Esempio n. 27
0
 def __init__(self, instance: Instance, solution: Solution):
     super().__init__(instance, solution)
     if solution is None:
         solution = Solution(pt.SuperDict())
     self.solution = solution
     return
Esempio n. 28
0
 def all_jobs_once(self, **params) -> pt.SuperDict[int, int]:
     missing = self.instance.data["jobs"].keys() - self.solution.data.keys()
     return pt.SuperDict({k: 1 for k in missing})
Esempio n. 29
0
 def all_jobs_once(self, **params):
     missing = self.instance.data['jobs'].keys() - self.solution.data.keys()
     return pt.SuperDict({k: 1 for k in missing})