Ejemplo n.º 1
0
def gaussian(ind, Pm, std, x_min, x_max):
    '''Gaussian mutation with rate of success Pm. If the mutation results in
        genes outside the specified bounds, they are set equal to the nearest
        bound.
    
    Arguments:
        ind {'individual' object} -- The individual.
        Pm {float} -- The rate of mutation as a decimal probability.
        std {float} -- Standard deviation for the gaussian function.
        x_min {float} -- Minimum bound on gene values.
        x_max {float} -- Maximum bound on gene values.
    
    Returns:
        'individual' object -- The mutated individual, or None.
    '''

    if ind:
        values = []
        for x in ind.values:
            if r.random() < Pm:
                values.append(x + np.random.normal(0, std))
            else:
                values.append(x)

            #stay within bounds
            if values[-1] < x_min:
                values[-1] = x_min
            if values[-1] > x_max:
                values[-1] = x_max

        return individual(values)
    return None
Ejemplo n.º 2
0
def two_point(Parents, n, Pc):
    '''Two point crossover. Same as single point except a second crossover
        point is calculated where the genome goes back to the first parent.
    
    Arguments:
        Parents {2-tuple of class 'individual'} -- The parents.
        n {int} -- The genome length
        Pc {float} -- The rate of success as a decimal propbability.
    
    Returns:
        'individual' object -- The child, or None.
    '''

    if r.random() < Pc:
        child_values = []
        crosspoint1 = r.randint(0, n)
        crosspoint2 = r.randint(crosspoint1, n)
        for i in range(n):
            if i < crosspoint1:
                child_values.append(Parents[0].values[i])
            elif i >= crosspoint1 and i < crosspoint2:
                child_values.append(Parents[1].values[i])
            else:
                child_values.append(Parents[0].values[i])
        return individual(child_values)
    return None #regenerate parent pair
Ejemplo n.º 3
0
def single_run(fdistr='RWS',
               fsamp='p_sample',
               fcross='single_point',
               fmut='uniform'):
    '''Driver for a single run of the GA. Genetic manipulation methods can be
        left blank or supplied for varying outcomes.
    
    Arguments:
        fdistr {str} -- RWS or distribution method if provided.
        fsamp {str} -- Proportional or sampling method if provided.
        fcross {str} -- Single-Point or crossover method if provided.
        fmut {str} -- Uniform or mutation method if provided.
    
    Returns:
        'individual' object -- The best-of-run individual.
    '''

    #initialize
    best_of_run = individual([0] * n)  #start with worst
    gen_count = 1
    P = []
    while len(P) < N:
        P.append(individual(None, n))

    while gen_count <= max_generations:
        distr(P, fdistr)  #calculate distribution
        for i in P:  #check if any are better than current BOR.
            if i.f > best_of_run.f:
                best_of_run = i
        P_next = []
        while len(P_next) < N:  #build next generation
            i = mut(cross((sample(P, fsamp), sample(P, fsamp)), fcross), fmut)
            if i:  #if not None
                P_next.append(i)

        gen_count += 1
        P = P_next

    print('Total evaluations for run:', ind.evals)
    return best_of_run
Ejemplo n.º 4
0
def uniform(ind, Pm, x_min, x_max):
    '''Uniform random mutation method.
        Replaces gene values regardless of current value.
    
    Arguments:
        ind {'individual' object} -- The individual.
        Pm {float} -- The rate of mutation as a decimal probability.
        x_min {float} -- Minimum bound on gene values.
        x_max {float} -- Maximum bound on gene values.
    
    Returns:
        'individual' object -- The mutated individual, or None.
    '''

    if ind:
        values = []
        for _ in ind.values:
            values.append(r.uniform(x_min, x_max))
        return individual(values)
    return None
Ejemplo n.º 5
0
def arithmatic(Parents, n, Pc, weight):
    '''Arithmatic crossover. Each gene is calculated as ax[i] + (1-a)y[i].
    
    Arguments:
        Parents {2-tuple of class 'individual'} -- The parents.
        n {int} -- The genome length
        Pc {float} -- The rate of success as a decimal propbability.
        weight {float} -- The weight that the first parent's genes have.
            0.5 will result in each parent contributing equally.
    
    Returns:
        'individual' object -- The child, or None.
    '''

    if r.random() < Pc:
        child_values = []
        for i in range(n):
            child_values.append( (weight * Parents[0].values[i]) + \
                ((1-weight) * Parents[1].values[i]) )
        return individual(child_values)
    return None
Ejemplo n.º 6
0
def single_point(Parents, n, Pc):
    '''Single point crossover with rate of success = Pc
    
    Arguments:
        Parents {2-tuple of class 'individual'} -- The parents.
        n {int} -- The genome length
        Pc {float} -- The rate of success as a decimal propbability.
    
    Returns:
        'individual' object -- The child, or None.
    '''

    if r.random() < Pc:
        child_values = []
        crosspoint = r.randint(0, n)
        for i in range(n):
            if i < crosspoint:
                child_values.append(Parents[0].values[i])
            else:
                child_values.append(Parents[1].values[i])
        return individual(child_values)
    return None #regenerate parent pair