コード例 #1
0
    def get_arriving_clusters_from_positions(self, vehicle_positions,
                                             outgoing_edges, IDs):

        arrivals = self.get_arrival_times(vehicle_positions)

        tally = {}
        arriving_cluster_info = {}

        arriving_clusters = ClusterSequence()

        for vehID, arrival, outgoing_edge in zip(IDs, arrivals,
                                                 outgoing_edges):
            bucket = arrival // self.sampling_interval
            try:
                tally[bucket] += 1
                arriving_cluster_info[bucket * self.sampling_interval].append(
                    VehicleInfo(vehID, arrival, outgoing_edge))
            except KeyError:
                tally[bucket] = 1
                arriving_cluster_info[bucket * self.sampling_interval] = [
                    VehicleInfo(vehID, arrival, outgoing_edge)
                ]

        for bucket, count in tally.items():
            arriving_clusters.insort(
                Cluster(count=count,
                        arrival=bucket * self.sampling_interval,
                        departure=(bucket + 1) * self.sampling_interval))

        return arriving_clusters, arriving_cluster_info
コード例 #2
0
    def get_queued_clusters_from_positions(self, vehicle_positions,
                                           outgoing_edges, IDs):

        arrival_times = self.get_arrival_times(vehicle_positions)

        queued_clusters = ClusterSequence()
        queued_cluster_info = {}

        queue_length = len(arrival_times)
        queue_arrival = 0
        queue_duration = queue_length / self.saturation_flow_rate
        queue_departure = self.round_to_delta(queue_arrival + queue_duration)
        queue_cluster = Cluster(count=queue_length,
                                arrival=queue_arrival,
                                departure=queue_departure)

        queued_clusters.insort(queue_cluster, merge=True)

        for vehID, arrival, outgoing_edge in zip(IDs, arrival_times,
                                                 outgoing_edges):
            try:
                queued_cluster_info[queue_arrival].append(
                    VehicleInfo(vehID, arrival, outgoing_edge))
            except KeyError:
                queued_cluster_info[queue_arrival] = [
                    VehicleInfo(vehID, arrival, outgoing_edge)
                ]

        return queued_clusters, queued_cluster_info
コード例 #3
0
 def construct_outflow(self, inflow, phase_sequence, start_times):
     curr_cluster = ScheduleStatus({phase: 0 for phase in inflow})
     outflow = ClusterSequence()
     for phase, start in zip(phase_sequence, start_times):
         next_cluster = inflow[phase][curr_cluster[phase]]
         outflow.append(
             Cluster(count=next_cluster.count,
                     arrival=start,
                     departure=start + next_cluster.duration))
         curr_cluster.schedule_in_place(phase)
     return outflow
コード例 #4
0
 def get_arriving_clusters(self, arrivals):
     tally = {}
     arriving_clusters = ClusterSequence()
     for arrival in arrivals:
         bucket = arrival // self.sampling_interval
         try:
             tally[bucket] += 1
         except KeyError:
             tally[bucket] = 1
     for bucket, count in tally.items():
         arriving_clusters.insort(
             Cluster(count=count,
                     arrival=bucket * self.sampling_interval,
                     departure=(bucket + 1) * self.sampling_interval))
     return arriving_clusters
コード例 #5
0
 def __init__(self, phases, inflow=None, cluster_info=None):
     self.inflow = {phase: ClusterSequence()
                    for phase in phases} if inflow is None else inflow
     self.cluster_info = {phase: {}
                          for phase in phases
                          } if cluster_info is None else cluster_info
     self.phases = sorted(phases)
コード例 #6
0
    def road_to_phase(self, edgeID, roadflow, turn_proportions):

        inflow = {}
        turns_by_phase = {}
        turns_from_edge = [
            turn for turn in turn_proportions
            if turn['incoming_edge'] == edgeID
        ]

        for turn in turns_from_edge:
            phase = turn['phase']
            try:
                turns_by_phase[phase] = min(
                    turns_by_phase[phase] + turn['probability'], 1)
            except KeyError:
                turns_by_phase[phase] = min(turn['probability'], 1)
                inflow[phase] = ClusterSequence()

        for cluster in roadflow:
            for phase, ratio in turns_by_phase.items():
                split = cluster.expected_proportion(ratio,
                                                    self.min_cluster_size)
                if split:
                    inflow[phase].insort(split, merge=True)

        return inflow
