# Thread: Reliability With Random numbers.

1. ## Reliability With Random numbers.

Write a program to test the circuit reliability with random numbers as many times as the user requests.
The circuit: I can't figure out how to get the attachment to work so here's my best at describing the circuit in words. A(reliability .80) is parallel with B(r=.75). AB is in series with D(r=.90). C(r=.90) is in series with E(r=.70). CE is in parallel with ABD.

I have this so far:
Code:
```#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//prototypes (function announcement)

//function main
int main ()
{
// declarations and initialzations
float rblty=0;
int  request;
float success=0,i=0;
srand(time(NULL));

//prompts and scans
printf("\nHow many times? ");
scanf("%d", &request);

//calculation
for(i;i<=request;i++);
{
if ((rand()%101)<=69)//component E

{success+=1;}
if ((rand()%101)<74) //component B

{success+=1;}

if ((rand()%101)<=79)//component A

{success+=1;}

if ((rand()%101)<=89)//component D

{success+=1;}
if ((rand()%101)<=89)//component C

{success+=1;}
rblty= (success)/i;

}

printf("Reliability: %f%% ", rblty *100);
return 0;
}```
I think the random numbers are working, but I can't figure out how to connect the reliability for the components to one another to find the total number of successes and I'm calculating the total reliability based on reliability=number of successes/number of trials. Any help would be greatly appreciated.

2. Code:
```\$ gcc -W -Wall foo.c
foo.c: In function ‘main’:
foo.c:23: warning: statement with no effect```
The statement with no effect being the last ; on this line.
for(i;i<=request;i++);

3. I'm not sure what you system reliability equation is, but generally ALL the devices have to work, to have the system as a whole work, right?

So...

success should be a boolean or an int (1=success, 0=failure), instead of a float. Do you see why?

