コード例 #1
0
 def crossover_population(self):
     candidates = []
     for i in range(self.num_crossovers):
         a = random.choice(self.population)
         b = random.choice(self.population)
         c = self.crossover_individuals(a, b)
         candidates.append(c)
     return candidates
コード例 #2
0
 def crossover_population(self):
     candidates = []
     population = [w for w, score in self.population]
     for i in range(self.num_candidates):
         a = random.choice(population)
         b = random.choice(population)
         c = self.crossover_weights(a, b)
         candidates.append(c)
     return candidates
コード例 #3
0
    def generate_tree_from_indexes(self, indexes):
        rootnode = Node(orientation=random.choice(
            [Orientation.Horizontal, Orientation.Vertical]),
                        children=[],
                        padding=random.choice([True, False]),
                        order=random.choice([-1, 1]),
                        t=0.5,
                        room_indexes=list(indexes),
                        score=None)
        self.generate_tree(rootnode)

        import json

        return rootnode
コード例 #4
0
    def crossover_individuals(self, a, b):
        new_vector = []

        for i, j in zip(a.vector, b.vector):
            new_vector.append(random.choice([i, j]))

        return DoorVectorScore(vector=new_vector, score=0)
コード例 #5
0
    def add_doors_depth_first(self, floorplan):
        visited_rooms = set([floorplan.rooms[0]])

        # pick starter room
        stack = deque([floorplan.rooms[0]])
        while len(visited_rooms) < len(floorplan.rooms):
            current = stack.popleft()
            for neighbor, edge in current.neighbors_and_edges:
                if neighbor in visited_rooms:
                    continue
                a, b = edge.t_bounds(4)
                if a is None:
                    continue

                side = random.choice([a, b])

                current_ap = (current.area / current.perimeter)
                neighbor_ap = (neighbor.area / neighbor.perimeter)

                direction = 1 if current_ap > neighbor_ap else -1

                edge.doors.append(
                    DoorFactory.interior_door(
                        side, direction, "left" if side == b else "right"))

                visited_rooms.add(neighbor)
                stack.append(neighbor)
コード例 #6
0
    def generate_tree(self, rootnode):
        if len(rootnode.room_indexes) <= 1:
            return

        # total_area = sum(areas)
        left, right = self.partition_list(rootnode.room_indexes)
        left_child = Node(orientation=random.choice(
            [Orientation.Horizontal, Orientation.Vertical]),
                          children=[],
                          padding=random.choice([True, False]),
                          order=random.choice([-1, 1]),
                          t=0.5,
                          room_indexes=left,
                          score=None)
        right_child = Node(orientation=random.choice(
            [Orientation.Horizontal, Orientation.Vertical]),
                           children=[],
                           padding=random.choice([True, False]),
                           order=random.choice([-1, 1]),
                           t=0.5,
                           room_indexes=right,
                           score=None)
        rootnode.children.extend([left_child, right_child])
        self.generate_tree(left_child)
        self.generate_tree(right_child)
コード例 #7
0
    def add_doors(self, door_vector):
        edge_list = self.edges

        if len(door_vector) != len(edge_list):
            raise Exception("Differing length of door vector and edges")

        for is_door, edge in zip(door_vector, edge_list):
            if is_door:
                a, b = edge.t_bounds(3.99)
                if a is None:
                    continue

                side = random.choice([a, b])
                direction = -1

                edge.doors.append(
                    DoorFactory.interior_door(side, direction, "left" if side == b else "right")
                )
コード例 #8
0
    def add_doors_minimum_spanning_tree(self, floorplan):

        matrix = np.full((len(floorplan.rooms), len(floorplan.rooms)),
                         np.inf,
                         dtype=np.float32)

        indexes = {}
        reverse_indexes = {}
        for i, room in enumerate(floorplan.rooms):
            indexes[room] = i
            reverse_indexes[i] = room

        for room in floorplan.rooms:
            for neighbor in room.neighbors:
                i = indexes[room]
                j = indexes[neighbor]
                matrix[i, j] = 1

        distances = scipy.sparse.csgraph.minimum_spanning_tree(matrix)
        # for di in distances:
        # print("Distance", di)
        for i, j in zip(*np.where(distances.toarray() == 1)):
            roomA = reverse_indexes[i]
            roomB = reverse_indexes[j]
            for neighbor, edge in roomA.neighbors_and_edges:
                if neighbor is roomB:
                    a, b = edge.t_bounds(4)
                    if a is None:
                        continue

                    side = random.choice([a, b])

                    current_ap = (roomA.area / roomA.perimeter)
                    neighbor_ap = (neighbor.area / neighbor.perimeter)

                    direction = 1 if current_ap > neighbor_ap else -1

                    edge.doors.append(
                        DoorFactory.interior_door(
                            side, direction, "left" if side == b else "right"))
コード例 #9
0
    def generate_candidate_floorplan(self):

        while True:
            used_rx = set()
            used_ry = set()

            floorplan = FloorPlan(
                [RoomFactory.Rectangle(self.lot_width, self.lot_height)])
            while len(floorplan.rooms) < len(self.desired_rooms):
                largest = self.get_largest_room(floorplan.rooms)

                while True:
                    rx, ry = self.get_random_point_in_room(largest)

                    correction_radius = 9
                    corrected_rx = self.get_nearest_value(
                        rx, correction_radius, used_rx)
                    corrected_ry = self.get_nearest_value(
                        ry, correction_radius, used_ry)

                    used_rx.add(corrected_rx)
                    used_ry.add(corrected_ry)

                    if largest.contains((corrected_rx, corrected_ry)):
                        break
                    else:
                        # Necessary to prevent infinite snap-to-grid loops
                        used_rx.add(rx)
                        used_ry.add(ry)

                floorplan.subdivide(
                    corrected_rx, corrected_ry,
                    random.choice(
                        [Orientation.Horizontal, Orientation.Vertical]))

            self.add_doors_depth_first(floorplan)
            self.add_doors_minimum_spanning_tree(floorplan)

            yield floorplan
コード例 #10
0
 def create_door_vector(length):
     return [ random.choice([0, 1]) for i in range(length) ]
コード例 #11
0
 def interior_door(t, direction, left_or_right=None):
     return Door(
         t, 6, direction, left_or_right
         if left_or_right is not None else random.choice(["left", "right"]))