Jump to content

Recommended Posts

What i am after is a round robin table that will sort lets say "cars", "drivers".  so if i have 10 cars and 10 drivers i would end up with 10 different combos of cars and there driver.   I am looking for ideas how to do this or if someone has code that does this aready.  The end game for this round robin is to have all info registered into a mysql database along with it a lap time for around the track.  So if car-6 and driver-2 have a lap time of 2 min i need to save this to a database. this would be for every slot in every round. 

 

 

Only idea i have come up with other than figuring out the code for the round robin is enter cars in one table, drivers in another. Use round robin code to generate the rounds and then have that saved to yet another table and from there display that info with functions to enter time.

 

 

Ideas, code or links would be helpful

 

Thanks

Link to comment
https://forums.phpfreaks.com/topic/296414-round-robin-questionsideas/
Share on other sites

If you have 10 cars and 10 drivers there are 100 different combinations, not 10.

 

Table : car (car_id | carname)

Table : driver (driver_id | drivername)

 

To get all combinations

SELECT carname, drivername
FROM car CROSS JOIN driver

If you have 10 cars and 10 drivers then there are 10! (ten factorial) ways of assigning each driver to a car, This is 3628800 different ways.

 

Read all the drivers into an array called $drivers[]

Then read all cars into an array called $cars[]

 

Randomly shuffle the arrays by using the PHP shuffle command

 

shuffle($drivers);
shuffle($cars);

 

Now put driver[0] with car[0], driver[1] with car[1] etc etc.

Edited by grissom

If you have 10 cars and 10 drivers then there are 10! (ten factorial) ways of assigning each driver to a car, This is 3628800 different ways.

 

bullshit-meter-01_thumb.gif

 

(Each of the 10 cars can have each of the 10 drivers. 10 x 10 = 100)

  • Like 1

bullshit-meter-01_thumb.gif

 

(Each of the 10 cars can have each of the 10 drivers. 10 x 10 = 100)

 

The first car has a choice of 10 drivers

 

The second car has a choice of 9 drivers (the first driver has been assigned)

 

So the number of ways of filling the first two cars is 10 X 9 = 90

 

The number of ways of filling the first three cars is 10 X 9 X 8 possibilities = 720  .. and so on.

 

You make yourself look a complete p**** with your above comment. I suggest you take some night classes in maths before you get cocky and post stupid insulting graphics

Keeping it simple, for the sake of my limited maths knowledge, let's say we have 3 cars (A,B,C) and 3 drivers (1,2,3). The combinations are then
 

A1 B1 C1
A2 B2 C2
A3 B3 C3

which I count to be 9 (ie 3 x 3);

Using the Grissom method the count would be 3! (ie 6), so which three would be left out?

Using the Grissom method the count would be 3! (ie 6), so which three would be left out?

It's not a counting "method" but a different situation. I'm going to stick with the racing analogy.

 

You're picking one driver and one car at a time (A1). The other drivers and the other cars are irrelevant. This driver+car does a qualifying lap around the track. You then give them a different car (A2), they lap, then lap again with the third car (A3). Repeat that with the other two drivers (B1-3, C1-3) and you have a total of nine qualifying laps. This way you can see a driver's performance change with respect to which car they were driving (A1-3, B1-3, C1-3), or alternatively how different drivers handle the same car (A-C1, A-C2, A-C3).

 

grissom is picking all the drivers and all the cars and putting them into a race all at once. Then the assignments change, except rather than have every driver get a different car, what changes is that somebody (perhaps more than one person) gets a different car. Thus the race lineup as a whole changes, even if some or most (but not all) of the drivers stay in the same car they were just driving.

The combinations are

1. A1B2C3

2. A1B3C2

3. A2B1C3

4. A2B3C1

5. A3B1C2

6. A3B2C1

This is more geared towards measuring the performance of a driver with respect to how the other drivers are doing. As is what happens a real race. For example, with races 1 and 2 you can see how driver A (who kept the same car for both) did when B and C changed cars. If you think A's car is the variable, you can compare races 3 and 4 where A used a different car from before (but kept it for both races) and B and C changed. Or races 5 and 6. For driver B you can compare 3+5/1+6/2+4 and for C it's 4+6/2+5/1+3.

 

tldr: you're counting driver+car combinations, grissom is counting driver+car+driver+car+driver+car combinations.

Edited by requinix
  • Like 1

@Birdmansplace (if you are still here after that short diversion)

 

I have shown you how to get the combinations for my envisaged scenario using a simple cross join in the SQL.

 

To use the scenario envisaged by grissom then the method is more complex. As it requires a recursive solution then read the data into arrays rather than have queries called recursively.

 

