def init_experiment(self): pysage.Arena.init_experiment(self) resource_utility = 0 for i in range(self.num_targets): target = self.targets[i] target.value = target.value_start resource_utility += target.value target.num_committed_agents = 0 # select target position randomly in the arena min_dist = self.dimensions_radius - target.size while True: # compute a random position within the arena while True: target.position = pysage.Vec2d( np.random.uniform(-min_dist, min_dist), np.random.uniform(-min_dist, min_dist)) if target.position.get_length( ) < self.dimensions_radius - target.size: break # check non overlapping position with other targets overlap = False for j in range(i): t = self.targets[j] if target.position.get_distance( t.position) < target.size + t.size: overlap = True break if not overlap: break print "Target id", i, "is at position", target.position # initialise agents uniformly within the arena max_pos_a = (self.dimensions_radius - CRWLEVYAgent.size) agents_on_targets = np.zeros(self.num_targets) agents_out = 0 for agent in self.agents: while True: agent.position = pysage.Vec2d( random.uniform(-max_pos_a, max_pos_a), random.uniform(-max_pos_a, max_pos_a)) if agent.position.get_length() < max_pos_a: break t = agent.init_on_target() if t is not None: agents_on_targets[self.targets.index(t)] else: agents_out += 1 self.results.new_run() self.results.store(np.mean(agents_on_targets), np.std(agents_on_targets), resource_utility) print agents_on_targets, agents_out, agents_out + sum( agents_on_targets)
def control(self, num_steps): # check if the agent is over any target if self.current_target is not None: if (self.current_target.position - self.position).get_length() > self.current_target.size: self.on_target = False self.current_target = None self.residence_times.append(self.steps_on_target) else: self.steps_on_target += 1 else: self.current_target = None for t in self.arena.targets: if (t.position - self.position).get_length() < t.size: self.current_target = t self.steps_on_target = 0 break # agent basic movement: go straight self.apply_velocity = pysage.Vec2d(CRWLEVYAgent.linear_speed, 0) self.apply_velocity.rotate(self.velocity.get_angle()) # agent random walk: decide step length and turning angle self.count_motion_steps -= 1 if self.count_motion_steps <= 0: # step length self.count_motion_steps = int( math.fabs( distribution_functions.levy(CRWLEVYAgent.std_motion_steps, CRWLEVYAgent.levy_exponent))) # turning angle crw_angle = 0 if CRWLEVYAgent.CRW_exponent == 0: crw_angle = distribution_functions.uniform_distribution( 0, (2 * math.pi)) else: crw_angle = distribution_functions.wrapped_cauchy_ppf( CRWLEVYAgent.CRW_exponent) self.apply_velocity.rotate(crw_angle) # check if close to the arena border if self.position.get_length( ) >= self.arena.size_radius - CRWLEVYAgent.size: self.apply_velocity = pysage.Vec2d(CRWLEVYAgent.linear_speed, 0) self.apply_velocity.rotate(math.pi + self.position.get_angle() + random.uniform(-math.pi / 2, math.pi / 2))
def __init__(self, config_element): # identification target self.id = config_element.attrib.get("id") if self.id is None: print "[ERROR] missing attribute 'id' in tag <subnet>" sys.exit(2) # if self.id == 'B': # print("target id", self.id, "is distance away", positionA) # position in meters self.position = pysage.Vec2d(0, 0) # value of the target (aggiunto da Violetta) self.value = 1 if config_element.attrib.get( "value") is None else float(config_element.attrib["value"]) # size of the target (radius) self.size = 0.02 if config_element.attrib.get( "size") is None else float(config_element.attrib["size"]) # color of the target self.color = "black" if config_element.attrib.get( "color") is None else config_element.attrib["color"] # number of agents commited to this target self.num_committed_agents = 0 # distance between targets self.distance = 0.7 if config_element.attrib.get( "distance") is None else float(config_element.attrib["distance"])
def __init__(self, config_element): # identification target self.id = config_element.attrib.get("id") if self.id is None: self.id = 0 # position in meters self.position = pysage.Vec2d(0, 0) # value of the target (aggiunto da Violetta) self.value = 1 if config_element.attrib.get( "value") is None else float(config_element.attrib["value"]) self.value_start = self.value # size of the target (radius) self.size = 0.02 if config_element.attrib.get( "size") is None else float(config_element.attrib["size"]) # color of the target self.color = "black" if config_element.attrib.get( "color") is None else config_element.attrib["color"] # number of agents commited to this target self.num_committed_agents = 0 # distance between targets self.distance = 0.7 if config_element.attrib.get( "distance") is None else float(config_element.attrib["distance"])
def __init__(self, config_element): pysage.Arena.__init__(self, config_element) self.results_filename = "CRWLEVY.dat" if config_element.attrib.get( "results") is None else config_element.attrib.get("results") self.results = Results() # is the experiment finished? self.has_converged = False self.convergence_time = float('nan') # control parameter: num_targets self.target_size = 0.02 if config_element.attrib.get( "target_size") is None else float( config_element.attrib["target_size"]) # control parameter: num_targets if config_element.attrib.get("num_targets") is None: print "[ERROR] missing attribute 'num_targets' in tag <arena>" sys.exit(2) self.num_targets = int(config_element.attrib["num_targets"]) nnruns = config_element.attrib.get("num_runs") if nnruns is not None: self.num_runs = int(nnruns) else: self.num_runs = 1 # create the targets self.targets = [] for i in range(0, self.num_targets): self.targets.append( Target(pysage.Vec2d(0, 0), self.target_size, self)) # control flag : value of flag self.central_place = None s_arena_type = config_element.attrib.get("arena_type") if s_arena_type == "bounded" or s_arena_type == "periodic" or s_arena_type == "unbounded" or s_arena_type == "circular": self.arena_type = s_arena_type else: print "Arena type", s_arena_type, "not recognised, using default value 'bounded'" self.arena_type = "bounded" # size_radius ssize_radius = config_element.attrib.get("size_radius") if ssize_radius is not None: self.dimensions_radius = float(ssize_radius) elif ssize_radius is None and self.arena_type == "circular": self.dimensions_radius = float(self.dimensions.x / 2.0) # control parameter: target_distance self.target_distance = 1.0 starget_distance = config_element.attrib.get("target_distance") if starget_distance is not None: self.target_distance = float(starget_distance) # variable in wich is stored the min among first passage time self.min_first_time = 0.0
def __init__(self, target_id, size, value, color, distance): # identification target self.id = target_id # position in meters self.position = pysage.Vec2d(0, 0) # value of the target (aggiunto da Violetta) self.value = value # size of the target (radius) self.size = size # color of the target self.color = color # number of agents commited to this target self.num_committed_agents = 0 # number of targets initialized self.targets_init = 0
def update( self ): # computes the desired motion and agent state for a in self.agents: a.control(self.num_steps) # if a.step_neighbours: print 'confirmed saved correctly' # apply the desired motion for a in self.agents: a.update() if a.position.get_distance((0,0)) > (self.dimensions_radius- a.size/2): current_angle = a.position.get_angle() a.position = pysage.Vec2d(self.dimensions_radius- a.size/2, 0) a.position.rotate(current_angle) # check convergence if self.check_quorum_reached() and not self.has_converged: self.has_converged = True self.convergence_time = self.num_steps # update simulation step counter self.num_steps += 1
def update(self): # computes the desired motion and agent state for a in self.agents: a.control(self.num_steps) # reset the count of aents on targets for t in self.targets: t.num_committed_agents = 0 # apply the desired motion - count the number of agents on each target agents_on_targets = np.zeros(self.num_targets) for a in self.agents: a.update() if a.position.get_distance( (0, 0)) > (self.dimensions_radius - a.size / 2): current_angle = a.position.get_angle() a.position = pysage.Vec2d(self.dimensions_radius - a.size / 2, 0) a.position.rotate(current_angle) if a.current_target is not None: a.current_target.num_committed_agents += 1 agents_on_targets[self.targets.index(a.current_target)] += 1 # update target value (exponential exploitation) and compute overall utility resource_utility = 0 for t in self.targets: for dt in range(int(self.timestep_length / self.integration_step)): t.value -= self.integration_step * t.value * self.exploitation_rate * ( t.num_committed_agents * t.num_committed_agents) resource_utility += t.value self.results.store(np.mean(agents_on_targets), np.std(agents_on_targets), resource_utility) # update simulation step counter self.num_steps += 1
def init_experiment(self): pysage.Arena.init_experiment(self) if self.arena_type == "unbounded": # unbounded arena has a central palce self.central_place = Target(self.dimensions / 2.0, self.target_size, self) # agents initialised in the center for agent in self.agents: agent.position = self.dimensions / 2.0 # targets initialised in circular sector for target in self.targets: ##### Different initalisation if bounded or unbounded # target_position_radius = random.uniform(self.dimensions_radius.x,self.dimensions_radius.y); target_position_angle = random.uniform(-math.pi, math.pi) target.position = self.dimensions / 2.0 + pysage.Vec2d( self.target_distance * math.cos(target_position_angle), self.target_distance * math.sin(target_position_angle)) elif self.arena_type == "circular": for target in self.targets: target_x = random.uniform(0, 2 * self.dimensions_radius) e1 = self.dimensions_radius - math.sqrt( math.pow(self.dimensions_radius, 2) - math.pow(target_x - self.dimensions_radius, 2)) e2 = self.dimensions_radius + math.sqrt( math.pow(self.dimensions_radius, 2) - math.pow(target_x - self.dimensions_radius, 2)) target.position = pysage.Vec2d(target_x, random.uniform(e1, e2)) del target_x, e1, e2 for agent in self.agents: on_target = True while on_target: pos_x = random.uniform(0, 2 * self.dimensions_radius) e1 = self.dimensions_radius - math.sqrt( math.pow(self.dimensions_radius, 2) - math.pow(pos_x - self.dimensions_radius, 2)) e2 = self.dimensions_radius + math.sqrt( math.pow(self.dimensions_radius, 2) - math.pow(pos_x - self.dimensions_radius, 2)) agent.position = pysage.Vec2d(pos_x, random.uniform(e1, e2)) del pos_x, e1, e2 on_target = False for t in self.targets: if (t.position - agent.position).get_length() < t.size: on_target = True break else: # targets initialised anywhere in the bounded or periodic arena for target in self.targets: ##### Different initalisation if bounded/periodic or unbounded target.position = pysage.Vec2d( random.uniform(self.target_size, self.dimensions.x - self.target_size), random.uniform(self.target_size, self.dimensions.y - self.target_size)) # agents initialised anywhere in the bounded/periodic arena for agent in self.agents: on_target = True while on_target: agent.position = pysage.Vec2d( random.uniform(0, self.dimensions.x), random.uniform(0, self.dimensions.y)) on_target = False for t in self.targets: if (t.position - agent.position).get_length() < t.size: on_target = True break self.inventory_size = 0 self.has_converged = False self.convergence_time = float('nan') self.results.new_run() self.min_first_time = 0.0
def control(self, num_steps): # first check if the agent is passing over any target if self.on_target and self.current_target is not None: if (self.current_target.position - self.position).get_length() > self.current_target.size: self.on_target = False self.current_target = None else: self.on_target = False self.current_target = None for t in self.arena.targets: if (t.position - self.position).get_length() < t.size: self.on_target = True self.current_target = t # check during each time step if the agent is at a target. # If yes, save target information to be used during N step # for decision when agent might not be under a target anymore self.step_target = t break # check all neighbors every time step to save their info for later processing # in case no neighbors are located at N step when decision is made step_neighbours = self.arena.get_neighbour_agents( self, CRWLEVYAgent.interaction_range) # if any neighbors available, save to the agent data if step_neighbours: self.step_neighbours = step_neighbours # make a decision every N time steps if num_steps % self.arena.decision_step == 0: # calculate time scaling from robot to macro TimeScaling = round( (self.arena.timestep_length * self.arena.time_scale * self.arena.decision_step), 7) # decision making if self.target_committed is None: # Discovery discovery_value = 0 discovery_target = None discovery_color = "black" if self.on_target or self.step_target: # if there is no current target, but has one target previously # visited then use this as the current target if self.step_target: self.current_target = self.step_target discovery_value = self.current_target.value * TimeScaling discovery_target = self.current_target.id discovery_color = self.current_target.color # Recruitment recruitment_value = 0 recruitment_target = None recruitment_color = "black" neighbours = self.arena.get_neighbour_agents( self, CRWLEVYAgent.interaction_range) if neighbours or self.step_neighbours: if neighbours: selected_neighbour = random.choice(neighbours) # if neighbor info was saved previously, also recruit elif self.step_neighbours: selected_neighbour = random.choice( self.step_neighbours) recruitment_value = selected_neighbour.target_value * TimeScaling recruitment_target = selected_neighbour.target_committed recruitment_color = selected_neighbour.target_color if discovery_value + recruitment_value > 1: print "[ERROR] Probabilities go over maximimum value" print repr(discovery_value + recruitment_value) sys.exit(2) # self.decision_made_Neigh = False # self.decision_made_Targ = False rand_number = random.uniform(0, 1) if rand_number < discovery_value: self.target_committed = discovery_target self.target_value = discovery_value / TimeScaling self.target_color = discovery_color self.arena.update_target_commitment(discovery_target, 1) # self.decision_made_Targ = True elif rand_number < discovery_value + recruitment_value: self.target_committed = recruitment_target self.target_value = recruitment_value / TimeScaling self.target_color = recruitment_color self.step_neighbours = None # reset list of neighbors after decision self.arena.update_target_commitment(recruitment_target, 1) # self.decision_made_Neigh = True # # else: self.decision_made_Neigh = False else: # Abandonment prob_abandonment = 1 / self.target_value * TimeScaling #0.5; #1.0 - self.current_target.value # Cross-Inhibition neighbours = self.arena.get_neighbour_agents( self, CRWLEVYAgent.interaction_range) prob_crossinhibition = 0 if neighbours or self.step_neighbours: if neighbours: selected_neighbour = random.choice(neighbours) # if neighbor info was saved previously, also do cross-inhibition elif self.step_neighbours: selected_neighbour = random.choice( self.step_neighbours) if selected_neighbour.target_committed != self.target_committed: prob_crossinhibition = selected_neighbour.target_value * TimeScaling #selected_neighbour.target_value # prob_crossinhibition = 0.3 * TimeScaling #selected_neighbour.target_value if prob_abandonment + prob_crossinhibition > 1.0: print "[ERROR] Probabilities go over maximimum value" sys.exit(2) # self.decision_made_Neigh = False if random.uniform(0, 1) < prob_abandonment + prob_crossinhibition: self.arena.update_target_commitment( self.target_committed, -1) self.target_committed = None self.target_value = 0 self.target_color = "black" self.step_neighbours = None # reset list of neighbors when decision made # self.decision_made_Neigh = True self.step_target = None # reset info self.step_neighbours = None # reset info # agent basic movement: go straight self.apply_velocity = pysage.Vec2d(CRWLEVYAgent.linear_speed, 0) self.apply_velocity.rotate(self.velocity.get_angle()) # agent random walk: decide step length and turning angle self.count_motion_steps -= 1 if self.count_motion_steps <= 0: # step length self.count_motion_steps = int( math.fabs( distribution_functions.levy(CRWLEVYAgent.std_motion_steps, CRWLEVYAgent.levy_exponent))) # turning angle crw_angle = 0 if CRWLEVYAgent.CRW_exponent == 0: crw_angle = random.uniform(0, (2 * math.pi)) else: crw_angle = wrapcauchy.rvs(CRWLEVYAgent.CRW_exponent) self.apply_velocity.rotate(crw_angle)
def init_experiment( self ): pysage.Arena.init_experiment(self) for i in range(self.num_targets): target = self.targets[i] target.num_committed_agents = 0 on_target = True # Get the location of the first target random and inside circle area environment # half the target distance while on_target: if i == 0: max_size = target.distance /2 while True: x1 = random.uniform(-max_size, max_size) negpos = random.choice((-1, 1)) y1 = math.sqrt(max_size**2 - x1**2) * negpos if math.sqrt(x1**2 + y1**2) == max_size: target.position = pysage.Vec2d(x1,y1) print"Target id", i, "is at position", target.position break # Get the location of the second target random, but set length away # from first target and inside circle area environment else: while True: targetA_pos = self.targets[0].position x = targetA_pos[0] * -1 y = targetA_pos[1] * -1 d2 = math.sqrt((x - 0)**2 + (y - 0)**2) if d2 < max_size * 2: target.position = pysage.Vec2d(x,y) print"Target id", i, "is at position", target.position break on_target= False for j in range(i): t = self.targets[j] if (t.position - target.position).get_length() < (t.size + target.size): on_target = True break for agent in self.agents: on_target = True while on_target: max_sizeA = (self.dimensions_radius - agent.size) while True: Arand1 = random.uniform(-max_sizeA, max_sizeA) Arand2 = random.uniform(-max_sizeA, max_sizeA) d1 = math.sqrt((Arand1 - 0)**2 + (Arand2 - 0)**2) if d1 < max_sizeA: agent.position = pysage.Vec2d(Arand1,Arand2) break on_target= False for t in self.targets: if (t.position - agent.position).get_length() < t.size: on_target = True break self.has_converged = False self.convergence_time = float('nan') self.results.new_run()
def control(self): # first check if some target is within the interaction range for t in self.arena.targets: if (t.position - self.position).get_length() < t.size: if not self.on_target: self.on_target = True self.count_motion_steps = 0 if t.id not in self.inventory: self.inventory.append(t.id) self.visited_target_id.append(t.id) if len(self.step_on_target_time) > 0: self.step_on_target_time.append( self.arena.num_steps - self.step_on_target_time[-1]) else: self.step_on_target_time.append(self.arena.num_steps) else: self.on_target = False if self.arena.arena_type == "unbounded" and (self.arena.num_steps + 1) % 5000 == 0: if self.arena.num_steps > 0: self.distance_from_centre.append( (self.arena.central_place.position - self.position).get_length()) ## if self.arena_type=="unbounded": ## if(self.arena.central_place.position - self.position).get_length() < self.arena.central_place.size: ## if not self.on_central_place: ## self.on_central_place = True ## self.count_motion_steps = 0 ## if len(self.step_on_central_place_time) > 0 : ## self.step_on_central_place_time.append(self.arena.num_steps - self.step_on_central_place_time[-1]) ## else: ## self.step_on_central_place_time.append(self.arena.num_steps) ## else: ## self.on_central_place = False # agent basic movement: go straight self.apply_velocity = pysage.Vec2d(CRWLEVYAgent.linear_speed, 0) self.apply_velocity.rotate(self.velocity.get_angle()) # agent random walk: decide step length and turning angle self.count_motion_steps -= 1 if self.count_motion_steps <= 0: # step length self.count_motion_steps = int( math.fabs( distribution_functions.levy(CRWLEVYAgent.std_motion_steps, CRWLEVYAgent.levy_exponent))) #self.count_motion_steps = math.fabs(stabrnd.stabrnd(CRWLEVYAgent.levy_exponent, 0, CRWLEVYAgent.std_motion_steps, CRWLEVYAgent.average_motion_steps, 1, 1)) # turning angle crw_angle = 0 if self.arena.arena_type == "unbounded" and ( scipy.random.random(1) <= CRWLEVYAgent.bias_probability): crw_angle = (self.arena.central_place.position - self.position ).get_angle() - self.velocity.get_angle() elif CRWLEVYAgent.CRW_exponent == 0: crw_angle = random.uniform(0, (2 * math.pi)) else: crw_angle = wrapcauchy.rvs(CRWLEVYAgent.CRW_exponent) self.apply_velocity.rotate(crw_angle)