www.webdeveloper.com
Results 1 to 5 of 5

Thread: Simple issue - Logic isn't

  1. #1
    Join Date
    Apr 2009
    Posts
    16

    Simple issue - Logic isn't

    I have an array of an unknown length which will always have an evenly divisible amount of values, for example:

    Code:
    print_r($initialarray);
    
    Array ( [0] => 30 [1] => 31 [2] => 32 [3] => 33 [4] => 34 [5] => 35 )
    I need to create sets:
    Set 1: 30 v 35; 31 v 34; 32 v 33;
    Set 2: 30 v 34; 31 v 33; 32 v 35;
    Set 3: 30 v 33; 31 v 32; 34 v 35;
    Set 4: 30 v 32; 33 v 34; 31 v 35;
    Set 5: 30 v 31; 32 v 34; 33 v 35;

    The order of the values are divide by v to indicate they are a set. The ordering of the values in the set does not matter (I put that together at random out of my head). As you can see there can not be duplicate sets matching in any other set or within the same set.


    I have tried many different things to come up with something that works.
    The closest I've gotten was putting the initial values into a cascading array containing all possible valid matchups:
    Code:
    Array ( [0] => Array ( [0] => 35 [1] => 31 ) [1] => Array ( [0] => 34 [1] => 31 ) [2] => Array ( [0] => 33 [1] => 31 ) [3] => Array ( [0] => 32 [1] => 31 ) )
    
    Array ( [0] => Array ( [0] => 35 [1] => 32 ) [1] => Array ( [0] => 34 [1] => 32 ) [2] => Array ( [0] => 33 [1] => 32 ) )
    
    Array ( [0] => Array ( [0] => 35 [1] => 33 ) [1] => Array ( [0] => 34 [1] => 33 ) )
    
    Array ( [0] => Array ( [0] => 35 [1] => 34 ) )
    These values are arrays within one array called $sched.
    I just noticed that I had left 30 out of the array.. oops



    Confused? I am....

    PHP Code:
    $count count($initialarray);
    $recount $count -1;
    for(
    $u=0$u $count;$u++){
        for(
    $d=0;$d<$recount;$d++){
             
    $vs[$u][$d] = $sched[$d][$u];
        }
        
    $recount -= 1;


    So that didn't work, I am complicating this beyond what it should be and I can't wrap my head around the issue anymore. Any help at all, even it means starting over, will be greatly appreciated!

  2. #2
    Join Date
    Nov 2002
    Location
    England
    Posts
    693

  3. #3
    Join Date
    Apr 2009
    Posts
    16
    I actually have already used :

    PHP Code:
    /*
     Use: $arr = power_perms($in);

     Example:
      $in = array("A","B","C");
      $power_perms = power_perms($in);
     
    */

    function power_perms($arr) {

        
    $power_set power_set($arr);
        
    $result = array();
        foreach(
    $power_set as $set) {
            
    $perms perms($set);
            
    $result array_merge($result,$perms);
        }
        return 
    $result;
    }

    //added maxLength to keep match ups between two
    function power_set($in,$minLength 2,$maxLength 2) {

       
    $count count($in);
       
    $members pow(2,$count);
       
    $return = array();
       for (
    $i 0$i $members$i++) {
          
    $b sprintf("%0".$count."b",$i);
          
    $out = array();
          for (
    $j 0$j $count$j++) {
             if (
    $b{$j} == '1'$out[] = $in[$j];
          }
          if (
    count($out) >= $minLength) {
              if (
    count($out) <= $maxLength) {
             
    $return[] = $out;
            }
          }
       }

       
    //usort($return,"cmp");  //can sort here by length
       
    return $return;
    }

    function 
    factorial($int){
       if(
    $int 2) {
           return 
    1;
       }

       for(
    $f 2$int-1$f *= $int--);

       return 
    $f;
    }

    function 
    perm($arr$nth null) {

        if (
    $nth === null) {
            return 
    perms($arr);
        }

        
    $result = array();
        
    $length count($arr);

        while (
    $length--) {
            
    $f factorial($length);
            
    $p floor($nth $f);
            
    $result[] = $arr[$p];
            
    array_delete_by_key($arr$p);
            
    $nth -= $p $f;
        }

        
    $result array_merge($result,$arr);
        return 
    $result;
    }

    function 
    perms($arr) {
        
    $p = array();
        for (
    $i=0$i factorial(count($arr)); $i++) {
            
    $p[] = perm($arr$i);
        }
        return 
    $p;
    }

    function 
    array_delete_by_key(&$array$delete_key$use_old_keys FALSE) {

        unset(
    $array[$delete_key]);

        if(!
    $use_old_keys) {
            
    $array array_values($array);
        }

        return 
    TRUE;


    Which results in :

    Code:
    Array ( [0] => 30 [1] => 31 [2] => 32 [3] => 33 [4] => 34 [5] => 35 ) Array ( [0] => Array ( [0] => 34 [1] => 35 ) [1] => Array ( [0] => 35 [1] => 34 ) [2] => Array ( [0] => 33 [1] => 35 ) [3] => Array ( [0] => 35 [1] => 33 ) [4] => Array ( [0] => 33 [1] => 34 ) [5] => Array ( [0] => 34 [1] => 33 ) [6] => Array ( [0] => 32 [1] => 35 ) [7] => Array ( [0] => 35 [1] => 32 ) [8] => Array ( [0] => 32 [1] => 34 ) [9] => Array ( [0] => 34 [1] => 32 ) [10] => Array ( [0] => 32 [1] => 33 ) [11] => Array ( [0] => 33 [1] => 32 ) [12] => Array ( [0] => 31 [1] => 35 ) [13] => Array ( [0] => 35 [1] => 31 ) [14] => Array ( [0] => 31 [1] => 34 ) [15] => Array ( [0] => 34 [1] => 31 ) [16] => Array ( [0] => 31 [1] => 33 ) [17] => Array ( [0] => 33 [1] => 31 ) [18] => Array ( [0] => 31 [1] => 32 ) [19] => Array ( [0] => 32 [1] => 31 ) [20] => Array ( [0] => 30 [1] => 35 ) [21] => Array ( [0] => 35 [1] => 30 ) [22] => Array ( [0] => 30 [1] => 34 ) [23] => Array ( [0] => 34 [1] => 30 ) [24] => Array ( [0] => 30 [1] => 33 ) [25] => Array ( [0] => 33 [1] => 30 ) [26] => Array ( [0] => 30 [1] => 32 ) [27] => Array ( [0] => 32 [1] => 30 ) [28] => Array ( [0] => 30 [1] => 31 ) [29] => Array ( [0] => 31 [1] => 30 ) )
    That isn't quite what I need I need to have grouped sets of unique matchups.
    I resorted the array above and then limited it to get the array:
    Code:
    Array ( [0] => Array ( [0] => 35 [1] => 31 ) [1] => Array ( [0] => 34 [1] => 31 ) [2] => Array ( [0] => 33 [1] => 31 ) [3] => Array ( [0] => 32 [1] => 31 ) )
    
    Array ( [0] => Array ( [0] => 35 [1] => 32 ) [1] => Array ( [0] => 34 [1] => 32 ) [2] => Array ( [0] => 33 [1] => 32 ) )
    
    Array ( [0] => Array ( [0] => 35 [1] => 33 ) [1] => Array ( [0] => 34 [1] => 33 ) )
    
    Array ( [0] => Array ( [0] => 35 [1] => 34 ) )
    I have now limited the matches to only unique matches.

    From that I need to get a match up for each number for a series.




    To sum it up: The numbers are teams. Each team needs to play each team once. The schedule will be set so that each team only plays one game each week.
    The schedule needs to be set over several weeks to allow all the games to be played without a team playing more than once in a week.

  4. #4
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    19,176
    If you want to build your own combinations, you could look into using the PEAR Math_Combinatorics package. And of course you could search for some ready-made PHP round robin classes/functions.
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  5. #5
    Join Date
    Apr 2009
    Posts
    16
    I wasn't sure what to search for and never thought to search for the obvious. In the end it was quite simply a google search. THANKS.


    Some modifications and this is perfect:

    PHP Code:
    /******************************************************************************
    * Round Robin Pairing Generator
    * Author: Eugene Wee
    * Date: 23 May 2005
    * Last updated: 13 May 2007
    * Based on an algorithm by Tibor Simko.
    *
    * Copyright (c) 2005, 2007 Eugene Wee
    *
    * Permission is hereby granted, free of charge, to any person obtaining a copy
    * of this software and associated documentation files (the "Software"), to deal
    * in the Software without restriction, including without limitation the rights
    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    * copies of the Software, and to permit persons to whom the Software is
    * furnished to do so, subject to the following conditions:
    *
    * The above copyright notice and this permission notice shall be included in
    * all copies or substantial portions of the Software.
    *
    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    * THE SOFTWARE.
    ******************************************************************************/

    function generateRoundRobinPairings($num_players) {
        
    // Do we have a positive number of players? If not, default to 4.
        
    $num_players = ($num_players 0) ? (int)$num_players 4;

        
    // If necessary, round up number of players to nearest even number.
        
    $num_players += $num_players 2;

        
    // Format for pretty alignment of pairings across rounds.
        
    $format "%0" ceil(log10($num_players)) . "d";
        
    $pairing "$format-$format ";

        
    // Set the return value
        
    $ret $num_players " Player Round Robin:\n-----------------------";

        
    // Generate the pairings for each round.
        
    for ($round 1$round $num_players$round++) {
            
    $ret .= sprintf("\nRound #$format : "$round);
            
    $players_done = array();

            
    // Pair each player except the last.
            
    for ($player 1$player $num_players$player++) {
                if (!
    in_array($player$players_done)) {
                    
    // Select opponent.
                    
    $opponent $round $player;
                    
    $opponent += ($opponent 0) ? $num_players 1;

                    
    // Ensure opponent is not the current player.
                    
    if ($opponent != $player) {
                        
    // Choose colours.
                        
    if (($player $opponent) % == xor $player $opponent) {
                            
    // Player plays white.
                            
    $ret .= sprintf($pairing$player$opponent);
                        } else {
                            
    // Player plays black.
                            
    $ret .= sprintf($pairing$opponent$player);
                        }

                        
    // This pair of players are done for this round.
                        
    $players_done[] = $player;
                        
    $players_done[] = $opponent;
                    }
                }
            }

            
    // Pair the last player.
            
    if ($round == 0) {
                
    $opponent = ($round $num_players) / 2;
                
    // Last player plays white.
                
    $ret .= sprintf($pairing$num_players$opponent);
            } else {
                
    $opponent = ($round 1) / 2;
                
    // Last player plays black.
                
    $ret .= sprintf($pairing$opponent$num_players);
            }
        }

        return 
    $ret;


Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles