Term Project
Genetic Algorithm in Engineering
Process Modelling
MEMBERS
- Arka Mitra (16ME10077)
- Abhijeet Bagade (16MF10008)
- Atharva Pusalkar (16MF10006)
- Sudhanshu Parashar (16ME30043)
- Ranjeet Kumar Shah (16ME10048)
Finding Resonance Frequency OF Forced Damped Oscillator using GA
Problem Statement:
We consider the motion of an oscillator under the influence of an external
Sinusoidal force F = cos(ωt+ᴪ). This is because an arbitrary time varying force F (t) can
always be decomposed into the sum of sinusoidal forces of different frequencies.
Introducing damping, the equation of motion becomes,
Which can be written as,
The particular integral is important when studying the long time or steady state response of
the oscillator. This solution is
This may be written as,
Where φ is the phase of the oscillation, relative to the force.
This has amplitude,
And the phase φ is,
Figure shows the amplitude and phase for different values of the damping coefficient β. The
damping ensures that the amplitude is finite for all values of ω. Also the change in the phase
is more gradual.
The low frequency and high frequency behaviour are exactly the same as the undamped
situation. The changes due to damping are mainly in the vicinity of ω = ω0. The amplitude is
maximum at,
For mild damping (β << ω0) this is approximately ω = ω0.
Sample Calculations to show how GA is implemented here
Here we perform iterations (only one) on initial values of ω, to show how GA works to improve the
overall fitness of the population.
1st Generation:
ω DV Fi Fi/Favg AC Mating pool
10011011 1.55 0.65 0.72 0 00110111
00110111 0.55 1.37 1.52 2 00110111
00010000 0.16 1.02 1.13 1 00010000
11100011 2.27 0.24 0.26 0 01111100
01111100 1.24 1.37 1.52 2 01111100
10010011 1.47 0.77 0.86 1 10010011
Favg = 0.90
2nd Generation:
Mating pool CS ωn DV Fi
00110111 3 00110000 0.48 1.26
00010000 3 00010111 0.23 1.05
00110111 5 00110100 0.52 1.32
01111100 5 01111111 1.27 1.26
01111100 4 00110011 0.51 1.30
10010011 4 10011100 1.56 0.64
Favg = 1.14
DV = Decoded Value
Fi = Fitness of individual string in the population
Favg = Average Fitness Value of the population
AC = Actual Count of the String
CS = Crossing Site
• We note that the least fit members get 0 copies in the mating pool. Selection here
has been done on the basis of Proportionate Selection Method.
• It is observed that in the 2nd generation, the Favg value increases to 1.14 from 0.90 in
the 1st generation. Hence, with each succeeding generation, the Favg value
increases, moving closer to the peak value of amplitude, at which all ω values
converge around the resonant value of ω.
• The maximum fitness value in each generation is highlighted by the blue colour. It is
noticed that the maximum fitness value reduces as we move to the 2nd generation.
This observation is not constant with each generation or each set of population
members selected. Only the Favg value is found to increase with every generation.
• We use a mutation constant (Pm) of 2% (i.e. 1/50). Mutation is performed and shown
in the 2nd table, highlighted by the pink colour. Here, of the available 48 bits, we
randomly choose 1 bit to mutate.
• Cross-over constant (Pc) is taken almost equal to 1 i.e. each pair of members selected
undergo cross-over almost definitely. The crossing sites are selected randomly, as
shown in the 2nd generation table (3,4 and 5 are taken as the random crossing sites).
• The decoded value (DV) is the actual integer value of the binary string representing
the member. The decoding algorithm has been included in the GA code on the
following pages.
THE CODE (IMPLEMENTED IN C)
#include<stdio.h>
#include<conio.h> //to use the getche function
#include<stdlib.h> //to use the rand function
#include<math.h>
typedef struct Chrom // creating the chrom structure
{short int bit[8];
int fit;
}
chrom; // now we have a chrom type that we can use
void *evpop(chrom popcurrent[6]); //defining the functions that we will use
float x(chrom popcurrent);
float y(float x);
void *selection(chrom popcurrent[6]);
void *crossover(chrom popnext[6]);
void *mutation(chrom popnext[6]);
void main() // the main function
{
int num; // num is the no. of
iterations
int i,j;
printf("\nWelcome to our first Genetic Algorithm. \nThe Algorithm’s function is to find the
maximum amplitude and the corresponding resonance frequency for a forced damped oscillator.
y = 1/√(1-x^2)^2+4x^2 is the amplitude function that we ty to maximise using GA here...\n");
// introduction to the program
enter: printf("\nPlease enter the no. of iterations: ");
scanf("%d",&num); // enter the no. of iterations in num
chrom popcurrent[6]; // we make 4 members of popcurrent
chrom popnext[6]; // we make 4 members of popnext
if(num<1) // if a -ve number is inserted .. enter num again
goto enter;
evpop(popcurrent); //initialise pop current
for(i=0;i<num;i++) // loop num times
{
printf("\ni = %d\n",i); // print the iteration number
for(j=0;j<6;j++)
popnext[j]=popcurrent[j]; //copy popcurrent to popnext in order to adjust it
selection(popnext); //select best members
crossover(popnext); //cross over to get children members
mutation(popnext); //mutate with a low probability
for(j=0;j<6;j++)
popcurrent[j]=popnext[j]; //copy the members of popnext to popcurrent
} // loop back until no. of iterations is exceeded
printf("\nPress any key to end ! ");
flushall(); // flush the input buffer
getche(); // wait for a character from the keyboard to end
} //end of main
void *evpop(chrom popcurrent[6]) //takes a pointer to a chrom of 6 elements
{
int i,j,value;
int random;
for(j=0;j<6;j++) // loop of j to choose members from [0] to [5]
{
for(i=0;i<8;i++) // loop of i to choose the gen of the chrom from [0] to [7]
{
random=rand(); // creating random value
random=(random%2); // make the random value 0 or 1 only
popcurrent[j].bit[i]=random; // initialising the bit[i] of chrom[j] with random
} // end of for(i)
value=x(popcurrent[j]); // get the value of the chrom as integer
popcurrent[j].fit=y(x(popcurrent[j])); // calcualte the fitness of chrom[j]
printf("\n popcurrent[%d]=%d%d%d%d%d%d%d%d value=%d fitness = %d", j,
popcurrent[j].bit[7], popcurrent[j].bit[6], popcurrent[j].bit[5], popcurrent[j].bit[4],
popcurrent[j].bit[3], popcurrent[j].bit[2], popcurrent[j].bit[1], popcurrent[j].bit[0], value,
popcurrent[j].fit); // print the chrom[j]
} // end of for(j)
return(0);
} //end of evpop function
float x(chrom popcurrent) //x function that evaluate the value of a given chrom
{
float z;
z=(popcurrent.bit[0]*1)+(popcurrent.bit[1]*2)+(popcurrent.bit[2]*4)+(popcurrent.bit[3]*8)+(popcur
rent.bit[4]*16)+(popcurrent.bit[5]*32)+(popcurrent.bit[6]*64)+(popcurrent.bit[7]*128);
return(z/100); //return the value of z/100, to account for precision decimal places
} // end x function
float y(float x) // the y function that we look for it's maximum value takes x value
{
float y;
y=1/sqrt((1-x*x)*(1-x*x)+4*x*x); // the function is y= 1/√(1-x^2)^2+4x^2)
return(y);
} // end of y function
void *selection(chrom popcurrent[6]) // selection takes a pointer to array of chroms
{
int i,j;
chrom temp; //temp member to use in sorting
for(i=0;i<5;i++) //sorting the given set due to fitness
for(j=0;j<5;j++)
{
if(popcurrent[j+1].fit>popcurrent[j].fit)
{
temp=popcurrent[j+1];
popcurrent[j+1]=popcurrent[j];
popcurrent[j]=temp;
} // end of if
} // end of for loop
for(i=0;i<6;i++)
printf("\nSorting:popnext[%d] fitness=%d",i,popcurrent[i].fit); //printing the result
printf("\n"); //print new line
flushall(); //flush the input buffer
return(0);
} //end of pick members
function
void *crossover(chrom popnext[6]) // crossover function takes a pointer to array of members
{
int random;
int i;
random=rand(); //random cross over point
random=((random%7)+1); // cross point should be between (1 - 7)
for(i=0;i<random;i++) //crossing the bits below the cross point index
{
popnext[2].bit[i]=popnext[0].bit[i]; //child 1 cross over
popnext[3].bit[i]=popnext[1].bit[i]; // child 2 cross over
} // end of for
for(i=random;i<8;i++) // crossing the bits beyond the cross point index
{
popnext[2].bit[i]=popnext[1].bit[i]; // child 1 cross over
popnext[3].bit[i]=popnext[0].bit[i]; // chlid 2 cross over
} // end of for
for(i=0;i<6;i++)
popnext[i].fit=y(x(popnext[i])); // calculating the fitness values for the new set
for(i=0;i<6;i++)
printf("\nCrossOver popnext[%d]=%d%d%d%d%d%d%d%d value=%d fitness = %d", i,
popnext[i].bit[7], popnext[i].bit[6], popnext[i].bit[5], popnext[i].bit[4], popnext[i].bit[3],
popnext[i].bit[2], popnext[i].bit[1], popnext[i].bit[0], x(popnext[i]), popnext[i].fit);
// printing the bits, value and fitness for the members of the new set
return(0);
} // end crossover function
void *mutation(chrom popnext[6]) // mutation funtion given a pointer to array of members
{
int random;
int row,col,value;
random=rand()%50; //random value is between ( 0 - 49 )
if (random==25) // Supposing Probability of mutation is 2 %
{
col=rand()%8; // random column (gene) choosing
row=rand()%6; // random row ( member ) choosing
if (popnext[row].bit[col]==0) // invert the bit to 1 if it was 0
popnext[row].bit[col]=1 ;
else if (popnext[row].bit[col]==1) // invert the bit to 0 if it was 1
popnext[row].bit[col]=0;
popnext[row].fit=y(x(popnext[row])); // calculate the fitness for the mutated member
value=x(popnext[row]);
printf("\nMutation occured in popnext[%d] bit[%d]:=%d%d%d%d%d%d%d%d value=%d
fitness=%d", row, col, popnext[row].bit[7], popnext[row].bit[6], popnext[row].bit[5],
popnext[row].bit[4], popnext[row].bit[3], popnext[row].bit[2], popnext[row].bit[1],
popnext[row].bit[0], value, popnext[row].fit);
// print the member index,bits,value, fintness of the mutated member
} // end of if
return(0);
} //end of mutation
REFERENCES
1. Programming in C – By Dennis Ritchie
2. Let us C – E. Balaguruswamy
3. Waves and Oscillations – Prof. Somnath Bharadwaj
4. Multi-Objective Optimization and Evolutionary Algorithms – Prof. Kalyanmoy Deb
5. The Internet