I've been working on writing a program that randomly fills sites in a 2-D array (10x10) with 1's and 0's that meet a user input for the fraction of 1's sites compared to total sites. The code I wrote works in principle I think but when I compiled and ran it I had an unexpectedly long run time (i never got it to finish). Is there any errors in my coding or is it just inefficient?
#include <iostream>
#include <cmath>
#include <ctime>
#include <new>
usingnamespace std;
int main()
{
//declare parameters
float p; //percentage of sites filled in array
longint i, j, n, m; // i=rows j=columns; loop indexes-n,l
longint pmass; //mass of percolating chain
longint filled, unfilled; // filled=number of 1s, unfilled=number of 0s
int perc_array[10][10]; //declare 2-d 10x10 array
//set i, j to both be 10
i=10;
j=10;
// user inputs
cout<<"What percentage (decimal) of sites do you want filled? (no more than 3 decimal places) \n";
cin>>p;
//zero filled and unfilled variables
filled=0;
unfilled=0;
//zero the array elements before seeding the sites. does this by going down each column and zeroing all the rows
//after it zeroes all the rows in the first column it does it for the second..to the jth column
for(n=0; n<j; n++)
{
for(m=0;m<i;m++)
perc_array[m][n]=0;
}
//seeding random number generator
srand(time(NULL));
// fill array with 0's or 1's (1's will indicate filled sites) and have the ratio of 1's to total array size
// be the same as the user defined p
do
{
//randomly fill array with 0s and 1s
for(n=0; n<j; n++)
{
for(m=0; m<i; m++)
perc_array[m][n]=rand() % 2; //generates random 0 or 1 to fill array spot
}
//count the number of filled and unfilled sites
for(n=0; n<j; n++)
{
for(m=0; m<i; m++)
{
if(perc_array[m][n]==0)
unfilled++;
else
filled++;
}
}
} while((filled/(filled+unfilled))!=p); // recalculates the array until the (filled/total) ratio is p
//output array to check by hand (for debugging purposes)
for(n=0;n<i;n++) //does output for each row n
{
for(m=0;m<j;m++) //outputs all columns in each row n
{
cout<<perc_array[n][m];
if(m==100)
cout<<"/n"; //new row
}
}
}
Probably an infinite loop. To see where it is, you could add:
cout<<"Loop ID =1"<<endl;
inside every loop (obviously change the 1 to a unique number), to see which one is repeating.
I did what you suggested and I found out that the do-while loop is repeating ad infinitum. I made some modifications to try and make it check the while condition clearer. So the new do while loop is:
do
{
//randomly fill array with 0s and 1s
for(m=0; m<j; m++)
{
for(n=0; n<i; n++)
perc_array[m][n]=rand() % 2; //generates random 0 or 1 to fill array spot
}
//count the number of filled and unfilled sites
for(n=0; n<j; n++)
{
for(m=0; m<i; m++)
{
if(perc_array[m][n]==0)
{
unfilled++;
}
elseif(perc_array[m][n]==1)
{
filled++;
}
}
}
//simplification variables
total=100;
randp=(filled/total);
//reset filled and unfilled when random array isn't percentage filled user specified
if(randp!=p)
{
filled=0;
unfilled=0;
}
//otherwise tell user of values (randp should be same as user input)
elseif(randp==p)
cout<<filled<<","<< unfilled<<","<<total<<","<<randp;
} while(randp!=p); // recalculates the array until the (filled/total) ratio is p
So, to my understanding the loop should terminate when it builds the array with the same percentage of 1's the user specified. since the condition is true when randp is not p the do-while loop will run again. However this still runs to infinity. I tried some couts and found that it is not correctly computing randp. Inside the do-while loop it says randp is 0. Even though when I have it tell me the number for filled states it returns a non-zero number. What am I doing wrong here??
When I ran your code (same as first post with only the do-while loop replaced be the second post), it seems to work fine for me. However, the variables "total" and "randp" were not declared in your first post, and so I declared them in the same line as p (ie as other floats) because I didn't know any better. My best guess would be that you have total declared as an int or long int. In C and C++, when you divide an int by an int, you get an int, even though you're trying to store it into a float or double. This is my speculation as to why you see randp as always zero due to your division statement at line 28. My method of decalring total as a float fixed the problem because if a float is part of the division, you can get a float back, but the other way is to cast one of the int's. In other words:
1 2 3 4 5 6
float d;
int b, c;
d = b/c; //returns an int into d
d = (float) b/c; // returns a float into d
Hope that helps.
EDIT: I meant to add that you should include <cstdlib> in addition to the other headers you have. Your compiler may not require it because it adds it automatically, but you have some function calls that need it (ie rand()).