def get_fitness(dna):
    # reset position
    e.solids[1].pos = [x, y]

    g = gene_functions.Gaps2(x, y)

    # set velocity based on input functions and weights from DNA
    for i in range(2):
        e.solids[1].velocity[i] = g.input0()[i] * dna[0] + \
                                  g.input3()[i] * dna[1] + \
                                  g.input4()[i] * dna[2]

    initial_velocity = e.solids[1].velocity

    # run the physics engine until either the termination condition is reached (termination function has to be put into the physics_engine.py
    runtime = pe.run_physics_engine(tick_length, e, time_limit)

    # if the simulation exceeds the time limit before the termination condition is reached, or way too quickly, the organism's fitness will be virtually 0
    if runtime >= time_limit or runtime <= tick_length * 10:
        return .00001 # can't be 0 bc that would cause division by 0 later on

    # fitness function, tries to minimize velocity while maximizing time spent before crashing back down to planet, uses normalized quantities
    velocity_magnitude = pe.distance(initial_velocity, [0, 0])

    norm_runtime = (runtime - tick_length * 10) / (time_limit - tick_length * 10)
    norm_velocity = velocity_magnitude / 5

    return (norm_runtime - norm_velocity) ** 2
def get_fitness(dna):
    # create unique object of gene function class for each iteration
    g = gene_functions.Gatd1()

    # set velocity based on input functions and weights from DNA
    for i in range(2):
        e.solids[0].velocity[i] = g.input0()[i] * dna[0] + \
                                  g.input1()[i] * dna[1]

    end_pos = pe.run_physics_engine(tick_length, e, time_limit)
    return 1 / (pe.distance([0, 0], end_pos)**.5)
def get_fitness(organism):
    # reset position, set velocity to what its DNA dictates
    e.solids[1].pos = [0, 11.001]
    e.solids[1].velocity = [0] + organism.dna

    # run the physics engine until either the termination condition is reached (termination function has to be put into the physics_engine.py
    runtime = pe.run_physics_engine(tick_length, e, time_limit)

    # if the simulation exceeds the time limit before the termination condition is reached, or way too quickly, the organism's fitness will be virtually 0
    if runtime >= time_limit or runtime <= tick_length * 10:
        return .001

    # fitness function, tries to minimize velocity while maximizing time spent before crashing back down to planet, uses normalized quantities
    velocity_magnitude = pe.distance([0] + organism.dna, [0, 0])

    norm_runtime = runtime / time_limit
    norm_velocity = velocity_magnitude / 5

    return (norm_runtime - norm_velocity)**2
Пример #4
0
def get_fitness(dna, destination):
    # create unique object of gene function class for each iteration
    g = gene_functions.Gasv1(e.g_strength[1], destination)

    # make sure to reset pos before starting again!!!!!!!!!!
    e.solids[0].pos = [-100, .001]

    # set velocity based on input functions and weights from DNA
    for i in range(2):
        e.solids[0].velocity[i] = g.input0()[i] * dna[0] + \
                                  g.input1()[i] * dna[1] + \
                                  g.input2()[i] * dna[2] + \
                                  g.input3()[i] * dna[3]

        if abs(e.solids[0].velocity[i]) >= 100:
            return 10 ** -10

    end_pos = pe.run_physics_engine(tick_length, e, time_limit)

    return 1 / (pe.distance(destination, end_pos) ** 2)
Пример #5
0
        velocity[j] = g.input0()[j] * dna[0]
                      # g.input1()[j] * dna[1] + \
                      # g.input4()[j] * dna[2]
    print(velocity)

            # print('velocity', velocity)

    e = environments.Environment(solids=[pe.Circle(static=True),
                            pe.Circle(radius=1, pos=i, velocity=velocity)],
                    g_type='nonuniform',
                    g_strength=10)


    # run the physics engine until either the termination condition is reached (termination function has to be put into the physics_engine.py
    runtime = pe.run_physics_engine(.2, e, 100)
    # print('runtime', runtime)

    # if the simulation exceeds the time limit before the termination condition is reached, or way too quickly, the organism's fitness will be virtually 0
    if runtime >= 100 or runtime <= .2 * 10:
        print('fitness', 0)
    else:
        # fitness function, tries to minimize velocity while maximizing time spent before crashing back down to planet, uses normalized quantities
        velocity_magnitude = pe.distance(velocity, [0, 0])

        norm_runtime = (runtime - .2 * 10) / (100 - .2 * 10)
        norm_velocity = velocity_magnitude / 5

        print('fitness', (norm_runtime - norm_velocity) ** 2)

    print()
import physics_engine as pe
from environments import Environment
import gene_functions

g = gene_functions.Gatd1()

velocity = [0, 0]
dna = [1.0493179215779653, 0.26432598219944303]

for j in range(2):
    velocity[j] = g.input0()[j] * dna[0] + \
                  g.input1()[j] * dna[1]


