Jump to content

Loop through Three Variables but Make them Always = 1


unemployment

Recommended Posts

I need to create a loop where I can cycle through three variables and determine the maximum output.  Here is an example...

 

First loop

$var_one = .01

$var_two = .01

$var_three = .98

 

run calculation for vars

 

Second Loop

$var_one = .02

$var_two = .01

$var_three = .97

 

run calculation for vars

 

This loop would run through ALL possible values making sure that the total of all variables would always equal 1.  There could be more than three variables so this will be dynamic.  I have no idea how to make this. Any thoughts?

 

 

Link to comment
Share on other sites

There could be more than three variables

 

You would use an array. Arrays are for sets of related data that you need to process.

 

$var[1] = .01;

$var[2] = .01;

$var[3] = .98;

 

With arrays, you can use php's array functions, such as array_sum to directly calculate the sum of the array, regardless of the number of elements in it, no looping required.

 

Link to comment
Share on other sites

There could be more than three variables

 

You would use an array. Arrays are for sets of related data that you need to process.

 

$var[1] = .01;

$var[2] = .01;

$var[3] = .98;

 

With arrays, you can use php's array functions, such as array_sum to directly calculate the sum of the array, regardless of the number of elements in it, no looping required.

 

but how could I adjust all of the array values and run a calculation for every potential variation?

Link to comment
Share on other sites

Not sure if this will help at all, but...

<?php
//Assuming results are from a DB query but in this example I will make an array of variables to loop through.
$variables=array(
0=>array(.01,.01,.98),
1=>array(.02,.01,.97),
2=>array(.02,.01,.01,.01,.95),
3=>array(.02,.01,.02,.01,.02,.01,.88)
);
//print_r($variables);
echo "<br />";
$var=array();
//This whole foreach section and above arrays would be replaced by DB query. 
foreach($variables as $k => $v){
$var[$k]=$v;
}
//  Remove all above code if using DB.

//So the DB query would look like this if using same DB field.
/* 
$var=array();
$sql="SELECT `field`,`id` FROM `table` WHERE anyfilters='filter'";
$result=mysql_query($sql);
while($row=mysql_fetch_array($result)){
$k=$row['id'];
$var[$k]=$row['field'];
}
*/
// Depending on what you want to do, you could for example echo record id and total with pass or fail.
foreach($var as $id => $subtotals){
$total=array_sum($var[$id]); 
$pass=($total!=1 ? 'FAIL' : 'PASS');
echo "Record id: $id - Total: $total - $pass<br />";
}
?>

 

I suppose the DB section really is a waste as you can just use SUM(field) in the query, but you never explained where you are getting these variables from.

Link to comment
Share on other sites

Not sure if this will help at all, but...

<?php
//Assuming results are from a DB query but in this example I will make an array of variables to loop through.
$variables=array(
0=>array(.01,.01,.98),
1=>array(.02,.01,.97),
2=>array(.02,.01,.01,.01,.95),
3=>array(.02,.01,.02,.01,.02,.01,.88)
);
//print_r($variables);
echo "<br />";
$var=array();
//This whole foreach section and above arrays would be replaced by DB query. 
foreach($variables as $k => $v){
$var[$k]=$v;
}
//  Remove all above code if using DB.

//So the DB query would look like this if using same DB field.
/* 
$var=array();
$sql="SELECT `field`,`id` FROM `table` WHERE anyfilters='filter'";
$result=mysql_query($sql);
while($row=mysql_fetch_array($result)){
$k=$row['id'];
$var[$k]=$row['field'];
}
*/
// Depending on what you want to do, you could for example echo record id and total with pass or fail.
foreach($var as $id => $subtotals){
$total=array_sum($var[$id]); 
$pass=($total!=1 ? 'FAIL' : 'PASS');
echo "Record id: $id - Total: $total - $pass<br />";
}
?>

 

I suppose the DB section really is a waste as you can just use SUM(field) in the query, but you never explained where you are getting these variables from.

 

Drummin, I think you are misinterpreting the problem.  I don't know the array values.  I need to determine every possible combination of values that equal to 1.  Every item can have as little of a value of .01

Link to comment
Share on other sites

Drummin, I think you are misinterpreting the problem.  I don't know the array values.  I need to determine every possible combination of values that equal to 1.  Every item can have as little of a value of .01

 

