Jump to content

Selecting elements from multidimensional array


Turgeon_P

Recommended Posts

I have a multidimensional array, lets say it's consisting of arrays for groups of balls and then with the key as the number of the ball and then subkeys for color and size, something like what can be seen below (slightly simplified).

 

If I want to select as many balls as possible, based on their size, but there has to be 1) at least one ball from each group and 2) the number of balls from each group multiplied with each other can't be more than lets say 20, and also 3) one of the groups has to have only one single ball selected (to maximize the number of balls selected in total).

 

I know the basics about arrays and foreach loops and so on but how would I go about checking for these above mentioned limitations?

Array(    [Group1] => Array    (           [1] => Array               (                [color] => 'blue'               [size] => 1.25               )          [2] => Array               (                [color] => 'red'               [size] => 1.59               )        [3] => Array               (                [color] => 'red'               [size] => 1.20               )        [4] => Array               (                [color] => 'green'               [size] => 1.91               )        [5] => Array               (                [color] => 'blue'               [size] => 1.73               )    )    [Group2] => Array    (        [1] => Array               (                [color] => 'red'               [size] => 1.84               )          [2] => Array               (                [color] => 'red'               [size] => 1.21               )        [3] => Array               (                [color] => 'green'               [size] => 1.17               )        [4] => Array               (                [color] => 'green'               [size] => 1.46               )        [5] => Array               (                [color] => 'blue'               [size] => 1.70               )    )    [Group3] => Array    (        [1] => Array               (                [color] => 'red'               [size] => 1.04               )          [2] => Array               (                [color] => 'yellow'               [size] => 1.99               )        [3] => Array               (                [color] => 'orange'               [size] => 1.07               )        [4] => Array               (                [color] => 'blue'               [size] => 1.12               )        [5] => Array               (                [color] => 'blue'               [size] => 1.18               )    )    [Group4] => Array    (        [1] => Array               (                [color] => 'blue'               [size] => 1.66               )          [2] => Array               (                [color] => 'blue'               [size] => 1.24               )        [3] => Array               (                [color] => 'blue'               [size] => 1.45               )        [4] => Array               (                [color] => 'blue'               [size] => 1.42               )        [5] => Array               (                [color] => 'red'               [size] => 1.38               )    ))
Edited by Turgeon_P
Link to comment
Share on other sites

Given your constraints you can pick a maximum of 9 balls (5 + 2 + 1 + 1) from the four groups so shuffle the groups then pick five from the first, two from the second and one from each of the remaining two groups.

 

Brute force method

$target = 10;       // max product of numbers chosen from groups
$result = array();
$max = 0;           // max ball count

$g1 = count($balls['Group1']);
$g2 = count($balls['Group2']);
$g3 = count($balls['Group3']);
$g4 = count($balls['Group4']);

for ($a=1; $a<=$g1; $a++) {
    for ($b=1; $b<=$g2; $b++) {
        for ($c=1; $c<=$g3; $c++) {
            for ($d=1; $d<=$g4; $d++) {
                $prod = $a*$b*$c*$d;
                $tot = $a + $b + $c + $d;
                if (($prod <= $target) && ($tot > $max)) {
                    $result = array($a,$b,$c,$d);
                }
            }
        }
    }
}

echo join (' + ', $result);              //==> 5 + 2 + 1 + 1
Edited by Barand
Link to comment
Share on other sites

Okay, I made a ninja edit from 10 to 20 in this example in case you missed that. In reality it's more groups and a higher limit but it was too tedious to mention.

 

It doesn't matter if the number of balls multiplicated is slightly less than 20 as long as I get the biggest sizes.

 

As I read my last post I started thinking and maybe it's easier to work with a simpler array, like this?

Array(    [0] => Array    (           [group] => 'Group1'        [number] => '1'        [color] => 'blue'        [size] => 1.25     )      [1] => Array    (           [group] => 'Group1'        [number] => '2'        [color] => 'red'        [size] => 1.59     )

...

)

 

I can pick the size elements and sort them but I still don't know how to make sure there's one ball selected from each group and that one group has no more than one ball selected.

Edited by Turgeon_P
Link to comment
Share on other sites

That brute force method might be something that I can start tinkering with but I won't be able to predict how many balls that should be selected from every group like that.

 

What is that max ball count set as zero in your example by the way? Did you mean that it should be set as 5+2+1+1=9?

 

I still wanna select the (relatively) biggest balls, even though it might be 3+3 instead of 5+2 from two groups. Let's say that I want the highest total weight with the above given constraints.

Edited by Turgeon_P
Link to comment
Share on other sites

What is that max ball count set as zero in your example by the way? Did you mean that it should be set as 5+2+1+1=9?

 

It is looping and trying to find the max number of balls. To do this it compares the new count with current max. If the new count is greater than the current max then we have a new max. To do this you have to set the current max to 0 at the start. If it were set to, say, 999, then you would never get a new count greater than the current max.

 

If you sort you balls in the groups by weight, and always start with the most balls from the heaviest group, heaviest group then that should help.

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.