# Mutation Operator

• 07-10-2006
Cdrwolfe
Mutation Operator
Hi all.

Trying to move on and create a simple Mutation operator for the string that was created and then edited in the first two functions.

Basically a for loop which checks each element in the array Output.

Then comes my attempt at random numbers.

RandMax was defined as 100 so it is like 100%.

Basically starts off with i think, initializing variable Mut1 to random number.

If Mut1 > 80
{
//Then mutate but now choose what to mutate to.

If Mut2 > 50
{
then Output[index] = 1
}
else
{
Output[index] = 0
}

as you can prb see better in the code i wanted it to check each element then produce a random number to see if it would get changed, the problem is this needs to be done for each loop, each time it loops the variable Mut1 and Mut2 need to be random/ differant then last time so to speak.

Reinitialised with new numbers.

This is where i think i'am going wrong and was wondering if anyone knew a better way of getting it to work.

Code:

```#include <iostream> #include <stdio.h> #include <string> #define RAND_MAX 100 using namespace std; using std::string; using std::cout; using std::endl; using std::cin; void GetUserInput(string &Input) {     cout << "Please enter Amino Acid Sequence \"H,P\": " << endl;     cin >> Input;         cin.get(); } void GetSetupString(string theInput, int (&Output)[50]) // To declare an Array as a reference from Main, syntax is differant then other // references, ie: Type (&ArryName)[Size], try finding that in any tutorial :) {   int index;     for (index = 0; index < theInput.length(); ++index)   {       switch (theInput[index])       {           case 'H':               Output[index] = 1;               break;           case 'P':               Output[index] = 0;               break;           default:               break;           }          cout << Output[index] ;   }  cin.get(); }    int GetMutation (int (&Output)[50]) {         int index;         for ( index = 0; index < 49; ++index)     {         int Mut1;         Mut1 = rand();         int Mut2;         Mut2 = rand();                 if (Mut1 > 80)                 {                                     if ( Mut2 > 50)             {                 Output[index] = 0;             }             else             {                 Output[index] = 1;             }         }         else         {             //do nothing         }                 cout << Output[index] ;     }                        cin.get();       }     int main () {     string Input;     int Output[50];     GetUserInput(Input);     GetSetupString(Input, Output);     GetMutation(Output); }```
Thank you for any help.
• 07-10-2006
anon
The rand() function doesn't work like that.
You may define the MAX value and then use the modulus operator: z = rand() % MAX

By the way, aren't you making this complicated for yourself? Why do you convert the string to an array of ints? You could just modify the letters in the string?
• 07-10-2006
Cdrwolfe
Quote:

Originally Posted by anon
The rand() function doesn't work like that.
You may define the MAX value and then use the modulus operator: z = rand() % MAX

By the way, aren't you making this complicated for yourself? Why do you convert the string to an array of ints? You could just modify the letters in the string?

It was made into an array as a way to test my referencing and try other stuff (Switch/Case)

I don't quite think rand() % MAX works :)

I'll scan through search again and see what comes up with random.

Thanks any way.

Works now ish, if only i could tell it to stop reading the rest of the array :)
• 07-10-2006
anon
I can't believe your rand() thing works - I tested it, and it doesn't.

Firstly, it will give a compiler error "redefinition of RAND_MAX". So I could only compile your code by adding #undef RAND_MAX first.

However, if you had checked the random numbers, you would have seen that they are still not from 1 to 100. It seems that redefining RAND_MAX doesn't affect how the random number generator works. It just takes away the oportunity to see what's the highest possible value.

Secondly, what you are doing with the arrays in the functions is really weird. Normally you would pass the pointer to the first member of the array and an int telling how many elements there are. Then you would access individual elements in the function using pointer arithmetic.

To solve your problem with printing all 50 numbers, if the string is shorter: consider using a dynamically allocated array that has the needed size (Input.size()).

I made some changes to your code to get it to work properly. Some of it is here:

Code:

```#include <iostream> //#include <stdio.h>  //not really needed #include <string> #include <ctime> //#undef RAND_MAX      //not a good idea //#define RAND_MAX 100 //using namespace std;  //not needed using std::string;            //if you are doing it this way using std::cout; using std::endl; using std::cin; const int MAX = 100;      //global max random number```
And here's the modified main function:
Code:

```int main () {     srand((unsigned) time(NULL));     string Input;     GetUserInput(Input);     int size = Input.size();     int* Output = new int[size];      //allocate memory     GetSetupString(Input, Output);     GetMutation(Output, size);        //pass size of array     delete [] Output;                      //free memory }```
• 07-10-2006
Cdrwolfe
Thanks, before hand i changed RAND_MAX to = 100, and seeded rand by defining srand = 12, then changed rand() to rand() % 100 like you suggested.

It worked after that, of course i need to change the seed to give new results but one step at a time :)

Anon you missed a previous thread where i basically went through learning pointers and references on what is essentially the same code above there or abouts.

Some people suggested i used referencing, i agreed because it is easir to understand then pointers. Could be wrong it's not the first time :).

Is it really weird what i'am doing with the arrays?
All i'am doing is referencing them.

Anyway if you like weird arrays in functions have a look at my latest bodge :D

Code:

