You are on page 1of 6

Genetic Algorithms and Its Use in the Optimization of an Engineering Model

Kansas State University, ME 400, M W 1:30pm


March 25, 2015, Manhattan, Kansas, USA

PROJECT 2 EVOLUTIONARY OPTIMIZATION


Caleb Shunatona
Mechanical Engineering Student
Kansas State University
Manhattan, Kansas, USA
ABSTRACT
The use of a stochastic algorithm helps engineers solve
more complex engineering models with multiple variables with
a more natural outcome. The engineering model given for a
spring-mass-dampener can be solved using the stochastic
genetic algorithm.

Underdamped
C < 2* (k*m)

(2)

C > 2* (k*m)

(3)

C = 2* (k*m)

(4)

Overdamped

Critically Damped
INTRODUCTION
A genetic algorithm is a stochastic algorithm that recreates
natural evolution. It includes the natural events such as mating,
mutation, and elitism throughout the maturing of generations.
The mating of the generations include choosing two parents
based on their fitness and creating two unique children based on
their alleles, or their own unique different variables. Mutation
causes a random children throughout to be reinitialized based
on a mutation percent. When elitism is used, the natural
selection of the best or strongest possible outcome will continue
on is put into consideration by doing so with replacing a
random parent with the best parent. With doing all of this in a
genetic algorithm, possible variables can be optimized within
many models. In a spring-mass-damper system model, given the
damping coefficient and spring constant as unknown variables
and given certain limiting factors, the damping coefficient and
spring constant can be optimized using the genetic algorithm.

THE SPRING-MASS-DAMPED SYSTEM


The system being solved is a spring system that returns
the gun slide of a gun that has been fired, putting its gun slide to
a fully open position, to its closed, firing position. The
movement of the gun slides position can be given using a
second order linear differential equation.
m* d2x/dt2+ c* dx/dt+ kx = 0

The movement for each condition of damping is given


by its own equation.
Underdamped
e-z*wn*t * (x0* cos(wd* t)+ (v0+z*wn*x0)/(wd)*sin(wd*t)) (5)
Overdamped
1/ (1-2)* ((v0- 2* x0)* e 1*t - (v0-1*x0)*e2*t)

(6)

Critically Damped
e-wn*t * (x0+ (vo+ wn* x0)* t)

(7)

Within the previous equation, the given variables are


the initial position (x0 = 1.69291 inches) and the initial velocity
(v0 = 0 inches per seconds). The variables given by separate
equations are the natural frequency (wn), damping ratio (z),
damped natural frequency (wd), and the roots of the
characteristic equation (1,2).
Natural Frequency
wn = (k/ m)

(8)

z = c/ (2* (k* m))

(9)

Damped Natural Frequency


wd = wn* (1- z2)

(10)

Roots of the Characteristic Equation


1,2 = -z* wn wn* (z2- 1)

(11)

Damping Ratio

(1)

The mass of the slide was given as 1.6 oz and x(t) will
give you the position of the slide dependent on time. The main
differences in the movement of any mass given this equation is
based on the damping ratio. Depending on the damping
coefficient and its relations to the spring constant and the mass,
the system can become underdamped, overdamped, and
critically damped.

The optimization of these equations wanted is for the gun


slide to return to the closed position after 0.15 seconds from an
optimized damping coefficient and spring constant.

Copyright 2015 by Caleb Shunatona

GENETIC ALGORITHM
The genetic algorithm is a great way to optimize an
objective function using the natural development of working
towards the best outcome of a model. The fitness of each
generation will be equated and this will tell how close to our
optimized variables we are. This algorithm is created using 100
different parents with two different alleles, the damping
coefficient (c) and the spring constant (k). The first thing
created were the bounds of the alleles. The bounds used for the
damping coefficient were a 0 minimum to the maximum
damping coefficient to stay underdamped. This is done because
in this case the bouncing of the spring caused by underdamping
is ignored because the gun slide is going to hit the rest of the
gun, stopping it when it reaches its initial firing position. The
bounds used for the spring constant were a 0 minimum to the
maximum spring constant that will not exceed an 11lb force to
cock the gun to this fired position. This is found using the force,
position, and spring constant relation.
F = k* x

the algorithm it produced these average and best fitness


outcomes for each iteration.

Graph 1. AVERAGE AND BEST FITNESS AT EACH


GENERATION

(12)

The first child generation created was done so with a


