def crossover(self, parents): parents.sort(key=lambda elem: len(elem[0].get_vertices())) crossover_point = random.randint(0, len(parents[0][0].get_vertices()) - 1) new_verts = parents[0][0].get_vertices( )[:crossover_point] + parents[1][0].get_vertices()[crossover_point:] return [Wall(new_verts), float('-inf')]
def __init__(self, pop_size, num_verts=8): self.pop_size = pop_size self.pop = [] for _ in range(self.pop_size): verts = [(random.uniform(-1.0, 1.0), random.uniform(-1.0, 1.0)) for __ in range(num_verts)] # pop: List[[Wall, fitness]] self.pop.append( [Wall([Vec(v[0], v[1]) for v in verts]), float('-inf')]) self.test_fitness()
def __init__(self, pop_size, num_verts=8): throat = 0.3 self.n_partilces = 10000 self.dt = 0.001 starting_angle = math.pi / 4 leghth = 1.5 self.pop_size = pop_size self.pop = [] for _ in range(self.pop_size): #verts = [(random.uniform(-1.0, 1.0), random.uniform(-1.0, 1.0)) for __ in range(num_verts)] x_pos = np.linspace(1.05, 1.05 - leghth * math.cos(starting_angle), num_verts) y_pos = np.linspace(throat / 2, leghth * math.sin(starting_angle), num_verts) verts = [(x_pos[i], y_pos[i]) for i in range(num_verts)] # pop: List[[Wall, fitness]] self.pop.append( [Wall([Vec(v[0], v[1]) for v in verts]), float('-inf')]) self.const_geom = [ [(1.0, -throat / 2), (1.5, -throat / 2), (2.0, -(throat / 2 + 0.4)), (2.0, -2.0), (4.0, -2.0), (4.0, 2.0), (2.0, 2.0), (2.0, (throat / 2 + 0.4)), (1.5, throat / 2), (1.0, throat / 2)], ] #[(1.05, throat/2 + 0.1),(0.0, 2.0)], #[(1.05, -throat/2 - 0.1),(0.0, -2.0)]] self.const_walls = [ Wall([Vec(v[0], v[1]) for v in w]) for w in self.const_geom ] self.bottom_wall = Wall( [Vec(verts[i][0], -verts[i][1]) for i in range(len(verts))]) #walls = [Wall([Vec(v[0], v[1]) for v in w]) for w in wall_vertices] self.test_fitness()
def objective(self, wall): pop_bottom_wall = Wall( [Vec(vert.x, -vert.y) for vert in wall.get_vertices()]) sim = Simulator( self.const_walls + [wall, pop_bottom_wall], genThermalIsotropic(100.0, 0.02, 2.0 + 0.1, -2.0 + 0.1, 55, self.n_partilces)) sim.many_step(100, self.dt) # magic number that works well-ish 1000 fx = 0 fy = 0 for wall in sim.get_walls(): fx += wall.force.x / self.n_partilces / self.dt / 2000 #fy += wall.force.y / self.n_partilces / self.dt / 2000 return -fx
def test_fitness(self): best_fitness = float('-inf') best_wall = self.pop[0][0] #best_stdev_x = 0 #best_stdev_y = 0 for elem in self.pop: wall = elem[0] fitness = self.objective(wall) if fitness > best_fitness: best_fitness = fitness best_wall = wall #best_stdev_x = stdev_x #best_stdev_y = stdev_y #print(f'stddev_x: {best_stdev_x}, stdev_y: {best_stdev_y}') #just for drawing self.bottom_wall = Wall( [Vec(vert.x, -vert.y) for vert in best_wall.get_vertices()]) return (best_wall, best_fitness)
return partcles throat = 0.3 n_partilces = 2000 dt = 0.001 wall_vertices = [[(1.0, -throat / 2), (1.5, -throat / 2), (2.0, -(throat / 2 + 0.4)), (2.0, -2.0), (4.0, -2.0), (4.0, 2.0), (2.0, 2.0), (2.0, (throat / 2 + 0.4)), (1.5, throat / 2), (1.0, throat / 2)], [(1.05, throat / 2 + 0.1), (0.0, 2.0)], [(1.05, -throat / 2 - 0.1), (0.0, -2.0)]] # wall_vertices = [[(1.0, 1.8), (1.8, 0.0), (1.0, -1.8)]] # wall_vertices = [] walls = [Wall([Vec(v[0], v[1]) for v in w]) for w in wall_vertices] thrust_value = [] thrust_frame = [] fig, ax = plt.subplots(1) axs = [ax] scatter, = axs[0].plot([], [], 'o', markersize=1) wall_plots = [axs[0].plot([], [], '-k')[0] for _ in range(len(walls))] #thrust, = axs[1].plot([],[],"-r") def anim_init(): axs[0].set_xlim(-4.0, 4.0) axs[0].set_ylim(-4.0, 4.0) #axs[1].set_ylim(-0.1,4.0)