e = Environment(solids=[pe.Circle(pos=[-100, -100], velocity=velocity),
                        pe.Rect(static=True, pos=[-155, 0], height=300),
                        pe.Rect(static=True, pos=[155, 0], height=300),
                        pe.Rect(static=True, pos=[0, -155], width=300),
                        pe.Rect(static=True, pos=[0, 155], width=300)],
                g_type='downward',
                g_strength=.2)

print(e.solids[0].velocity)

# run the physics engine until the termination condition is reached (termination function has to be put into the physics_engine.py and return statement corrected)
# time_limit is set to be virtually infinite because we are not worried about this environment running indefinitely, the ball will always eventually slow down to stop
end_pos = pe.run_physics_engine(.2, e, 10 ** 10)

print('fitness', 1 / pe.distance([0, 0], end_pos))
import gene_functions
from environments import Environment
import physics_engine as pe

dna = [-0.4782179829546539, 0.07012079426483595, 2.7799442290567735, 0.4543957971535216]

destination = [100, 100]
g = gene_functions.Gasv1(-9.81, destination)
velocity = [0, 0]

for i in range(2):
    velocity[i] = g.input0()[i] * dna[0] + \
                  g.input1()[i] * dna[1] + \
                  g.input2()[i] * dna[2] + \
                  g.input3()[i] * dna[3]

print('velocity', velocity)

e = Environment(solids=[pe.Circle(pos=[-100, .001], velocity=velocity)],
                g_type='uniform',
                g_strength=[0, -9.81])

end_pos = pe.run_physics_engine(.2, e, 10 ** 2)
print('end_pos', end_pos)

print('dist', pe.distance(end_pos, destination))
                if not solid.static:
                    for i in range(2):
                        solid.velocity[i] += e.g_strength[i] * tick_length

        # update velocities of non-static solids based on nonuniform gravity
        elif e.g_type == 'nonuniform':
            if not solid.static:
                for other in e.solids:
                    # don't let it apply gravity upon itself
                    if solid.pos == other.pos:
                        continue

                    # normalize velocity vector
                    x_diff = other.pos[0] - solid.pos[0]
                    y_diff = other.pos[1] - solid.pos[1]
                    dist = pe.distance(solid.pos, other.pos)
                    norm_dist_v = [x_diff / dist, y_diff / dist]
                    # formula for acceleration derived from Newton's formula for universal gravitation
                    g = (e.g_strength * other.mass) / ((solid.pos[0] - other.pos[0]) ** 2 + (solid.pos[1] - other.pos[1]) ** 2)

                    # use normalized vector, acceleration, and tick length to adjust velocity in either direction
                    for i in range(2):
                        solid.velocity[i] += norm_dist_v[i] * g * tick_length

        # downward gravity for top-down environments in which moving objects have friction with the background, which in this case is the floor
        elif e.g_type == 'downward':
            if not solid.static:
                lost_v = e.g_strength * solid.mass * tick_length

                vel_mag = pe.distance([0, 0], solid.velocity)
                      g.input5()[i] * dna[5]
    # print('destination', destination)
    # print('barrier_x', barrier_x)
    # print('velocity', velocity)

    if stahp:
        sys.exit()

    e = Environment(solids=[
        pe.Circle(pos=[-100, -100], velocity=velocity),
        pe.Rect(static=True, width=100, pos=[barrier_x, 0]),
        pe.Rect(static=True, pos=[-155, 0], height=300),
        pe.Rect(static=True, pos=[155, 0], height=300),
        pe.Rect(static=True, pos=[0, -155], width=300),
        pe.Rect(static=True, pos=[0, 155], width=300)
    ],
                    g_type='downward',
                    g_strength=.2)

    # run the physics engine until the termination condition is reached (termination function has to be put into the physics_engine.py and return statement corrected)
    # time_limit is set to be virtually infinite because we are not worried about this environment running indefinitely, the ball will always eventually slow down to stop
    end_pos = pe.run_physics_engine(.1, e, 10**10)

    total_distance += pe.distance(destination, end_pos)
    # print('end_pos', end_pos)
    # print('distance', pe.distance(destination, end_pos))
    # print()

print(total_distance)
print('total_distance', total_distance**.001)
# iterates through all generations
for generation in range(gen_count):
    # print percent progress
    if (generation * 100) / gen_count % 1 == 0:
        print((generation * 100) / gen_count)

    # calculate fitness of each organism
    for organism in p.organisms:
        organism.fitness = get_fitness(organism)

    # do natural selection and mutation
    p.natural_selection()
    p.reproduce('unweighted breeding')
    for organism in p.organisms:
        organism.mutate(mutate_chance, standard_deviations)

for organism in p.organisms:
    print(organism.dna, pe.distance([0] + organism.dna, [0, 0]),
          organism.fitness)

print('time elapsed:', time() - start_time)

# termination function needs to be copied into physics_engine.py above the run_physics_engine() function
# it is kept here to save it, because the copy of it in physics_engine.py has to be changed for each distinct algorithm used

# def termination(environ, tick_length):
#     next_pos = [0, environ.solids[1].pos[1] + (environ.solids[1].velocity[1] * tick_length)]
#     if distance([0, 0], next_pos) <= 11:
#         return True
#     return False