def k_means(X, k, n, init=None):
    # INITIALIZATION
    # return two vectors for the minimum and maximum point values for each dimension in the data

    # initialize the means by selecting random points from the dirts
    if init is None or len(init) != k:
        if k <= len(X):
            means = random.sample(X, k)
        else:
            means = X + random.choices(X, k=k - len(X))
    else:
        if len(init) != k: print('init is the incorrect size')
        means = init

    for i in range(n):
        dists = [[distance2(u, x) for u in means]
                 for x in X]  # using distance squared because square roots
        # are expensive and argmin(x) == argmin(x^2)
        clusters = [[x for (x, ds) in zip(X, dists) if ds.index(min(ds)) == i]
                    for i in range(k)]

        means = [
            vector_average(xs) if xs else u
            for (xs, u) in zip(clusters, means)
        ]

    return (clusters, means)
示例#2
0
    def __init__(self, point_item):
        self.vertices = set()
        if not point_item.is_bounded():
            return

        # Compute segments edges
        for other in point_item.others:
            v1, v2 = other.vertices()
            for v in [v1, v2]:
                EPSILON = 1e-4
                distances = list(utils.distance2(v, i) for i in self.vertices)
                if len(distances) == 0 or min(distances) > EPSILON:
                    self.vertices |= {v}

        # Sort vertices to make the shape convex
        self.vertices = list(self.vertices)
        OA = utils.vector(point_item.point, self.vertices[0])
        len_OA = utils.length(OA)
        t = {(self.vertices[0], 0)}
        for vertex in self.vertices[1:]:
            OB = utils.vector(point_item.point, vertex)
            len_OB = utils.length(OB)
            cos_angle = utils.dot(OA, OB) / (len_OA * len_OB)
            if cos_angle < -1:
                cos_angle = -1
            elif cos_angle > 1:
                cos_angle = 1

            angle = math.acos(cos_angle)
            if utils.cross(OA, OB) < 0:  # sign of sin
                angle = 2 * math.pi - angle
            t |= {(vertex, angle)}
        self.vertices = list(vertex
                             for vertex, _ in sorted(t, key=lambda x: x[1]))
示例#3
0
 def delete_points(self, points_to_delete):
     EPSILON = 1e-4
     others_to_delete = set()
     for p in points_to_delete:
         for other in self.others:
             if utils.distance2(other.item.point, p) < EPSILON:
                 others_to_delete |= {other}
     self.others -= others_to_delete
示例#4
0
    def get_mask(self, width, height):
        # TODO caching static lights would optimize somewhat, but invalidation
        # needs to be taken into account
        mask = BitMask.zeros(width, height)
        if not self.lit:
            return mask

        # TODO this could be optimized to a square of 2 * range
        for y, row in enumerate(mask):
            for x, c in enumerate(row):
                if distance2(self._owner.pos, (x, y)) <= (self._range * self._range):
                    mask[y][x] = 1
        return mask
示例#5
0
 def delete_points(self, points_to_delete):
     EPSILON = 1e-4
     items_to_delete = set()
     for i in self.point_items:
         to_delete = False
         for p in points_to_delete:
             if utils.distance2(i.point, p) < EPSILON:
                 items_to_delete |= {i}
                 to_delete = True
                 break
         if not to_delete:
             i.delete_points(points_to_delete)
     self.point_items -= items_to_delete
示例#6
0
 def distance2(self, other):
     return distance2(self.pos, other.pos)
示例#7
0
 def build_network(self):
     self.network = nx.Graph()
     for u in self.env.agents:
         for v in [a for a in self.env.agents if distance2(u.location,a.location) <= self.range**2]:
             if not u is v: self.network.add_edge(u,v)
def find_nearest(agent_location, dirts):
    dists = [distance2(agent_location, d) for d in dirts]
    return dirts[dists.index(min(dists))]
    def p_greedy_drone(percepts):
        agent_location = percepts['GPS']
        agent_heading = percepts['Compass']
        # collect communication data
        dirts = [o[1] for o in percepts['Objects'] if o[0] == 'Dirt']
        drones = [
            d[1] for d in percepts['Objects']
            if d[0] == 'Drone' and d[1] != agent_location
        ]

        if dirts:
            close_dirts = [
                d for d in dirts
                if distance2(d, agent_location) < (sensor_radius * .75)**2
            ]
            if close_dirts:  # if there are dirts close to you, move towards the center (of mass) of them
                target = vector_average(close_dirts)
            else:  # if there are no dirts close to you, move towards the closest dirt
                target = find_nearest(agent_location, dirts)

            if drones:  # if there are drones around, move away from them by half your sensor radius
                targets = [target]
                for d in [
                        d for d in drones
                        if distance2(d, agent_location) < (sensor_radius)**2
                ]:
                    targets.append(
                        vector_add(
                            scalar_vector_product(
                                sensor_radius * .5,
                                vector_add(agent_location,
                                           scalar_vector_product(-1, d))),
                            agent_location))
                target = vector_average(targets)

            command = go_to(agent_location, agent_heading, target, bump=False)
            return command
        elif drones:  # if no dirts, but there are drones around
            targets = []
            for d in [
                    d for d in drones
                    if distance2(d, agent_location) < (sensor_radius)**2
            ]:
                targets.append(
                    vector_add(
                        scalar_vector_product(
                            sensor_radius * .5,
                            vector_add(agent_location,
                                       scalar_vector_product(-1, d))),
                        agent_location))
            if targets:
                target = vector_average(targets)
                return go_to(agent_location, agent_heading, target, bump=False)
            else:
                return random.choice([
                    'TurnRight', 'TurnLeft', 'MoveForward', 'MoveForward',
                    'MoveForward', 'MoveForward'
                ])
        else:  # if no dirts and no drones, make a random action
            return random.choice([
                'TurnRight', 'TurnLeft', 'MoveForward', 'MoveForward',
                'MoveForward', 'MoveForward'
            ])