That's a LOT of combinations. I think you'd need a recursive function maybe? *thinking*.

The maximum count is going to be 100, and the min is 1.

so...

 

$combos = array();
for($num=1; $num<=100; $num++){
$combo = array();
for($values=1; $values<=$num; $values++){
  $combo[] = 0.01;
}
  $combo[] = 1-($num*0.01);
  $combos[] = $combo;
}

 

Would get you all of the combos with only values of 0.01 and the other max value. Not sure where to go from there, math is hard. :)

Link to comment
Share on other sites

Drummin, I think you are misinterpreting the problem.  I don't know the array values.  I need to determine every possible combination of values that equal to 1.  Every item can have as little of a value of .01

 

That's a LOT of combinations. I think you'd need a recursive function maybe? *thinking*.

The maximum count is going to be 100, and the min is 1.

so...

 

$combos = array();
for($num=1; $num<=100; $num++){
$combo = array();
for($values=1; $values<=$num; $values++){
  $combo[] = 0.01;
}
  $combo[] = 1-($num*0.01);
  $combos[] = $combo;
}

 

Would get you all of the combos with only values of 0.01 and the other max value. Not sure where to go from there, math is hard. :)

 

Hi Jesirose,

 

Your function is a start, but it does not limit the number of array keys to the number of stocks I am going to pass through.  I'd like to be able to limit the amount of keys to a defined number.  So how many combinations can there be for 3 array keys?

Link to comment
Share on other sites

You lost me.

 

For instance... I'm trying to create a function that will pass through the number of stocks in your portfolio and will then determine the proper asset allocation by looping through all of the potential allocation amounts.  In my app... lets say you pick three stocks.  In order for me to calculate the mix of your portfolio I need to run a calculation showing every possible combination that your asset allocations could have.  For example... if you have three stocks... yahoo, microsoft and goolge and you are trying to find the best asset allocation you need to determine every potential allocation.  Thus, you could put 10 percent in yahoo, 60 percent in microsoft and 30 percent in google, but that might not be the best allocation.  You could also put 20 percent in yahoo, 20 percent in microsoft and 60 percent in google. 

 

The function you provided does not limit the amount of array keys created and just continues to make keys for possible combinations.  I need a function that will take an existing number of keys and loop through all possible combinations.

 

The percent always needs to equal 100% of money you have available. 

 

I want to return an array that looks like this... array=>array(1,1,98),array(1,2,97), array(1,3,96), array(1,4,95)...ect

Link to comment
Share on other sites

Well you take what I wrote and adapt it, I wasn't trying to actually write the whole thing for you, you won't learn that way.

 

PS: it wasn't a function, but you could easily make it a function. That is what you'll need to do based on your post

Link to comment
Share on other sites

for( $var_1 = .01; $var_1 <= .98; $var_1 = $var_1 + .01 ) {
  for( $var_2 = .01; $var_2 + $var_1 < 1; $var_2 = $var_2 + .01 ) {
    $var_3 = 1 - ( $var_1 + $var_2 );
    // do something with the three vars
  }
}

For loops don't always have to increment or decrement by 1.

Link to comment
Share on other sites

for( $var_1 = .01; $var_1 <= .98; $var_1 = $var_1 + .01 ) {
  for( $var_2 = .01; $var_2 + $var_1 < 1; $var_2 = $var_2 + .01 ) {
    $var_3 = 1 - ( $var_1 + $var_2 );
    // do something with the three vars
  }
}

For loops don't always have to increment or decrement by 1.

 

The problem with this is that the third var never changes and therefore this does not determine all of the possible allocations.  Thought this is probably a good start to the solution.

Link to comment
Share on other sites

for( $var_1 = .01; $var_1 <= .98; $var_1 = $var_1 + .01 ) {
  for( $var_2 = .01; $var_2 + $var_1 < 1; $var_2 = $var_2 + .01 ) {
    $var_3 = 1 - ( $var_1 + $var_2 );
    // do something with the three vars
  }
}

For loops don't always have to increment or decrement by 1.

 

The problem with this is that the third var never changes and therefore this does not determine all of the possible allocations.  Thought this is probably a good start to the solution.