``` void GetPopulation(int (&Output)[21], int (&Pop)[PopSize][21]) {     int index;     int j;         for ( index = 0; index > PopSize; ++index)     {         for ( j = 0; j > 21; ++j)                     {                     int Out;                     Out = Output[j];                             Pop[index][j] = Pop[index][Out];                     cout << Pop[index][j];                     }                          cout << Pop[index][j];     }    }```
Popsize is defined
Aswell as int Pop[PopSize][21] which is in main

It is my attempt at an Array within an array.
What i'am trying to do is create a population of individual arrays that of which are like "Output"

It compiles but to be honest it doesn't do anything prb some rubbish mistake but i'am tired and can't concentrate at the moment.

Perhaps tomorrow everything will be clearer :)
• 07-10-2006
anon
Look at the code I posted. The standard way to seed the random number generator is using system time.

I suggested allocating memory with new, because then you can have an array that is exactly as large as needed (what if user entered more than 50 characters?)

By the way, you could use vectors instead of arrays. Here's a small program to show how easy it is:

Code:

```#include <iostream> #include <vector> using namespace std; void VectorInput(vector<int>& v) {     int n = 0;     cout << "Enter ingegers (0 to stop)" << endl;     do {         cin >> n;         if (n) v.push_back(n);     } while (n); } void OutputDouble(vector<int>& v) {     cout << "Printing doubles..." << endl;     for (int i = 0; i < v.size(); i++)         cout << v[i]*2 << " ";     cout << endl; } int main() {     vector<int> MyVector;     VectorInput(MyVector);     OutputDouble(MyVector);     cin.ignore();     cin.get();     return 0; }```
• 07-10-2006
Cdrwolfe
I'll have to read up on vectors, is it able to do the array of arrays thing i was trying to do above?

Anyway thanks for the help i shall read up on it tomorrow.

thanks

Regards Wolfe
• 07-10-2006
ruthgrin
Code:

```void GetPopulation(int (&Output)[21], int (&Pop)[PopSize][21]) {     int index;     int j;     /*     This next loop only runs while the value of index is greater    than Popsize. Since index is set to zero at the start of the      loop, the loop will only run if Popsize is less than zero, which I      doubt. I think changing the > to a < in the loop condition will     suffice.     */         for ( index = 0; index > PopSize; ++index)     {     /*     Again, loop only executes if j is greater than 21. Change > to <     to fix this.     */         for ( j = 0; j > 21; ++j)                     {                     int Out;                     Out = Output[j];                             Pop[index][j] = Pop[index][Out];                     cout << Pop[index][j];                     }                          cout << Pop[index][j];     }    }```
Incidentally, have you done any work with pointers yet? As I recall, you can't pass an actual array to a function (though it may look as if you are depending on how you declare the function parameters), rather a pointer to the start of the array is passed and you can access elements of the array through the pointer using 'array indexing', as I believe it is called. For example:

Code:

```char string[14] = "Test string\n"; /* Note that I do not assign the address of the array to ptr, but the program will still work. */ char *ptr = string; for(int i = 0; i < 14; i++) {   std::cout << ptr[i]; }```
Note that there is no bounds checking, so if the pointer is told to read (or write) a location outside the array, nothing will stop it from doing so, which will probably result in undesirable operation of your program (anything from garbage values being read to program crashes). If any of this seems unclear, say so and I'll try to explain more basically.
• 07-11-2006
Cdrwolfe
Found out about the ">" last night, knew it would be something stupid i did :D.

I'am referencing the array into the function instead of using a pointer both have the same effect i believe.

Thanks
• 07-11-2006
anon
Yes, vectors can do the same things as arrays and much more:
they know their own size (MyVector.size()) and they expand as you add more elements.

By the way, I don't think you need all the array stuff for the mutation code. Input is string, why can't output also be a string?

Here's another modification of your code. As I didn't see any reason why input should be converted to 1-s and 0-s I omitted it. (You could also convert input into a string of '1'-s and '0'-s if you want to - it's not a number after all.)

The key to the tast is the string::replace() method.

Code:

```#include <iostream> #include <ctime> #include <string> using std::string; using std::cout; using std::endl; using std::cin; const int MAX = 101; const int MUTATION_PROBABILITY = 10; void GetUserInput(string &Input) {     cout << "Please enter Amino Acid Sequence \"H,P\": " << endl;     cin >> Input;         cin.get(); }  string GetMutation (const string& Input) {     string Output = Input;     for ( int index = 0; index < Input.size(); ++index)     {         if (rand()%MAX < MUTATION_PROBABILITY)                { /*Simplified the whole thing. If random number is smaller than the probability of mutation, replace H with P and P with H.*/             switch (Input[index]) {                 case 'H':                     Output.replace(index, 1, "P");                     break;                 case 'P':                     Output.replace(index, 1, "H");                     break;             }         }     }                        return Output;  } int main () {     srand((unsigned)time(NULL));     string Input;     string Output;     GetUserInput(Input);     Output = GetMutation(Input);     cout << Output << endl;     cin.get();     return 0; }```
• 07-11-2006
Cdrwolfe
Sadly the string of "HHPPP" etc has to be converted into (1,0) for the fitness function i intend to right to work. It just makes it easier.

Also doesn't return Output only return the first element of the string?

Anyway going to post a new thread on Array of Arrays :) Hope to see you there :D

p.s i like your "mutator" i'll have to work it in.

thanks for the help

Regards Wolfe