コード例 #7
0
    def publish_results(self, inflow, outflow, phase_sequence, road_ratio):
        outflow_by_edge = {}
        curr_cluster = {phase: 0 for phase in inflow}
        for outgoing_cluster, phase in zip(outflow, phase_sequence):
            original_cluster = inflow[phase][curr_cluster[phase]]
            curr_cluster[phase] += 1
            for incoming_edge, split_ratio in road_ratio[phase][
                    original_cluster.arrival].items():
                turns_from_edge = self._get_normalized_turn_ratios(
                    incoming_edge, phase)
                for turn in turns_from_edge:
                    outgoing_edge = turn['outgoing_edge']
                    turn_probability = turn['probability']
                    outflow_to_edge = outgoing_cluster.expected_proportion(
                        split_ratio * turn_probability, self.min_cluster_size)
                    if outflow_to_edge:
                        try:
                            outflow_by_edge[outgoing_edge].insort(
                                outflow_to_edge, merge=True)
                        except KeyError:
                            outflow_by_edge[outgoing_edge] = ClusterSequence(
                                [outflow_to_edge])
                    else:
                        pass

        with self.shared_lock:
            self.publish_directory.clear()
            for edge, outflow in outflow_by_edge.items():
                self.publish_directory[edge] = outflow
            self.shared_results_directory[self.id] = self.publish_directory
コード例 #8
0
    def get_inflow_from_roadflow(self, roadflow, phases, turn_proportions):
        # Warning: road_to_phase doesn't return edge_inflow for every phase
        #          Only for phases relevant to the edge
        inflow = {phase: ClusterSequence() for phase in phases}
        road_count = {}
        for edge, edge_roadflow in roadflow.items():
            if edge_roadflow:
                edge_inflow = self.road_to_phase(edge, edge_roadflow,
                                                 turn_proportions)
                for phase, clusters in edge_inflow.items():
                    inflow[phase] = inflow[phase].merge(clusters)
                    if phase not in road_count:
                        road_count[phase] = {}
                    for cluster in clusters:
                        if cluster.arrival not in road_count[phase]:
                            road_count[phase][cluster.arrival] = {}
                        try:
                            road_count[phase][
                                cluster.arrival][edge] += cluster.count
                        except KeyError:
                            road_count[phase][
                                cluster.arrival][edge] = cluster.count

        return inflow, road_count
コード例 #9
0
    def get_feasible_control_flow(self, inflow, curr_phase,
                                  curr_phase_duration, curr_time, road_ratio):

        outflow = ClusterSequence()
        phase_sequence = []
        phase_duration = []
        updated_inflow = {phase: ClusterSequence() for phase in inflow}
        updated_road_ratio = {phase: {} for phase in inflow}

        violation_time = None

        tmp_curr_phase = curr_phase
        tmp_curr_phase_duration = curr_phase_duration
        tmp_curr_time = curr_time
        tmp_inflow = {
            phase: sequence.copy()
            for phase, sequence in inflow.items()
        }

        while violation_time != float('inf'):

            violation_time = float('inf')
            tmp_outflow, tmp_phase_sequence, tmp_phase_duration = self.scheduler.schedule(
                tmp_inflow, tmp_curr_phase, tmp_curr_phase_duration,
                tmp_curr_time)

            curr_index = 0

            for cluster, phase, duration in zip(tmp_outflow,
                                                tmp_phase_sequence,
                                                tmp_phase_duration):
                cluster_from_inflow = tmp_inflow[phase][0]
                if duration > self.Gmax[phase]:
                    violation_time = cluster.departure - (duration -
                                                          self.Gmax[phase])
                    if violation_time < cluster.arrival:
                        if curr_index == 0:
                            violation_time = tmp_curr_time
                        else:
                            previous_cluster = tmp_outflow[curr_index - 1]
                            violation_time = previous_cluster.departure

                    unviolated_outflow, violated_outflow = cluster.split(
                        violation_time, self.min_cluster_size)
                    unviolated_ratio = 1 - (violated_outflow.count /
                                            cluster.count)
                    unviolated_inflow, violated_inflow = cluster_from_inflow.split_by_ratio(
                        unviolated_ratio, self.min_cluster_size)

                    tmp_inflow[phase].set(0, violated_inflow)
                    road_ratio[phase][violated_inflow.arrival] = road_ratio[
                        phase][cluster_from_inflow.arrival]

                    if unviolated_outflow:

                        outflow.append(unviolated_outflow)
                        phase_sequence.append(phase)
                        phase_duration.append(self.Gmax[phase])
                        updated_inflow[phase].append(unviolated_inflow)
                        updated_road_ratio[phase][
                            unviolated_inflow.arrival] = road_ratio[phase][
                                cluster_from_inflow.arrival]

                    tmp_curr_time = violation_time + self.Y[phase]
                    tmp_curr_phase = self.get_next_phase(phase)
                    tmp_curr_phase_duration = 0

                    break
                else:
                    outflow.append(cluster)
                    phase_sequence.append(phase)
                    phase_duration.append(duration)
                    scheduled_cluster = tmp_inflow[phase].pop(0)
                    if scheduled_cluster:
                        updated_inflow[phase].append(scheduled_cluster)
                        updated_road_ratio[phase][
                            scheduled_cluster.arrival] = deepcopy(
                                road_ratio[phase][cluster_from_inflow.arrival])

                curr_index += 1

        return outflow, phase_sequence, phase_duration, updated_inflow, updated_road_ratio