random initialization. This was done using a time seeded
randomizer to find a number between the minimum and
maximum bounds to input for each allele. The fitness of the first
generation is found before the algorithm starts. When the
algorithm starts the child generation matures and becomes the
parent generation. The fitness of each new generation is
evaluated to be used later. The best fitness created with each
new generation will be found and stored before mating to be
used in the elitism aspect of a genetic algorithm. When the
mating occurs, two different parents are chosen from an
algorithm that chooses two parents based on how low their
fitness evaluation is. These two parents while produce two
children in which a random number of alleles is given from
either parent to the children. After mating, some random
mutations will occur within the generation to reproduce the
unpredictable changes created within generations in nature. This
is created by choosing a preconceived mutation percentage,
usually between 2 and 5 percent. Then that many children will
try to be selected using a random number generator and be
reinitialized with new random alleles. The last thing to create
the genetic algorithm is to take elitism into consideration. By
taking the alleles with the best (lowest) fitness found from the
earlier generation saved in the algorithm from before mating, it
can be taken and continued on in the new generation. The
algorithm will take this best fitness and replace the worst fitness
with it. The best fitness will usually live on in nature and this
recreates that phenomenon.

With this run through the combination of c and k that


minimized the objective function as shown was 0.001 lb*s/in
for the damping coefficient and 0.150 lb/in for the spring
constant.
ACKNOWLEDGMENTS
I would like to thank the instructors Richard McCulloch
and Aaron Schmidt for all their help.

ALGORITHM OUTCOMES
After the genetic algorithm is used to optimize the
spring-mass-damped system, the outcomes will vary slightly
every time it is done. This genetic algorithm will run through
100 iterations with a population of 100 people. After running

Copyright 2015 by Caleb Shunatona

APPENDIX

#include<iostream> // cout, cin


