def neighbors(self): """Return neighbor agents within the communication range.""" cache = self.scheduler.zone_cache if not cache: die("update_zone() must have been called for zone caching.") p = self.mobility.current i, j = self.zone() neighbors = [] # check nine zones including/surrounding the current one for dj in [-1, 0, 1]: if j + dj < 0: continue for di in [-1, 0, 1]: if i + di < 0: continue if not cache.get(j + dj, None): continue if not cache[j + dj].get(i + di, None): continue for agent in self.scheduler.zone_cache[j + dj][i + di]: if agent == self: continue q = agent.mobility.current if abs(p[0] - q[0]) > self.range_: continue if abs(p[1] - q[1]) > self.range_: continue if math.sqrt((p[0] - q[0])**2 + (p[1] - q[1])**2) > self.range_: continue neighbors.append(agent) return neighbors
def create_random_graph(self, N=10, E=20, no_multiedge=False): if E < N: die('Too small number of edges') for v in range(1, N + 1): self.add_vertices(v) # add first (N - 1) edges for making sure connectivity for i in range(1, N): u = i + 1 v = random.randrange(1, u) if random.uniform(0, 1) >= 0.5: self.add_edge(u, v) else: self.add_edge(v, u) # randomly add remaining (E - (N - 1)) edges for i in range(1, E - (N - 1) + 1): # FIXME: avoid cycle edges, but this may take log time ntries = 1 while ntries < MAX_RETRIES: u = random.randrange(1, N + 1) v = random.randrange(1, N + 1) if not no_multiedge and u != v: break if no_multiedge and u != v and not self.has_edge(u, v): break self.add_edge(u, v) return self
def __init__(self, scheduler=None): if scheduler is None: die("Scheduler class must be specified.") self.scheduler = scheduler self.tx_total = 0 self.rx_total = 0 self.dup_total = 0 self.uniq_total = 0 self.delivered_total = 0 self.uniq_delivered_total = 0
def __init__(self, path=None, *args, **kwargs): super().__init__(*args, **kwargs) if not path: die("Underlying path class must be specified.") if not path.graph: die("Path class doesn't return a valid graph via path.graph.") self.path = path self.current_edge = None self.current_offset = None self.wait = True # choose a random point on a graph self.move_to_point(*self.random_point())
def __init__(self, id_=None, scheduler=None, mobility=None, monitor=None, range_=50): if id_ is None: id_ = len(scheduler.agents) + 1 if not scheduler: die("Scheduler class must be specified.") if not mobility: die("Mobility class must be specified.") if not monitor: die("Monitor class must be specified.") if range_ > MAX_RANGE: die(f"range cannot exceed MAX_RANGE ({MAX_RANGE})") self.id_ = id_ self.scheduler = scheduler self.mobility = mobility self.monitor = monitor self.range_ = range_ self.last_neighbors = [] self.received = defaultdict(int) self.receive_queue = defaultdict(int) self.delivered = defaultdict(int) self.tx_count = 0 self.rx_count = 0 self.dup_count = 0 self.scheduler.add_agent(self)
def usage(): prog = os.path.basename(sys.argv[0]) die(f""" usage: {prog} [-v] [-s #] [-n #] [-r range] [-I id[,id]...] [-m mobility] [-p path] [-a agent] [-M monitor] -v verbose mode -s # seed of random number generator -n # number of agents -r range communication range [m] -I id[,id...] initial infected nodes -m mobility name of mobility class (Fixed/FullMixed/LevyWalk/LimitedRandomWaypoint/RandomWalk/RandomWaypoint/graph.Fixed/graph.Sequential/graph.RandomWalk/grpah.CRWP) -p path name of path class (NONE/Line/Grid/Voronoi) -a agent name of agent class (CarryOnly/Random/Epidemic/P_BCAST/SA_BCAST/HP_BCAST/ProPHET) -M monitor name of monitor class (Null/Log/Cell) """)
def __init__(self, id_=None, scheduler=None, mobility=None, monitor=None, pydtnsim=None, range_=50): super().__init__( id_=id_, scheduler=scheduler, mobility=mobility, monitor=monitor, range_=range_) if not pydtnsim: die("class pydtnsim is must be specified.") self.pydtnsim=pydtnsim
def import_dot(self, lines): buf = '' for line in lines: # remove C++-style comment pos = line.find('//') if pos >= 0: line = line[pos:] line = line.strip() buf += line # remove C-style comment buf = re.sub(r'/\*.*?\*/', '', buf) m = re.search(r'graph\s+(\S+)\s*{(.*)}', buf) if not m: die('Invalid graph format (missing dot graph header)') body = m.group(2) return self._import_dot_body(body)
def export_graph(self, fmt, *args): name = EXPORT_SUBP.get(fmt, None) method = getattr(self, name, None) if not name or not method: die(f"No export support for graph format `{fmt}'") return method(*args)
def expect_multiedged(self): if not self.multiedged(): die('multiedged graph expected')
def expect_directed(self): if not self.directed(): die('directed graph expected')
def expect_undirected(self): if not self.undirected(): die('undirected graph expected')