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
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
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
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)
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)
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)
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") )
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"))
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
def create_door_vector(length): return [ random.choice([0, 1]) for i in range(length) ]
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"]))