def _generate_sample(self, config, node): max_x = math.inf max_y = math.inf min_x = -math.inf min_y = -math.inf anchors = [n for n in node.one_hop_neighbors if n.is_anchor] virtual_anchors = [] for a1 in anchors: # type: Node for a2 in anchors: # type: Node if a1 is not a2: va_x = ((a1.currentP.x - a2.currentP.x) / 2) + a1.currentP.x va_y = ((a1.currentP.y - a2.currentP.y) / 2) + a1.currentP.y virtual_anchors.append(Point(va_x, va_y)) if len(virtual_anchors) == 0: return super(VA_MCL, self)._generate_sample(config, node) for a in virtual_anchors: # type: Point max_x = min(max_x, a.x + config['communication_radius']) max_y = min(max_y, a.y + config['communication_radius']) min_x = max(min_x, a.x - config['communication_radius']) min_y = max(min_y, a.y - config['communication_radius']) return Point(uniform(min_x, max_x), uniform(min_y, max_y))
def predicting_step(self, sample_set): if len(sample_set) == 0: return Point(0, 0) x_pred = sum([p.x for p in sample_set]) / len(sample_set) y_pred = sum([p.y for p in sample_set]) / len(sample_set) return Point(x_pred, y_pred)
def sampling_step(self, config, node, sample_set): sampled_sample_set = [] for i in range(self.num_resample_iterations): for ss in sample_set: # type: SampleSet sampled_ss = SampleSet() for n, p in ss.node_dict.items(): d = random() * config['max_v'] a = uniform(0, 2 * math.pi) new_x = p.x + d * math.cos(a) new_y = p.y + d * math.sin(a) sampled_ss.node_dict[n] = Point(new_x, new_y) sampled_ss.node_dict_previous[n] = p for n in node.one_hop_neighbors: if n not in sampled_ss.node_dict: placed = sampled_ss.node_dict sampled_ss.node_dict[n] = self._generate_sub_sample( config, placed, n) for n in node.two_hop_neighbors: if n not in sampled_ss.node_dict: placed = sampled_ss.node_dict sampled_ss.node_dict[n] = self._generate_sub_sample( config, placed, n) sampled_sample_set.append(sampled_ss) return sampled_sample_set
def _generate_sample(self, config, node): max_x = math.inf max_y = math.inf min_x = -math.inf min_y = -math.inf for n1 in node.one_hop_neighbors: # type: Node if n1.is_anchor: max_x = min(max_x, n1.currentP.x + config['communication_radius']) max_y = min(max_y, n1.currentP.y + config['communication_radius']) min_x = max(min_x, n1.currentP.x - config['communication_radius']) min_y = max(min_y, n1.currentP.y - config['communication_radius']) elif self in n1.p_pred and self._are_lcc_close(node, n1): max_x = min( max_x, n1.p_pred[self.name()].x + config['communication_radius']) max_y = min( max_y, n1.p_pred[self.name()].y + config['communication_radius']) min_x = max( min_x, n1.p_pred[self.name()].x - config['communication_radius']) min_y = max( min_y, n1.p_pred[self.name()].y - config['communication_radius']) return Point(uniform(min_x, max_x), uniform(min_y, max_y))
def move(self): if self.currentP is not None: self.previousP = Point(self.currentP.x, self.currentP.y) if self.destination is None: self.destination = Point(random() * self.max_x, random() * self.max_y) distance = self.currentP.distance(self.destination) distance_x = self.destination.x - self.currentP.x distance_y = self.destination.y - self.currentP.y v = random() * (self.max_v - 1) + 1 if v < distance: x = self.currentP.x + (v * distance_x / distance) y = self.currentP.y + (v * distance_y / distance) self.currentP = Point(x, y) else: self.currentP = Point(self.destination.x, self.destination.y) self.destination = None
def sampling_step(self, config, node, sample_set): sampled_sample_set = [] for i in range(self.num_resample_iterations): for p in sample_set: d = random() * config['max_v'] a = uniform(0, 2 * math.pi) new_x = p.x + d * math.cos(a) new_y = p.y + d * math.sin(a) sampled_sample_set.append(Point(new_x, new_y)) return sampled_sample_set
def _generate_sample(self, config, node): max_x = math.inf max_y = math.inf min_x = -math.inf min_y = -math.inf for a in [n for n in node.one_hop_neighbors if n.is_anchor]: # type: Node max_x = min(max_x, a.currentP.x + config['communication_radius']) max_y = min(max_y, a.currentP.y + config['communication_radius']) min_x = max(min_x, a.currentP.x - config['communication_radius']) min_y = max(min_y, a.currentP.y - config['communication_radius']) return Point(uniform(min_x, max_x), uniform(min_y, max_y))
def _generate_sub_sample(self, config, placed, to_be_placed: Node): max_x = math.inf max_y = math.inf min_x = -math.inf min_y = -math.inf for n, p in placed.items(): # type: Node, Point if to_be_placed in n.one_hop_neighbors: max_x = min(max_x, p.x + config['communication_radius']) max_y = min(max_y, p.y + config['communication_radius']) min_x = max(min_x, p.x - config['communication_radius']) min_y = max(min_y, p.y - config['communication_radius']) return Point(uniform(min_x, max_x), uniform(min_y, max_y))
def predicting_step(self, sample_set): all_predicted_distances = {} for s in sample_set: # type: SampleSet for n in s.node_dict.keys(): if n not in all_predicted_distances: all_predicted_distances[n] = [] all_predicted_distances[n].append(s.node_dict[n]) avg_predicted_distances = {} for n in all_predicted_distances.keys(): avg_predicted_distances[n] = np.mean( [n.distance(Point(0, 0)) for n in all_predicted_distances[n]]) return avg_predicted_distances
def __init__(self, index, is_anchor, config, currentP=None): self.index = index self.is_anchor = is_anchor self.max_x = config['max_x'] self.max_y = config['max_y'] self.max_v = config['max_v'] self.communication_radius = config['communication_radius'] self.currentP = currentP if currentP is not None else Point( random() * self.max_x, random() * self.max_y) self.previousP = None self.destination = None self.one_hop_neighbors = [] self.two_hop_neighbors = [] self.one_hop_neighbor_predicted_distances = {} self.p_pred = {}
def _generate_sample(self, config, node): sample_set = SampleSet() sample_set.node_dict[node] = Point(0, 0) for n in node.one_hop_neighbors: placed = sample_set.node_dict sample_set.node_dict[n] = self._generate_sub_sample( config, placed, n) for n in node.two_hop_neighbors: placed = sample_set.node_dict sample_set.node_dict[n] = self._generate_sub_sample( config, placed, n) return sample_set
def run(self, num_time_instances=2, num_nodes=4, num_anchors=25, stage_size=(200, 200), max_v=50, communication_radius=50): config = { 'max_x': stage_size[0], 'max_y': stage_size[1], 'max_v': max_v, 'communication_radius': communication_radius, } # VA Example self.nodes = [] self.nodes.append( Node(0, is_anchor=False, config=config, currentP=Point(60, 100))) self.nodes.append( Node(1, is_anchor=True, config=config, currentP=Point(100, 100))) self.nodes.append( Node(2, is_anchor=True, config=config, currentP=Point(60, 60))) self.nodes.append( Node(3, is_anchor=False, config=config, currentP=Point(120, 130))) self.nodes.append( Node(4, is_anchor=True, config=config, currentP=Point(120, 70))) self.single_run(config, self.nodes) # Orbit Example self.nodes = [] self.nodes.append( Node(0, is_anchor=False, config=config, currentP=Point(100, 100))) self.nodes.append( Node(1, is_anchor=True, config=config, currentP=Point(110, 100))) self.nodes.append( Node(2, is_anchor=True, config=config, currentP=Point(90, 100))) self.nodes.append( Node(3, is_anchor=True, config=config, currentP=Point(135, 140))) self.nodes.append( Node(4, is_anchor=True, config=config, currentP=Point(50, 87))) self.single_run(config, self.nodes) # LCC Example self.nodes = [] self.nodes.append( Node(0, is_anchor=False, config=config, currentP=Point(100, 100))) self.nodes.append( Node(1, is_anchor=True, config=config, currentP=Point(140, 100))) self.nodes.append( Node(2, is_anchor=True, config=config, currentP=Point(140, 110))) self.nodes.append( Node(2, is_anchor=True, config=config, currentP=Point(130, 110))) self.nodes.append( Node(3, is_anchor=False, config=config, currentP=Point(140, 90))) self.nodes.append( Node(4, is_anchor=False, config=config, currentP=Point(65, 100))) self.nodes.append( Node(4, is_anchor=False, config=config, currentP=Point(100, 75))) self.nodes.append( Node(4, is_anchor=False, config=config, currentP=Point(150, 75))) self.single_run(config, self.nodes)
def run(self, num_time_instances=2, num_nodes=4, num_anchors=25, stage_size=(200, 200), max_v=50, communication_radius=50, should_plot=True): config = { 'max_x': stage_size[0], 'max_y': stage_size[1], 'max_v': max_v, 'communication_radius': communication_radius, } self.algorithms = [ TrinaryMCL(), ] # Trinary Example self.nodes = [] NUM_NODES_TO_RENDER = num_nodes # random.seed(NUM_NODES_TO_RENDER) for i in range(NUM_NODES_TO_RENDER): if i > 0: MAX_MOVEMENT = 2.0 new_p = Point(random.random() * (config['communication_radius'] * MAX_MOVEMENT) - (config['communication_radius'] * MAX_MOVEMENT / 2), random.random() * (config['communication_radius'] * MAX_MOVEMENT) - (config['communication_radius'] * MAX_MOVEMENT / 2)) random_int = i - math.ceil((min(5,i)) * random.random()) new_p.x += self.nodes[random_int].currentP.x new_p.y += self.nodes[random_int].currentP.y self.nodes.append(Node(i, is_anchor=False, config=config, currentP=new_p)) else: self.nodes.append(Node(i, is_anchor=False, config=config, currentP=Point(0, 0))) # Build state matrix and neighbor lists # Time=1 self.update_global_state_matrix(self.nodes, config['communication_radius']) self.update_one_hop_neighbors_lists(self.nodes) self.update_two_hop_neighbors_lists(self.nodes) # Move each node for n in self.nodes: # type: Node n.move() if should_plot: self.plot_nodes(config['communication_radius']) # Build state matrix and neighbor lists # Time=2 self.update_global_state_matrix(self.nodes, config['communication_radius']) self.update_one_hop_neighbors_lists(self.nodes) self.update_two_hop_neighbors_lists(self.nodes) # Make predictions for all nodes for algo in self.algorithms: # MDS calculation n_nodes = len(self.nodes) predicted_distances = np.ones((n_nodes,n_nodes)) * 100 # 50 # -1 # 100 predicted_distances_count = np.ones((n_nodes,n_nodes)) for n in self.nodes: n.one_hop_neighbor_predicted_distances[algo.name()] = {} algo.predict(config, self.nodes, self.current_global_state_matrix) for n in self.nodes: for n2 in n.one_hop_neighbors: predicted_distances[n.index][n2.index] = n.currentP.distance(n2.currentP) predicted_distances[n2.index][n.index] = n.currentP.distance(n2.currentP) predicted_distances_count[n.index][n2.index] += 1 predicted_distances_count[n2.index][n.index] += 1 for n2 in n.two_hop_neighbors: predicted_distances[n.index][n2.index] = n.currentP.distance(n2.currentP) predicted_distances[n2.index][n.index] = n.currentP.distance(n2.currentP) predicted_distances_count[n.index][n2.index] += 1 predicted_distances_count[n2.index][n.index] += 1 X_true = np.array([[p.currentP.x,p.currentP.y] for p in self.nodes]) # Get average predicted_distances = predicted_distances / predicted_distances_count # MDS mds_model = MDS(n_components=2, max_iter=3000, eps=1e-19, dissimilarity="precomputed") mds_positions = mds_model.fit_transform(predicted_distances) # mds_positions = mds_model.fit(predicted_distances).embedding_ # Rotate clf = PCA(n_components=2) X_true = clf.fit_transform(X_true) mds_positions = clf.fit_transform(mds_positions) # Rescale mds_positions *= np.sqrt((X_true ** 2).sum()) / np.sqrt((mds_positions ** 2).sum()) # new_X_true = X_true * np.sqrt((mds_positions ** 2).sum()) / np.sqrt((X_true ** 2).sum()) # new_mds_positions = mds_positions * np.sqrt((X_true ** 2).sum()) / np.sqrt((mds_positions ** 2).sum()) # Scale for i in [0,1]: d_true = X_true[:,i].max() - X_true[:,i].min() d_mds = mds_positions[:,i].max() - mds_positions[:,i].min() mds_positions[:,i] *= (d_true / d_mds) # Rotate clf = PCA(n_components=2) X_true = clf.fit_transform(X_true) mds_positions = clf.fit_transform(mds_positions) for i in range(len(self.nodes)): n1 = self.nodes[i] for j in range(len(self.nodes)): n2 = self.nodes[j] if i != j: print("not the same!") if n1.currentP.distance(n2.currentP) < config['communication_radius']: print("in distance!") # plt.plot([n1.currentP.x, n2.currentP.x], [n1.currentP.y, n2.currentP.y], '--r') # plt.plot([X_true[i,0], X_true[j,0]], [X_true[i,1], X_true[j,1]], '--r') # plt.plot([mds_positions[i,0], mds_positions[j,0]], [mds_positions[i,1], mds_positions[j,1]], ':b') if should_plot: plt.plot(X_true[:,0], X_true[:,1], '^r') plt.plot(mds_positions[:,0], mds_positions[:,1], '*b') for i in range(n_nodes): plt.text(X_true[i,0], X_true[i,1], str(i), color='r') plt.text(mds_positions[i,0], mds_positions[i,1], str(i), color='b') plt.legend(["True positions", "MDS predictions"]) print(X_true) print(mds_positions) err = 0 for i in range(len(X_true)): err = math.sqrt((X_true[i, 0] - mds_positions[i, 0])**2 + (X_true[i, 1] - mds_positions[i, 1])**2) print("Error: ", err) if should_plot: plt.show() return {'error': err}