Yes it does:
    $var_3 = 1 - ( $var_1 + $var_2 );

so as each of the values for the first 2 vars changes through each of the loops the value of the third will also change. 

 

Just out of curiosity, because I can never get my head around this - this will generate 1million combinations using just the 3 vars, right?

Link to comment
Share on other sites

for( $var_1 = .01; $var_1 <= .98; $var_1 = $var_1 + .01 ) {
  for( $var_2 = .01; $var_2 + $var_1 < 1; $var_2 = $var_2 + .01 ) {
    $var_3 = 1 - ( $var_1 + $var_2 );
    // do something with the three vars
  }
}

For loops don't always have to increment or decrement by 1.

 

The problem with this is that the third var never changes and therefore this does not determine all of the possible allocations.  Thought this is probably a good start to the solution.

Yes it does:
    $var_3 = 1 - ( $var_1 + $var_2 );

so as each of the values for the first 2 vars changes through each of the loops the value of the third will also change. 

 

Just out of curiosity, because I can never get my head around this - this will generate 1million combinations using just the 3 vars, right?

 

Right now the code returns:

 

[0] => Array
        (
            [0] => 0.01
            [1] => 0.98
            [2] => 0.0099999999999993
        )

    [1] => Array
        (
            [0] => 0.02
            [1] => 0.97
            [2] => 0.0099999999999993
        )

    [2] => Array
        (
            [0] => 0.03
            [1] => 0.96
            [2] => 0.0099999999999993
        )

 

[2] never changes because [0] and [1] always add up to .99.  The real odd thing about this is that it should equal 0.01, right?  I'm not sure how many combination this would return.

 

The forloops only return 96 results currently.

 

Link to comment
Share on other sites

Right now the code returns:

 

[0] => Array
        (
            [0] => 0.01
            [1] => 0.98
            [2] => 0.0099999999999993
        )

    [1] => Array
        (
            [0] => 0.02
            [1] => 0.97
            [2] => 0.0099999999999993
        )

    [2] => Array
        (
            [0] => 0.03
            [1] => 0.96
            [2] => 0.0099999999999993
        )

Those are some strange results. Might have to make them whole numbers and divide:

$anarray = array();
for( $a = 1; $a <= 98; $a++ ) {
  for( $b = 1; $a + $b < 100; $b++ ) {
    $c = 100 - ( $a + $b );
    $var_1 = $a / 100;
    $var_2 = $b / 100;
    $var_3 = $c / 100;
    $anarray[] = array( $var_1, $var_2, $var_3 );
  }
}
print_r( $anarray );

You can see the results here: http://www.bwdplus.com/test/testloop.php

Link to comment
Share on other sites

Right now the code returns:

 

[0] => Array
        (
            [0] => 0.01
            [1] => 0.98
            [2] => 0.0099999999999993
        )

    [1] => Array
        (
            [0] => 0.02
            [1] => 0.97
            [2] => 0.0099999999999993
        )

    [2] => Array
        (
            [0] => 0.03
            [1] => 0.96
            [2] => 0.0099999999999993
        )

Those are some strange results. Might have to make them whole numbers and divide:

$anarray = array();
for( $a = 1; $a <= 98; $a++ ) {
  for( $b = 1; $a + $b < 100; $b++ ) {
    $c = 100 - ( $a + $b );
    $var_1 = $a / 100;
    $var_2 = $b / 100;
    $var_3 = $c / 100;
    $anarray[] = array( $var_1, $var_2, $var_3 );
  }
}
print_r( $anarray );

You can see the results here: http://www.bwdplus.com/test/testloop.php

 

Great solution, but how can I do this while making it dynamic.  I have tried increasing the numbers to four variables, but this doesn't seem to work:

 

$anarray2 = array();
for( $a = 1; $a <= 97; $a++ ) {
  for( $b = 1; $a + $b < 100; $b++ ) {
	for( $c = 1; $a + $b + $c < 100; $c++ ) {
		$d = 100 - ( $a + $b + $c );
		$var_1 = $a / 100;
		$var_2 = $b / 100;
		$var_3 = $c / 100;
		$var_4 = $d / 100;
		$anarray2[] = array( $var_1, $var_2, $var_3, $var_4 );
	}
  }
}
print_r( $anarray2 );

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.