#include<cmath> // fabs
#include<iomanip> // setprecision, fixed
#include<stdlib.h> // srand, rand
#include<time.h> // time
#include<stdio.h> // getchar, remove
#include<fstream> // file io
using namespace std;
// OBJECTIVE FUNCTION
// FOR PARENT INPUT
double fp(double parent[]){
double m, c, k, t, wn, wd, z, xo, vo, L1, L2;
m=0.045392;
// mass in kg
t=0.15;
// time in sec
xo=1.69291;
// initial position in in.
vo=0.;
// initial velocity in in/sec
c=parent[0];
// damping coefficient in lb-s/in
k=parent[1];
// spring constant in lb/in
wn=sqrt(k/m);
// natural frequency
z=c/(2.*sqrt(k*m));
// damping ratio
wd=wn*sqrt(1.-(z*z));
// damped natural frequency
L1=(-z*wn)+(wn*sqrt((z*z)-1.));
// roots of the
characteristic equation
L2=(-z*wn)-(wn*sqrt((z*z)-1.));
// roots of the
characteristic equation
if(fabs(z-1.0) < 1E-5)
return exp(-wn*t)*(xo+(vo+wn*xo)*t);
else if(z < 1.0)
return
exp(z*wn*t)*(xo*cos(wd*t)+(vo+z*wn*xo)/(wd)*sin(wd*t));
else
return
1.0/(L1-L2)*((vo-L2*xo)*exp(L1*t)-(voL1*xo)*exp(L2*t));
}
//FOR CHILD INPUT
double fc(double child[]){
double m, c, k, t, wn, wd, z, xo, vo, L1, L2;
m=0.045392;
// mass in kg
t=0.15;
// time in sec
xo=1.69291;
// initial position in in.
vo=0.;
// initial velocity in in/sec
c=child[0];
// damping coefficient in lb-s/in
k=child[1];
// spring constant in lb/in
wn=sqrt(k/m);
// natural frequency
z=c/(2.*sqrt(k*m));
// damping ratio
wd=wn*sqrt(1.-(z*z));
// damped natural frequency
L1=(-z*wn)+(wn*sqrt((z*z)-1.));
// roots of the
characteristic equation

L2=(-z*wn)-(wn*sqrt((z*z)-1.));
characteristic equation

// roots of the

if(fabs(z-1.0) < 1E-5)


return exp(-wn*t)*(xo+(vo+wn*xo)*t);
else if(z < 1.0)
return
exp(z*wn*t)*(xo*cos(wd*t)+(vo+z*wn*xo)/(wd)*sin(wd*t));
else
return
1.0/(L1-L2)*((vo-L2*xo)*exp(L1*t)-(voL1*xo)*exp(L2*t));
}
// RETURNS THE MEAN OF A 1D MATRIX
double mean(double fitness[], int N){
double sum=0.0;
for (int j=0; j<N ;j++){
sum = fitness[j]+sum;
}
return sum/N;
}
// RANDOM NUMBER 0 TO 1
double frand(){
return (double)rand()/(RAND_MAX);
}
// RETURNS A RANDOM ELEMENT rho=[0,N-1]
BASED ON FITNESS
int roulette_wheel(double fitness[], int N){
double f_sum=0.0, r,F;
int k=0;
// FIND THE CANDIDATE WITH THE MINIMUM
FITNESS
for (int j=0;j<N;j++){
f_sum=fitness[j];
}
r= frand()*f_sum;
F=1.0/fitness[k];
while (F<r){
k++;
F=F+1.0/fitness[k];
}
return k;
}
// RETURNS OPTIMUM FITNESS
double goal(double fitness[], int N){
double temp;

Copyright 2015 by Caleb Shunatona

temp=fitness [0];

L[1]=0.; U[1]=kmax;
for variable 2 (k)

//FIND THE MINIMUM FITNESS


for (int j=0;j<N;j++){
if (fitness[j]<temp){
temp=fitness[j];
}
}
return temp;

// Set the display to 3 significant figures


cout << setprecision(3) << fixed;
// Randomly initialize the first child generation
for (int j=0;j<N;j++){
child[j][0]=frand()*cmax;
child[j][1]=frand()*kmax;
}

}
int main(){
int
Na=2,
N=100,
P1,
max_iteration=100;
double rho=0.05, temp;
ofstream output("output.dat");

P2,

// Lower and upper bounds

a,

count=0,

// Seed the random number generator based on the


current time
srand(time(NULL));
// Allocate memory for the children generation
double **child;
child = new double *[N];
for(int j=0; j<N; j++)
child[j] = new double [Na];

// Determine population fitnesses


for(int j=0; j<N;j++){
fitness[j]=fc(child[j]);
}
// Output best and average fitness values
cout << goal(fitness, N) << " " << mean(fitness, N) <<
endl;
output << goal(fitness, N) << " " << mean(fitness, N)
<< endl;
// Optimize the fitness using the objective function
for (int i=0; i<max_iteration; i++)
{
// Increment generations
for (int j=0;j<N;j++){
parent[j][0]=child[j][0];
parent[j][1]=child[j][1];
}

// Allocate memory for the parent generation


double **parent;
parent = new double *[N];
for(int j=0; j<N; j++)
parent[j] = new double [Na];

// Evaluate parent fitnesses


for (int j=0;j<N;j++){
fitness[j]=fp(parent[j]);
}

// Allocate memory for the lower and upper bounds


double *U;
U = new double [Na];
double *L;
L = new double [Na];

// Elitism part a: store the best solution


temp=goal(fitness,N);
for (int j=0;j<N;j++){
if (temp==fitness[j]){
temp_best[0]=parent[j][0];
temp_best[1]=parent[j][1];
}
}

// Allocate memory for the elitism variable


double *temp_best;
temp_best = new double [Na];
// Allocate memory for the fitness matrix
double *fitness;
fitness = new double [N];

// Mate parents
for(int k=0; k<N; k+=2){

// Define the allele bounds


double kmax=1.69291/11.; // kmax= bounds to 11
pound restriction
double cmax=(2.*sqrt(kmax*0.045392));
// cmax
bounds dampening ratio from 0 to 1
L[0]=0.; U[0]=cmax;
// Lower and upper bounds
for variable 1 (c)

// Select parents
P1=roulette_wheel(fitness,N);
P2=roulette_wheel(fitness,N);
while(P1==P2){
P2=roulette_wheel(fitness,N);

Copyright 2015 by Caleb Shunatona

// Copy parents directly to children k and k+1


child[k][0]=parent[P1][0];
child[k][1]=parent[P2][1];
child[k+1][0]=parent[P2][0];
child[k+1][1]=parent[P1][1];
}
// Mutate random children
for(int j=0;j<N;j++){
if (frand() <= rho){
child[j][0]=frand()*cmax;
child[j][1]=frand()*kmax;
}
}
for(int j=0;j<N;j++){
fitness[j] = fc(child[j]);
}
// Elitism part b: replace the worst with the stored best
temp=goal(fitness,N);
int ti=0;
if (fitness[ti]==temp){
ti++;
}
child[ti][0]=temp_best[0];
child[ti][1]=temp_best[1];

// Output best and average fitness values


cout << goal(fitness, N) << " " << mean(fitness, N)
<< endl;
output << goal(fitness, N) << " " << mean(fitness, N)
<< endl;
// OUTPUT THE OPTIMIZED K AND C
//cout << child[ti][0] << " " << child[ti][1] <<
endl;
}
// Close the output file
output.close();
return 0;
}

Copyright 2015 by Caleb Shunatona

Copyright 2015 by Caleb Shunatona

You might also like