def can_attack(self, unit): if self.attack_range < dist(self, unit): return False if self.attack_range > 50 and not is_visible_from( self, unit, UnitTypes.bullet): return False return True
def find_nearest_obj(self, unit, units, set_of_types=None): found = [] if set_of_types is None: found = units else: for obj in units: if obj.unit_type in set_of_types: found.append(obj) if not found: return None found = sorted(found, key=lambda obj: dist(unit, obj)) return found[0] if len(found) == 1 or unit != found[0] else found[1]
def run(self): self.ga.initialisation() self.ga.evaluation() bestFitness = 0 bestDist = 0 bestChromoOverallRepres = None for g in range(self.ga.param['noGen']): self.ga.oneGenerationElitism() #self.ga.oneGeneration() #self.ga.oneGenerationSteadyState() bestChromo = self.ga.bestChromosome() if bestChromo.fitness > bestFitness: bestChromoOverallRepres = bestChromo.repres bestFitness = bestChromo.fitness bestDist = str(dist(bestChromo.repres, self.ga.problParam)) print('Best solution in generation ' + str(g) + ' is: ' + str(bestChromo.repres) + ' fitness = ' + str(bestChromo.fitness) + ' dist: ' + str(dist(bestChromo.repres, self.ga.problParam))) print("\n") print('Best solution overall is: ' + str(bestChromoOverallRepres) + ' fitness = ' + str(bestFitness) + ' dist: ' + str(bestDist))
def compute_centrality(nodes, origins, compute_r, compute_g, compute_b, compute_c, compute_s, radius, network_radius, beta, measures_to_normalize, accumulator_fields): """ Computes reach, gravity, betweenness, closeness, and straightness on a graph. |nodes|: graph representation; dictionary mapping node id's to |Node| objects |origins|: subset of nodes that will be used as sources of shortest path trees |compute_r|: compute reach? |compute_g|: compute gravity type index? |compute_b|: compute betweenness? |compute_c|: compute closeness? |compute_s|: compute straightness? |radius|: for each node, only consider other nodes that can be reached within this distance |network_radius|: use network radius or birds-eye radius? |beta|: parameter for gravity type index |measures_to_normalize|: a list of measures to normalize |accumulator_fields|: a list of cost attributes to accumulate """ # Number of nodes in the graph N = len(nodes) O = len(origins) if O > N: raise Invalid_Parameters_Exception("size of origins exceeds size of nodes") elif O == 0: return # Preprocessing have_accumulations = len(accumulator_fields) > 0 if have_accumulations: empty_accumulations = lambda: dict((field, 0.0) for field in accumulator_fields) have_locations = hasattr(nodes.values()[0], LOCATION) if compute_s and not have_locations: # We cannot compute straightness without node locations compute_s = False if compute_b: # Initialize betweenness values for id in nodes: setattr(nodes[id], BETWEENNESS, 0.0) # Initialize the sum of all node weights (normalization) sum_weights = 0.0 # Computation progress = Progress_Bar(O, 1, STEP_4) for s in origins: if s not in nodes: continue weight_s = getattr(nodes[s], WEIGHT) if have_locations: location_s = getattr(nodes[s], LOCATION) sum_weights += weight_s # Initialize reach (weighted and unweighted) computation for |s| # (normalization) reach_s = -1 weighted_reach_s = -weight_s # Initialize measures if compute_g: gravity_s = 0.0 if compute_b: P = {s: []} # Predecessors S = [] # Stack containing nodes in the order they are extended sigma = {s: 1.0} # Number of shortest paths from |s| to other nodes delta = {} # Dependency of |s| on other nodes if compute_c: d_sum_s = 0.0 if compute_s: straightness_s = 0.0 if have_accumulations: accumulations_s = {s: empty_accumulations()} d = {s: 0.0} # Shortest distance from |s| to other nodes # Queue for Dijkstra Q = [(0.0, s)] if network_radius else [(0.0, s, 0.0)] # If we use euclidean radius, make a list of all reachable nodes if not network_radius: reachable_s = set() for t in nodes: location_t = getattr(nodes[t], LOCATION) if dist(location_s, location_t) <= radius: reachable_s.add(t) # Dijkstra while Q and (True if network_radius else reachable_s): # Pop the closest node to |s| from |Q| if network_radius: d_sv, v = heappop(Q) else: d_sv, v, dist_sv = heappop(Q) if v in reachable_s: reachable_s.remove(v) weight_v = getattr(nodes[v], WEIGHT) if have_locations: location_v = getattr(nodes[v], LOCATION) compute = network_radius or dist_sv <= radius if compute: reach_s += 1 weighted_reach_s += weight_v if d_sv > 0: if compute_g: gravity_s += weight_v * exp(-d_sv * beta) if compute_c: d_sum_s += weight_v * d_sv if compute_s: straightness_s += (weight_v * dist(location_s, location_v) / d_sv) if compute_b: S.append(v) for w, d_vw, accumulations_vw in getattr(nodes[v], NEIGHBORS): # s ~ ... ~ v ~ w d_sw = d_sv + d_vw if not network_radius: # Use Euclidean distance location_w = getattr(nodes[w], LOCATION) dist_sw = dist(location_s, location_w) if compute_b: b_refresh = False add_w_to_Q = False if not w in d: # Found a path from |s| to |w| for the first time if d_sw <= radius or not network_radius: add_w_to_Q = True d[w] = d_sw if compute_b: b_refresh = True elif lt_tol(d_sw, d[w]): # Found a better path from |s| to |w| if d_sw <= radius or not network_radius: if d[w] <= radius or not network_radius: longer_path_node = (d[w], w) if network_radius else (d[w], w, dist_sw) Q.remove(longer_path_node) heapify(Q) add_w_to_Q = True d[w] = d_sw if compute_b: b_refresh = True if add_w_to_Q: new_node = (d_sw, w) if network_radius else (d_sw, w, dist_sw) heappush(Q, new_node) if have_accumulations: accumulations_s[w] = merge_maps(accumulations_s[v], dict(accumulations_vw), add) if compute_b: if b_refresh: sigma[w] = 0.0 P[w] = [] if eq_tol(d_sw, d[w]): # Count all shortest paths from |s| to |w| sigma[w] += sigma[v] # Update the number of shortest paths P[w].append(v) # |v| is a predecessor of |w| delta[v] = 0.0 # Recognize |v| as a predecessor if compute_r: setattr(nodes[s], REACH, weighted_reach_s) if compute_g: setattr(nodes[s], GRAVITY, gravity_s) if compute_b: while S: # Revisit nodes in reverse order of distance from |s| w = S.pop() delta_w = delta[w] if w in delta else 0.0 # Dependency of |s| on |w| for v in P[w]: weight_w = getattr(nodes[w], WEIGHT) delta[v] += sigma[v] / sigma[w] * (weight_w + delta_w) if w != s: between_w = getattr(nodes[w], BETWEENNESS) setattr(nodes[w], BETWEENNESS, between_w + delta_w) if compute_c: setattr(nodes[s], CLOSENESS, (1.0 / d_sum_s if d_sum_s > 0 else 0.0)) if compute_s: setattr(nodes[s], STRAIGHTNESS, straightness_s) nodes[s].reach = reach_s nodes[s].weighted_reach = weighted_reach_s if have_accumulations: total_accumulations_s = empty_accumulations() for v in accumulations_s: total_accumulations_s = merge_maps(total_accumulations_s, accumulations_s[v], add) for field in accumulator_fields: setattr(nodes[s], field, total_accumulations_s[field]) progress.step() # Normalization if BETWEENNESS in measures_to_normalize and O < N: measures_to_normalize.remove(BETWEENNESS) AddWarning(WARNING_NO_BETWEENNESS_NORMALIZATION) if measures_to_normalize: norm_progress = Progress_Bar(O, 1, PROGRESS_NORMALIZATION) for s in origins: if s not in nodes: continue reach_s = nodes[s].reach weighted_reach_s = nodes[s].weighted_reach # Normalize reach if compute_r and REACH in measures_to_normalize: weight_s = getattr(nodes[s], WEIGHT) try: setattr(nodes[s], NORM_REACH, reach_s / (sum_weights - weight_s)) except: setattr(nodes[s], NORM_REACH, 0.0) # Normalize gravity if compute_g and GRAVITY in measures_to_normalize: gravity_s = getattr(nodes[s], GRAVITY) try: setattr(nodes[s], NORM_GRAVITY, (exp(beta) * gravity_s / weighted_reach_s)) except: setattr(nodes[s], NORM_GRAVITY, 0.0) # Normalize betweenness if compute_b and BETWEENNESS in measures_to_normalize: betweenness_s = getattr(nodes[s], BETWEENNESS) try: setattr(nodes[s], NORM_BETWEENNESS, (betweenness_s / (weighted_reach_s * (reach_s - 1)))) except: setattr(nodes[s], NORM_BETWEENNESS, 0.0) # Normalize closeness if compute_c and CLOSENESS in measures_to_normalize: closeness_s = getattr(nodes[s], CLOSENESS) try: setattr(nodes[s], NORM_CLOSENESS, closeness_s * weighted_reach_s) except: setattr(nodes[s], NORM_CLOSENESS, 0.0) # Normalize straightness if compute_s and STRAIGHTNESS in measures_to_normalize: straightness_s = getattr(nodes[s], STRAIGHTNESS) try: setattr(nodes[s], NORM_STRAIGHTNESS, (straightness_s / weighted_reach_s)) except: setattr(nodes[s], NORM_STRAIGHTNESS, 0.0) norm_progress.step()
def compute_centrality(nodes, origins, compute_r, compute_g, compute_b, compute_c, compute_s, radius, beta, measures_to_normalize, accumulator_fields): """ Computes reach, gravity, betweenness, closeness, and straightness on a graph. |nodes|: graph representation; dictionary mapping node id's to |Node| objects |origins|: subset of nodes that will be used as sources of shortest path trees |compute_r|: compute reach? |compute_g|: compute gravity type index? |compute_b|: compute betweenness? |compute_c|: compute closeness? |compute_s|: compute straightness? |radius|: for each node, only consider other nodes that can be reached within this distance |beta|: parameter for gravity type index |measures_to_normalize|: a list of measures to normalize |accumulator_fields|: a list of cost attributes to accumulate """ # Number of nodes in the graph N = len(nodes) O = len(origins) if N == 0 or O == 0: return # Preprocessing have_accumulations = len(accumulator_fields) > 0 have_locations = hasattr(nodes.values()[0], LOCATION) if compute_s and not have_locations: # We cannot compute straightness without node locations compute_s = False if compute_b: # Initialize betweenness values for id in nodes: setattr(nodes[id], BETWEENNESS, 0.0) # Initialize the sum of all node weights (normalization) sum_weights = 0.0 # Computation progress = Progress_Bar(O, 1, STEP_4) for s in origins: weight_s = getattr(nodes[s], WEIGHT) if have_locations: location_s = getattr(nodes[s], LOCATION) sum_weights += weight_s # Initialize reach (weighted and unweighted) computation for |s| # (normalization) reach_s = -1 weighted_reach_s = -weight_s # Initialize measures if compute_g: gravity_s = 0.0 if compute_b: P = {s: []} # Predecessors S = [] # Stack containing nodes in the order they are extended sigma = {s: 1.0} # Number of shortest paths from |s| to other nodes delta = {} # Dependency of |s| on other nodes if compute_c: d_sum_s = 0.0 if compute_s: straightness_s = 0.0 if have_accumulations: empty_accumulations = lambda: dict((field, 0.0) for field in accumulator_fields) accumulations_s = {s: empty_accumulations()} d = {s: 0.0} # Shortest distance from |s| to other nodes Q = [(0.0, s)] # Queue for Dijkstra # Dijkstra while Q: # Pop the closest node to |s| from |Q| d_sv, v = heappop(Q) weight_v = getattr(nodes[v], WEIGHT) if have_locations: location_v = getattr(nodes[v], LOCATION) reach_s += 1 weighted_reach_s += weight_v if d_sv > 0: if compute_g: gravity_s += weight_v * exp(-d_sv * beta) if compute_c: d_sum_s += weight_v * d_sv if compute_s: straightness_s += (weight_v * dist(location_s, location_v) / d_sv) if compute_b: S.append(v) for w, d_vw, accumulations_vw in getattr(nodes[v], NEIGHBORS): # s ~ ... ~ v ~ w d_sw = d_sv + d_vw if compute_b: b_refresh = False if not w in d: # Found a path from |s| to |w| for the first time if d_sw <= radius: heappush(Q, (d_sw, w)) # Add |w| to |Q| if have_accumulations: accumulations_s[w] = merge_maps(accumulations_s[v], dict(accumulations_vw), add) d[w] = d_sw if compute_b: b_refresh = True elif lt_tol(d_sw, d[w]): # Found a better path from |s| to |w| if d_sw <= radius: if d[w] <= radius: Q.remove((d[w], w)) heapify(Q) heappush(Q, (d_sw, w)) # Add |w| to |Q| if have_accumulations: accumulations_s[w] = merge_maps(accumulations_s[v], dict(accumulations_vw), add) d[w] = d_sw if compute_b: b_refresh = True if compute_b: if b_refresh: sigma[w] = 0.0 P[w] = [] if eq_tol(d_sw, d[w]): # Count all shortest paths from |s| to |w| sigma[w] += sigma[v] # Update the number of shortest paths P[w].append(v) # |v| is a predecessor of |w| delta[v] = 0.0 # Recognize |v| as a predecessor if compute_r: setattr(nodes[s], REACH, weighted_reach_s) if compute_g: setattr(nodes[s], GRAVITY, gravity_s) if compute_b: while S: # Revisit nodes in reverse order of distance from |s| w = S.pop() delta_w = delta[w] if w in delta else 0.0 # Dependency of |s| on |w| for v in P[w]: weight_w = getattr(nodes[w], WEIGHT) delta[v] += sigma[v] / sigma[w] * (weight_w + delta_w) if w != s: between_w = getattr(nodes[w], BETWEENNESS) setattr(nodes[w], BETWEENNESS, between_w + delta_w) if compute_c: setattr(nodes[s], CLOSENESS, (1.0 / d_sum_s if d_sum_s > 0 else 0.0)) if compute_s: setattr(nodes[s], STRAIGHTNESS, straightness_s) nodes[s].reach = reach_s nodes[s].weighted_reach = weighted_reach_s if have_accumulations: total_accumulations_s = empty_accumulations() for v in accumulations_s: total_accumulations_s = merge_maps(total_accumulations_s, accumulations_s[v], add) for field in accumulator_fields: setattr(nodes[s], field, total_accumulations_s[field]) progress.step() # Normalization if BETWEENNESS in measures_to_normalize and O < N: measures_to_normalize.remove(BETWEENNESS) AddWarning(WARNING_NO_BETWEENNESS_NORMALIZATION) if measures_to_normalize: norm_progress = Progress_Bar(O, 1, PROGRESS_NORMALIZATION) for s in origins: reach_s = nodes[s].reach weighted_reach_s = nodes[s].weighted_reach # Normalize reach if compute_r and REACH in measures_to_normalize: weight_s = getattr(nodes[s], WEIGHT) try: setattr(nodes[s], NORM_REACH, reach_s / (sum_weights - weight_s)) except: setattr(nodes[s], NORM_REACH, 0.0) # Normalize gravity if compute_g and GRAVITY in measures_to_normalize: gravity_s = getattr(nodes[s], GRAVITY) try: setattr(nodes[s], NORM_GRAVITY, (exp(beta) * gravity_s / weighted_reach_s)) except: setattr(nodes[s], NORM_GRAVITY, 0.0) # Normalize betweenness if compute_b and BETWEENNESS in measures_to_normalize: betweenness_s = getattr(nodes[s], BETWEENNESS) try: setattr(nodes[s], NORM_BETWEENNESS, (betweenness_s / (weighted_reach_s * (reach_s - 1)))) except: setattr(nodes[s], NORM_BETWEENNESS, 0.0) # Normalize closeness if compute_c and CLOSENESS in measures_to_normalize: closeness_s = getattr(nodes[s], CLOSENESS) try: setattr(nodes[s], NORM_CLOSENESS, closeness_s * weighted_reach_s) except: setattr(nodes[s], NORM_CLOSENESS, 0.0) # Normalize straightness if compute_s and STRAIGHTNESS in measures_to_normalize: straightness_s = getattr(nodes[s], STRAIGHTNESS) try: setattr(nodes[s], NORM_STRAIGHTNESS, (straightness_s / weighted_reach_s)) except: setattr(nodes[s], NORM_STRAIGHTNESS, 0.0) norm_progress.step()