The data (I restricted to 4 of each for brevity of output)

$cars =    [    'Audi', 
                'BMW', 
                'Chrysler', 
                'Daewoo' ];
                
$drivers = [    'Adam', 
                'Ben', 
                'Cathy', 
                'Diana'  ]

The code

$k = count($cars);
$thead = "<tr><th rowspan='2'>Round</th><th colspan='$k'>Cars</th></tr><tr><th>" . 
        join('</th><th>', $cars) . "</th></tr>\n";
$tbody = '';

$results = [];
combos($drivers, $results, []);  // call the recursive function to get combinations

foreach ($results as $k => $names) {
    $tbody .= "<tr><td>".(++$k)."</td><td>" . join('</td><td>', $names) . "</td></tr>\n";
}


function combos($set, &$results, $tmp) 
{
    $k = count($set);
    if ($k==1) {
        $results[] = array_merge($tmp, $set);
    }
    else {
        // takes each one in turn and call with remaining set members
        foreach ($set as $k => $x) {
            $copy = $set;
            unset($copy[$k]);
            combos($copy, $results, array_merge($tmp, [$x]));
        }
    }
}

Output

 

post-3105-0-81633600-1432221049_thumb.png

  • Like 1

Read all the drivers into an array called $drivers[]

Then read all cars into an array called $cars[]

 

Randomly shuffle the arrays by using the PHP shuffle command

shuffle($drivers);
shuffle($cars);

Now put driver[0] with car[0], driver[1] with car[1] etc etc.

 

Just in case anyone is tempted to use this "shuffle and pray" shortcut approach to this problem I checked out its validity.

 

I took arrays of N drivers and shuffled them N! times, storing each combination. I then checked to see how many were unique. These are the results

ACB BAC BAC BAC CBA CBA

3 drivers:      3 duplicate combinations out of      6 (50%)

ABCD ACDB ADBC ADBC ADCB BADC BCAD BCDA BCDA BDCA CABD CABD
CBAD CBDA DABC DACB DACB DACB DBAC DBCA DBCA DCAB DCAB DCBA

4 drivers:      7 duplicate combinations out of     24 (29%)

ABDCE ABDEC ABECD ABECD ABEDC ABEDC ACBDE ACDBE ACDBE ACDEB ADBEC ADEBC
ADECB AEBDC AECBD AECDB AEDCB BACED BADCE BADEC BADEC BCAED BCDEA BCDEA
BCEAD BDACE BDACE BDAEC BDAEC BDCAE BDCAE BDEAC BDECA BEDAC BEDAC BEDCA
CABDE CABED CABED CAEDB CAEDB CAEDB CBAED CBDAE CBEAD CBEDA CBEDA CDABE
CDAEB CDBAE CDBEA CDEAB CDEBA CDEBA CDEBA CDEBA CDEBA CEABD CEADB CEADB
CEADB CEBDA CEDAB CEDAB CEDAB CEDBA DABCE DABCE DABCE DAEBC DBAEC DBCAE
DBEAC DCABE DCBAE DCBEA DCBEA DCBEA DCEAB DCEBA DCEBA DEACB DEACB DEBAC
DEBAC DEBCA DECAB DECAB DECBA DECBA DECBA EADBC EADBC EADBC EADBC EBACD
EBACD EBACD EBACD EBCDA EBDCA EBDCA ECABD ECBAD ECBAD ECBDA ECBDA ECDAB
ECDBA ECDBA EDABC EDABC EDACB EDACB EDACB EDBCA EDBCA EDCAB EDCBA EDCBA

5 drivers:     46 duplicate combinations out of    120 (38%)

6 drivers:    265 duplicate combinations out of    720 (36%)

7 drivers:   1841 duplicate combinations out of   5040 (36%)

8 drivers:  14761 duplicate combinations out of  40320 (36%)

9 drivers: 327861 duplicate combinations out of 362880 (90%)

Verdict: Not fit for purpose.

 

The code used to test:

<?php

$drivers = ['A','B'];
$extra   = ['C','D','E','F','G','H','I'];
$factorials =   [ 
                    3 => 6,
                    4 => 24,
                    5 => 120,
                    6 => 720,
                    7 => 5040,
                    8 => 40320,
                    9 => 362880   ];

foreach ($extra as $e) {
    $drivers[] = $e;  // add to drivers
    echo countUnique($drivers, $factorials);       // test with N drivers 
}                            

