Jump to content

Loop through Three Variables but Make them Always = 1


unemployment

Recommended Posts

$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 );

$anarray2 = array();
for( $a = 1; $a <= 97; $a++ ) {
  for( $b = 1; $a + $b <=98 ; $b++ ) {
    for( $c = 1; $a + $b + $c <= 99; $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 );

That's how a 4th variable would look. I would think that a recursive function might be what you need, but I'm not sure how it would be constructed.

Link to comment
Share on other sites

I can't figure out how to create the recursive function for this.  This is as far as I have gotten and it's not very far.  Any ideas?

 

<?php

function combination($total = 3){

	for($i = 1; $i <= $total: $i++){
	        
	    
	        return combination($total - 1);
    	}
}

?>

Link to comment
Share on other sites

  • 4 weeks later...

I made the following, and they work:

function create1array( $iterations ) {
if( $iterations <= 1 ) return array( array( 1 ) );
else {
	$maxarray = maxarray( 99, $iterations - 1 );
	foreach( $maxarray AS $key1=>$value1 ) {
		$cursum = 0;
		foreach( $value1 AS $value2 ) {
			$cursum += $value2;
		}
		$maxarray[$key1][] = 100 - $cursum;
	}
	$onearray = array();
	foreach( $maxarray AS $value1 ) {
		$newarray = array();
		foreach( $value1 AS $value2 ) {
			$newarray[] = $value2 / 100;
		}
		$onearray[] = $newarray;
	}
	return $onearray;
}
}

function maxarray( $maxvalue, $iterations ) {
if( $iterations <= 1 ) {
	$makearray = array();
	for( $i = 1; $i <= $maxvalue; $i++ ) {
		$makearray[] = array( $i );
	}
	return $makearray;
}
else {
	$makearray = array();
	$startarray = maxarray( $maxvalue - 1, $iterations -1 );
	foreach( $startarray AS $value1 ) {
		$cursum = 0;
		foreach( $value1 AS $value2 ) {
			$cursum += $value2;
		}
		for( $i = 1; $i <= $maxvalue - $cursum; $i++ ) {
			$nextarray = $value1;
			$nextarray[] = $i;
			$makearray[] = $nextarray;
		}
	}
	return $makearray;
}
}

The functions ate memory resources fast - I got out of memory errors when trying more than 3.

 

Good Luck!

Link to comment
Share on other sites

Maybe you should look at this problem in a different way. Why?

 

Because the number of possible combinations increases exponentially with each added stock. The number of permutations is roughly equal to 100 raised to the power of (the number of stocks minus 1) -- roughly, because you excluded zero and therefore 100 from the possibilities. So:

 

Stocks	Formula	    Result
1	100^0	        1
2	100^1	      100
3	100^2	   10,000
4	100^3	1,000,000

 

Who is going to sit around and wait for your webpage to calculate one million permutations and then wait for you to multiply all those percentages by their available funds; and then wait for you to loop through the results and determine the "proper asset allocation"? This page will take forever. Not to mention the memory exhaustion problem that rythemton pointed out.

 

If you could define what "proper asset allocation" means in terms of a formula, you could do it with far fewer calculations. For instance; let's say that Current Highest Price gets 2 points, Biggest Price Jump in Past 6 Months gets 4 points, Biggest Price Jump in Past 12 Months gets 2 points, Current Highest PE Ratio gets 3 points. Then you calculate the "points" for each stock (warning the following numbers are coming straight out of my @#$%&!)

 

Highest Price: Yahoo

Biggest 6-Month Jump: Google

Biggest 12-Month Jump: Apple

Highest P/E: Yahoo

 

Points:

Yahoo => 2 + 3 = 5

Google => 4

Apple => 2

TOTAL = 11

 

Allocation:

Yahoo => (5 / 11) = 45.45% ==>> $AvailableFunds * .4545

Google => (4 / 11) = 36.36% ==>> $AvailableFunds * .3636

Apple => (2 / 11) = 18.18% ==>> $AvailableFunds * .1818

 

Of course, you have to handle rounding issues and so forth. But this cuts the number of calculations you have to do down to a linear number, uses far fewer resources, and will return the results in a reasonable amount of time.

 

Link to comment
Share on other sites

  • 2 months later...

Incrementing by 5% keeps it manageable. Here's a recursive function for you

 

<?php
// portfolio size (2 or more)
$num = 3;

// get the combinations                                            
$results = array();
combo($results,$num, array());

// output the results
$format = str_repeat('%3d ', $num) . '<br />';
echo '<pre>';
foreach($results as $r)
{
    vprintf($format, $r); ;
}
echo '</pre>'; 

// the recursive function
function combo(&$results, $n, $com)
{
    if ($n < 2) exit("Must have at least 2 stocks");
    
    $sum = array_sum($com);
    $k = count($com);
    if ($k == $n-1) {
        $com[] = 100 - $sum;
        $results[] = $com;
    }
    else {
        $max = 100 - ($n-$k-1)*5;
        for ($i=5; $i+$sum<=$max; $i+=5) {
            
            combo($results, $n, array_merge($com,array($i)));
        }
    }
}
?>

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.