for(;i<result is what you want, with no = sign. C programmers count 0, 1, 2, 3, ... < Number Requested. Since we start with zero, instead of 1.

Same with rand(). A range of 0 to 100 is a range of 101. You want a range of 100, so
Code:
`rand() % 100 + 1`
will give you 1 - 100.

success might be set to 1 at the start of the for loop (assume a positive result), and then switched to 0 if ANY of the devices should fail

Code:
```if(((rand() % 100 + 1) <= 69) && (success == 1))
;
else
success = 0;```
then have a total_success variable to keep a tally of how many successes you get, in total: success should be either 1 or 0, so:

Code:
`total_success += success;`
Note that since you aren't using every possible combination of bits, the rand() function will be slightly skewed.

4. Thank you. Here is my updated code:

Code:
```//preprocessor
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//prototypes (function announcement)

//function main
int main ()
{
// declarations and initialzations
float rblty=0;
int  request=0;
float success=0,i=0;
srand(time(NULL));
float total_success=0;

//prompts and scans
printf("\nHow many times? ");
scanf("%d", &request);

//calculation
for(i;i<request;i++)
{success=1;
if (((rand()%100+1)<=69)&&(success==1))//component E
;
else
{success=0;}

if (((rand()%100+1)<=74)&&(success==1)) //component B
;
else
{success=0;}
if (((rand()%100+1)<=79)&&(success==1))//component A
;
else
{success=0;}
if (((rand()%100+1)<=89)&&(success==1))//component D
;
else
{success=0;}
if (((rand()%100+1)<=89)&&(success==1))//component C
;
else
{success=0;}

total_success += success;

}

printf("\ntotal successes: %f", total_success);
printf("\ntimes: %f", i);
rblty=total_success/i;
printf("\nReliability: %f%% \n", rblty *100);

return 0;
}```
It seems to be working better, but I don't think I'm quite there yet. I have attached a picture of the circuit. Does the order I have my if statements in make sense? I think that's where my problem is. Does it not matter if it's in parallel or series because it has to go through it if it's a success? And I had some variables declared as floats so I could divide them and not get an integer back.

5. Looking at your current code, I suggest a simplification:
Code:
```#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//prototypes (function announcement)

//function main
int main()
{
// declarations and initialzations
float reliability = 0.0f;
int num_iterations = 0;
int total_success = 0;
int i = 0;
srand(time(NULL));

//prompts and scans
printf("\nHow many times? ");
scanf("%d", &num_iterations);
if (num_iterations < 1)
{
num_iterations = 1;
}

//calculation
for (i = 0; i < num_iterations; i++)
{
if (((rand() % 100 + 1) <= 69)     //component E
&& ((rand() % 100 + 1) <= 74)  //component B
&& ((rand() % 100 + 1) <= 79)  //component A
&& ((rand() % 100 + 1) <= 89)  //component D
&& ((rand() % 100 + 1) <= 89)) //component C
{
++total_success;
}
}
reliability = (float)total_success / num_iterations;

printf("\ntotal successes: %d", total_success);
printf("\ntimes: %d", num_iterations);
printf("\nReliability: %f%% \n", reliability * 100);

return 0;
}```
You do not need the counts to be floats, hence I made them ints.

6. So as long as the random number is less than all of the values given, it's a success regardless of whether or not it's in series or parallel? I'm getting around 30% reliability. When I calculated it by hand(parallel: 1-((1-r1)*(1-r2)), series: r1*r2), I got about 94% why is it so different when using the random numbers? Should it be closer, or is the 30% correct?

7. Originally Posted by JSM
So as long as the random number is less than all of the values given, it's a success regardless of whether or not it's in series or parallel? I'm getting around 30% reliability. When I calculated it by hand(parallel: 1-((1-r1)*(1-r2)), series: r1*r2), I got about 94% why is it so different when using the random numbers? Should it be closer, or is the 30% correct?
I believe you've got two definitions of "success". If one of the parallel devices fails, will the excess current to the other devices, cause them to fail also? Or will the device continue successfully working, as long as any one of the parallel devices in the series device as a unit, is working?

It sounds like the lower success percentage is calculated as if all the devices were strung in series, which the higher percentage is calculated with several parallel devices, capable of working successfully, even if only one of the parallel devices is working.

The program's logic won't be the same, of course.

8. The higher one was calculated with taking into account which components were in parallel and which were in series. In the program I'm writing now, they're all just together...I don't understand how to account for which ones are in parallel and which ones are in series.

9. Your answer that you calculated by hand is correct. The problem is your original implementation doesn't actually take into account the parallel and series components. You just check for any one of the items to fail and then count the whole thing as a failure.

You need to implement your hand calculations in your program. I don't know what your teacher is after and which of these you should do, but you can either
1. Calculate the reliability of each parallel/series section by hand, then begin to combine pieces (e.g. AB = ???, CE = ???, ABD= ???, ABDCE = ???).
2. Simplify your reliability equation. You will effectively end up with one box that has a reliability close to what you calculated by hand. Then, you only need to pick one random number for each try.

Also, you can use drand48 to get random (double precision) floating points. You will need this as the reliability values you will be using, once you start to combine parallel and series components, will have more than 2 decimal places, and rand() % 100 wont work so well.

10. Hmm...I just read the man page on drand48 and it said those functions were deprecated in favor of rand. Still, floating point numbers would be ideal for his case. Anybody have thoughts on something like the following (generates a random number between 0 and 1):
Code:
`double d = rand() / ((double) RAND_MAX);`

11. Does this code make sense now as far as the logic goes?

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//prototypes (function announcement)

//function main
int main ()
{
// declarations and initialzations
float rblty=0;
int  request=0;
float success=0,i=0;
srand(time(NULL));
float total_success=0;

//prompts and scans
printf("\nHow many times? ");
scanf("%d", &request);

//calculation
for(i;i<request;i++)
{
if (((rand()%100+1)<=79)||((rand()%100+1)<=74))//component A or B

{
if (((rand()%100+1)<=89) )//component D
success=1; //if it makes it through A or B and then through D, it's successful
else
success=0;
}
if (((rand()%100+1)<=89))//component C

{
if (((rand()%100+1)<=69))//component E
success=1;//if it makes it through C and E, it will be successful
else
success=0;

}
total_success += success;

}

printf("\ntotal successes: %f", total_success);
printf("\ntimes: %f", i);
rblty=total_success/i;
printf("\nReliability: %f%% \n", rblty *100);

return 0;
}```

12. That looks much better. I haven't run it and checked the numbers it gives, however.

13. Nope. I'm guessing you didn't really test it since we know the answer is ~94%, but you're program gives answers ~70%. There are two errors with your current implementation. First, success is not necessarily getting a new value every time through the loop. You should initialize it to zero at the top of the for loop and make sure every possible path through your system is covered. Second, success can be true after the A||B && D block, meaning your system succeeded, but then get reset to zero in the C && E block, skewing your results. This has to do with you implementing the two parallel paths in completely separate if statements.

It would probably help if you broke your code down a bit.

As a matter of good design, any time you find yourself repeating the same section of code, you should put it in a function. Thus, create a function called, for example, test and put your rand()... check inside it. You can define reliability values for A = .75, etc. and call something like test(A) a to determine if component A was successful.

Then you can define a test_system function that tests the overall system for success. It would return something along the lines of
Code:
`test(A) || test(B)...`
using appropriate || and && for parallel and series components and () for grouping.

14. Ok, so I am supposed to be getting something closer to 94? I was getting around 80%...I'm not sure how close it's supposed to be to 94.

First, success is not necessarily getting a new value every time through the loop. Make sure every possible path through your system is covered. Second, success can be true after the A||B && D block, meaning your system succeeded, but then get reset to zero in the C && E block, skewing your results. This has to do with you implementing the two parallel paths in completely separate if statements.
I added other paths, the reliability is better, but do I have them all now?
Code:
```#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//prototypes (function announcement)

//function main
int main ()
{
// declarations and initialzations
float rblty=0;
int  request=0;
float success=0,i=0;
srand(time(NULL));
float total_success=0;

//prompts and scans
printf("\nHow many times? ");
scanf("%d", &request);

//calculation
for(i;i<request;i++)
{success=0;
if (((rand()%100+1)<=79)||((rand()%100+1)<=74))//component A or B

{
if (((rand()%100+1)<=89) )//component D
success=1; //if it makes it through A or B and then through D, it's successful
else
success=0;
}
else  if (((rand()%100+1)<=89))//component C

{
if (((rand()%100+1)<=69))//component E
success=1;//if it makes it through C and E, it will be successful
else
success=0;

}
else if ((((rand()%100+1)<=79)&&((rand()%100+1)<=89) )&&(((rand()%100+1)<=89)&&((rand()%100+1)<=69)))//(A&&D)&&(C&&E)
{
success=1;
}
else if ((((rand()%100+1)<=74)&&((rand()%100+1)<=89) )&&(((rand()%100+1)<=89)&&((rand()%100+1)<=69)))//(B&&D)&&(C&&E)
{
success=1;
}
total_success += success;

}

printf("\ntotal successes: %f", total_success);
printf("\ntimes: %f", i);
rblty=total_success/i;
printf("\nReliability: %f%% \n", rblty *100);

return 0;
}```
It is getting a bit messy, I'll try using a function.

15. No, you still don't have it right. If you ran your program, you should've realized that. When you do run it, use a large number of iterations, like a million. Answering 5 for how many times is not going to cause your program to converge on the correct answer. On any modern-ish computer, 1 million iterations shouldn't take more than a few seconds, and should get you within a fraction of a percent (my version of the program gave me an error of about .15%.

Where did (A&&D)&&(C&&E) and (B&&D)&&(C&&E) come from? The parentheses in those cases happen to be useless since all the operators are &&. More to the point, however, the if...else if blocks still don't properly cover all your paths in the circuit from what I can tell.

I am going to mandate that you use functions for this, if you still want my help. All those rand statements with the % and the +1 and the <= inside a single if clause are very difficult for me to parse, and it makes it much less likely that I will catch a logical error.

Lastly, think about the correlation between your logical operators (&& and ||) and series/parallel components. Is && parallel or series components? What about ||?