function countUnique($d, $facts)  
{
    $combos = [];
    $k = count($d);
    $f = $facts[$k];
    for ($i=0; $i<$f; $i++) {
        shuffle($d);                 // shuffles n! times
        $str = join('',$d);          // and stores each
        $combos[] = $str;            // random combination
    }
        
        // output the smaller shuffled combo arrays to view duplicates
        if ($k < 6) {
            sort($combos);
            $chunks = array_chunk($combos, 12);
            foreach($chunks as $coms) echo join(' ', $coms)."<br>";
            echo '<br>';
        }
        
    $n = count(array_unique($combos));  // count how many were unique
    $n1 = $f - $n;   // number of duplicate values
    $n2 = count($combos);  // to check that n! were generated
    return sprintf('%d drivers: %6d duplicate combinations out of %6d (%d%%)<br><br>', 
            count($d), $n1, $n2, $n1*100/$n2 );
}
?>
  • Like 1
  • 2 weeks later...

Thanks for the in-put...  The way i worded the opening topic was to be able to relate to alot of users to see what i should do.  I am building a web based "arena log" for my father inlaws horse arena and they host a few different things.  The round robin they do is team round robin and its a roper and a healer  (car, driver as stated in opening topic). All healer's compete with one roper.    I need to be able to enter into a mysql database these names, roper in one table and healer in another.  Then once all the names are there make a round robin table.  Once round robin table is made i also need to save a track time with that pair of people for each round.

 

My skills with php are limited and looking for help to literally wright the code.  Since I am doing this for him free of charge I am coming to you guys for help.  Once everything for this is complete i plan on making it open source for download some where.

 

Thanks

martin nicky and olivia heal for alice then bob and finally cindy.  So there would be three rounds and never with the same partner. and for each round i need to be able to log a time per pair per round.

Round1

Alice & Martin   _time_

Bob & Nicky     _time_

Cindy & Olivia  _time_

 

Round2

Alice & Nicky _time_

Bob & Nicky  _time_

Cindy & Martin  _time_

 

Step one

Enter roper and healer by name to a database

 

Step two

Use info from step one to make round robin list and save it.

 

Step three

Pull list from step two and be able to save a track time per pair and save again to database.

 

 

Hope that helps

I assume Round 2 is supposed to have Bob and Olivia?

 

As it so happens, what you're describing wasn't quite covered by grissom or Barand. So that's awesome.

 

Would it be enough to shuffle the list of ropers and the list of healers, pair everyone, and then "rotate" one of the lists? Like it goes M/N/O/P/Q then N/O/P/Q/M then O/P/Q/M/N and so on. The advantage is that it's really, really easy to do, but the disadvantage is that the results aren't random from one round to the next: someone can look at the assignments in one round and tell what the assignments will be in the next round.

Edited by requinix

You need to the ropers in a consistent sequence and rotate the heelers each round

A B C
------
M N O
N O M
O M N

Once allocated the running order can be shuffled.

 

So it would be like this

<?php
$ropers = [ 'Alice',
            'Bob',
            'Cindy',
            'Dave',
            'Emma',
            'Fred',
            'Gina',
            'Henry',
            'Imogen',
            'Jack'      ];
            
$heelers= [ 'Martin',
            'Nicola',
            'Oliver',
            'Paula',
            'Quentin',
            'Rosie',
            'Steve',
            'Tracey',
            'Uri',
            'Vanessa'  ];

$output = '';
for ($round=1; $round<=10; $round++) {
    $rotated = rotate($heelers, $round-1);
    $riders = array_combine($ropers, $rotated);
    
    $output .= "<table border='1'>\n
        <tr><th colspan='4'>Round $round</th></tr>\n
        <tr><th></th><th>Roper</th><th>Heeler</th><th>Time</th></tr>\n";
    $turn=1;
    $rprs = $ropers; // keep ropers in original order
    shuffle($rprs);
    foreach ($rprs as $r) {
        $h = $riders[$r];  // get the heeler allocated to the roper for this round
        $output .= "<tr><td>$turn</td><td>$r</td><td>$h</td><td></td></tr>\n";
        ++$turn;
    }
    $output .= "</table>\n";
}
            
function rotate($array, $n)
{
    for ($i=0; $i<$n; $i++)
        $array[] = array_shift($array);
    return $array;
}

?>
<html>
<head>
<title>Round Robin</title>
<style type="text/css">
    table {
        margin: 5px;
        width:  18%;
        float:  left;
    }
    th {
        color: white;
        background-color: #369;
    }
    td {
        background-color: white;
        font-family: sans-serif;
        font-size: 9pt;
    }
    div {
        background-color: #CCC;
    }
</style>
</head>
<body>
    <h1>Round Robin Event</h1>
    <div>
    <?=$output?>
    </div>
