def cluster_data_volume(self, cluster_id, intercluster_only=False): """ :param cluster_id: :param intercluster_only: :return: :rtype: pq.bit """ cluster = self._find_cluster(cluster_id) if not intercluster_only: # Handle the intra-cluster data volume segment_pairs = itertools.permutations(cluster.segments, 2) internal_volume = np.sum( [segment_volume(s, d, self.env) for s, d in segment_pairs]) else: internal_volume = 0 # Handle the inter-cluster data volume external_segments = list( set(self.sim.segments) - set(cluster.segments)) # Outgoing data ... segment_pairs = list( itertools.product(cluster.segments, external_segments)) # Incoming data ... segment_pairs += list( itertools.product(external_segments, cluster.segments)) external_volume = np.sum( [segment_volume(s, d, self.env) for s, d in segment_pairs]) total_volume = internal_volume + external_volume return total_volume
def communication_delay(self, begin, end): """ Compute the communication delay between any two segments. This is done as per Equation 1 in FLOWER. :param begin: :type begin: core.segment.Segment :param end: :type end: core.segment.Segment :return: The total communication delay in seconds :rtype: pq.second """ travel_delay = self.movement_model.shortest_distance(begin, end) / self.env.mdc_speed if begin.cluster_id == end.cluster_id: transmission_count = 1 elif (begin.cluster_id == self.sim.centroid.cluster_id) or ( end.cluster_id == self.sim.centroid.cluster_id): transmission_count = 2 else: transmission_count = 3 transmission_delay = transmission_count transmission_delay *= data.segment_volume(begin, end, self.env) transmission_delay /= self.env.comms_rate relay_delay = self.holding_time(begin, end) total_delay = travel_delay + transmission_delay + relay_delay return total_delay
def communication_delay(self, begin, end): """ Compute the communication delay between any two segments. This is done as per Equation 1 in FLOWER. :param begin: :type begin: core.segment.Segment :param end: :type end: core.segment.Segment :return: The total communication delay in seconds :rtype: pq.second """ duration, path = self.movement_model.shortest_distance(begin, end) travel_delay = duration / self.env.mdc_speed path_clusters = self.count_clusters(path) transmission_delay = len(path_clusters) transmission_delay *= data.segment_volume(begin, end, self.env) transmission_delay /= self.env.comms_rate relay_delay = self.holding_time(path_clusters[1:]) total_delay = travel_delay + transmission_delay + relay_delay return total_delay
def communication_delay(self, begin, end): """ Compute the communication delay between any two segments. This is done as per Equation 1 in FLOWER. :param begin: :type begin: core.segment.Segment :param end: :type end: core.segment.Segment :return: The total communication delay in seconds :rtype: pq.second """ travel_delay = self.movement_model.shortest_distance( begin, end) / self.env.mdc_speed if begin.cluster_id == end.cluster_id: transmission_count = 1 elif (begin.cluster_id == self.sim.centroid.cluster_id) or ( end.cluster_id == self.sim.centroid.cluster_id): transmission_count = 2 else: transmission_count = 3 transmission_delay = transmission_count transmission_delay *= data.segment_volume(begin, end, self.env) transmission_delay /= self.env.comms_rate relay_delay = self.holding_time(begin, end) total_delay = travel_delay + transmission_delay + relay_delay return total_delay
def communication_delay(self, begin, end): """ Compute the communication delay between any two segments. This is done as per Equation 1 in FLOWER. :param begin: :type begin: core.segment.Segment :param end: :type end: core.segment.Segment :return: The total communication delay in seconds :rtype: pq.second """ duration, path = self.movement_model.shortest_distance(begin, end) travel_delay = duration / self.env.mdc_speed path_clusters = self.count_clusters(path) transmission_delay = len(path_clusters) transmission_delay *= data.segment_volume(begin, end, self.env) transmission_delay /= self.env.comms_rate relay_delay = self.holding_time(path_clusters[1:]) total_delay = travel_delay + transmission_delay + relay_delay return total_delay
def communication_delay(self, begin, end): """ Compute the communication delay between any two segments. This is done as per Equation 1 in FLOWER. :param begin: :type begin: core.segment.Segment :param end: :type end: core.segment.Segment :return: The total communication delay in seconds :rtype: pq.second """ duration, path = self.movement_model.shortest_distance(begin, end) path_clusters = self.count_clusters(path) segment_speed_pairs = list() path_index = 0 last_segment = None for path_cluster in path_clusters: segments = list() if last_segment: segments.append(last_segment) while path[path_index] in path_cluster.tour.objects: segments.append(path[path_index]) last_segment = path[path_index] path_index += 1 if path_index >= len(path): break segment_speed_pairs.append((path_cluster.mdc_speed, segments)) travel_delay = 0. # * pq.second for speed, segments in segment_speed_pairs: cluster_distance = 0 # * pq.meter start_segment = segments[0] for end_segment in segments[1:]: distance = np.linalg.norm( start_segment.location.nd - end_segment.location.nd) cluster_distance += distance travel_delay += cluster_distance / speed transmission_delay = len(path_clusters) transmission_delay *= data.segment_volume(begin, end, self.env) transmission_delay /= self.env.comms_rate relay_delay = self.holding_time(path_clusters[1:]) total_delay = travel_delay + transmission_delay + relay_delay return total_delay
def centroid_data_volume(self, cluster_id): """ :param cluster_id: :return: :rtype: pq.bit """ centroid = self._find_cluster(cluster_id) # Handle the intra-centroid data volume segment_pairs = itertools.permutations(centroid.segments, 2) volume = np.sum( [segment_volume(s, d, self.env) for s, d in segment_pairs]) cluster_pairs = list() # Handle the incoming volume from each cluster for cluster in self.sim.clusters: other_clusters = list(self.sim.clusters) for other_cluster in other_clusters: # Cluster -> Other Cluster cluster_pairs.append((cluster, other_cluster)) # Other Cluster -> Cluster cluster_pairs.append((other_cluster, cluster)) for src_cluster, dst_cluster in cluster_pairs: src_segments = src_cluster.segments dst_segments = dst_cluster.segments segment_pairs = itertools.product(src_segments, dst_segments) volume += np.sum( [segment_volume(s, d, self.env) for s, d in segment_pairs]) return volume
def cell_volume(src, dst, env): """ :param src: :type src: flower.cell.Cell :param dst: :type dst: flower.cell.Cell :param env: :type env: core.environment.Environment :return: """ if (src, dst) in data_memo: return data_memo[(src, dst)] segment_pairs = itertools.product(src.segments, dst.segments) total_volume = 0. # pq.bit for src, dst in segment_pairs: total_volume += segment_volume(src, dst, env) data_memo[(src, dst)] = total_volume return total_volume
def cluster_data_volume(self, cluster_id, intercluster_only=False): """ :param cluster_id: :param intercluster_only: :return: :rtype: pq.bit """ current_cluster = self._find_cluster(cluster_id) cluster_index = self.sim.clusters.index(current_cluster) cluster_tree, preds = sp.breadth_first_order(self.cluster_graph, cluster_index, directed=False, return_predecessors=True) children_indexes = list() for index in cluster_tree: if preds[index] == cluster_index: children_indexes.append(index) cluster_graph = self.cluster_graph.toarray() cluster_graph[cluster_index] = 0 cluster_graph[:, cluster_index] = 0 components_count, labels = sp.connected_components(cluster_graph, directed=False) cluster_groups = collections.defaultdict(list) for index, label in enumerate(labels): if index == cluster_index: continue cluster_groups[label].append(self.sim.clusters[index]) # Build a set of "super clusters." These are just collections of all # segments from the clusters that make up each child branch from the # current cluster. super_clusters = collections.defaultdict(list) for label, clusters in cluster_groups.items(): for cluster in clusters: super_clusters[label].extend(cluster.tour.objects) # Now, we get the list of segment pairs that will communicate through # the current cluster. This does not include the segments within the # current cluster, as those will be accounted for separately. sc_index_pairs = itertools.permutations(super_clusters.keys(), 2) segment_pairs = list() for src_sc_index, dst_sc_index in sc_index_pairs: src_segments = super_clusters[src_sc_index] dst_segments = super_clusters[dst_sc_index] segment_pairs.extend( list(itertools.product(src_segments, dst_segments))) intercluster_volume = np.sum([segment_volume(src, dst, self.env) for src, dst in segment_pairs]) if not intercluster_only: # NOW we calculate the intra-cluster volume segment_pairs = itertools.permutations( current_cluster.tour.objects, 2) intracluster_volume = np.sum([segment_volume(src, dst, self.env) for src, dst in segment_pairs]) else: intracluster_volume = 0 # ... and the outgoing data volume from this cluster other_segments = list( set(self.sim.segments) - set(current_cluster.tour.objects)) segment_pairs = itertools.product(current_cluster.tour.objects, other_segments) intercluster_volume += np.sum([segment_volume(s, d, self.env) for s, d in segment_pairs]) return intercluster_volume + intracluster_volume