</body>
</html>

PS : 100 (10x10) combinations :)

post-3105-0-06340500-1433506376_thumb.png

Edited by Barand
  • Like 1

Yes to your first question requinix, and I like your idea because you say its more simple as long as your able to use mysql database. I need to register them in a table and the shuffle them from the table and save it to another table.  From that other table i would need to be able to add a time to each pairing and save it back to the table so at the end we can find the winner.

  • 1 month later...

Barand

 

I have been messing round with the code you posted and have been trying to do some stuff.  I have setup a database called roundrobin in mysql.  there is 2 tables  RRroper, RRheeler.  in each table there is 4 columns sid(auto increm), roper/healer.  I am trying to figure out the code needed for $ropers and $heelers= to login and pull names from the database.

include("dbinfo.php");
mysql_connect($host,$username,$password);
@mysql_select_db($database) or die( "Unable to select database");
// Retrieve data from database
$sql="SELECT * FROM roper ORDER BY sid";
$result=mysql_query($sql);
while($rows=mysql_fetch_array($result)){
echo $rows['roper'];
}

this will read the database but can't get it to word in your coding.  I have changed $result to $ropers with no luck. removed while($rows.... and the next 2 lines with the same issue.

 

The other issue will be once i pull info from the db if i have more than 10 pairs not all will display

for ($round=1; $round<=10; $round++) {

so not sure what to do with changing "10" to read the count of how many ropers are in the database.

 

Thanks

couldn't save my edited post for some reason. so heres what i was adding:

 

so not sure what to do with changing "10" to read the count of how many ropers are in the database.

 

Once thats figured out i am also going to make a table to save the output to the db so i can save the times for each pair every round. I would like it to display the same way as well if possible.

 

To sum it up:

first step would be to enter names to database.

step 2 the code you made to display and make sure everything is correct

step 3 save displayed output to a table along with a column for time

step 4 display saved output with the ability to save round time per pair per round

step 5 when all rounds complete view it as your code does with saved times

 

Thanks

OK no strategy then, so assuming there are always the same number of each, and given your data looks like this

mysql> SELECT sid, roper FROM rrroper;
+-----+--------+
| sid | roper  |
+-----+--------+
|   1 | Alice  |
|   2 | Bob    |
|   3 | Cindy  |
|   4 | Dave   |
|   5 | Emma   |
|   6 | Fred   |
|   7 | Gina   |
|   8 | Henry  |
|   9 | Imogen |
|  10 | Jack   |
+-----+--------+
10 rows in set (0.00 sec)

mysql> SELECT sid, heeler FROM rrheeler;
+-----+---------+
| sid | heeler  |
+-----+---------+
|   1 | Martin  |
|   2 | Nicola  |
|   3 | Oliver  |
|   4 | Paula   |
|   5 | Quentin |
|   6 | Rosie   |
|   7 | Steve   |
|   8 | Tracey  |
|   9 | Uri     |
|  10 | Vanessa |
+-----+---------+
10 rows in set (0.00 sec)

CREATE TABLE `result` (
  `result_id` int(11) NOT NULL AUTO_INCREMENT,
  `round_no` int(11) NOT NULL,
  `roper_id` int(11) NOT NULL,
  `heeler_id` int(11) NOT NULL,
  `time` time DEFAULT NULL,
  PRIMARY KEY (`result_id`)
)

this code will generate the rounds for you in a result table for you to record the times (assumes ropers and heelers both have id values 1..N)

<?php
include("db_inc.php"); // define HOST, USERNAME etc
$db = new mysqli(HOST,USERNAME,PASSWORD,'roundrobin');
//
//   GENERATE THE result TABLE
//   PAIRING EACH ROPER WITH A 
//   DIFFERENT HEELER FOR EACH ROUND
//

$res = $db->query("SELECT COUNT(*) FROM rrroper");
list($numRounds) = $res->fetch_row();

for ($r=1; $r<=$numRounds; $r++) {
    $sql = "INSERT INTO result (round_no, roper_id, heeler_id)
            SELECT $r as `round`
            , r.sid as roper
            , h.sid as heeler
            FROM rrroper r
            INNER JOIN rrheeler h
                ON r.sid = MOD((h.sid + $r),10) + 1";
    $db->query($sql);
}
?>
Edited by Barand

A couple of corrections required to the above:

INNER JOIN rrheeler h
ON r.sid = MOD((h.sid + $r),10) + 1";

should be

INNER JOIN rrheeler h
ON r.sid = MOD((h.sid + $r),$numRounds) + 1";

and the "time" column in result table should be DECIMAL(8,2)

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.