Algoritmo di Berger

Da Wikipedia, l'enciclopedia libera.

L'algoritmo di Berger è un algoritmo usato per stilare un calendario (diviso in giornate o turni) di un campionato sportivo con la formula del girone all'italiana. La versione basilare, riproducibile anche a mano, produce una lista che non alterna automaticamente un turno in casa ad uno in trasferta.

È stato programmato dallo scacchista austriaco Johann Berger.

Caratteristiche dell'algoritmo[modifica | modifica wikitesto]

Dato un numero pari di squadre partecipanti, l'algoritmo calcola "n:2" accoppiamenti per ogni partita.[1]

  • Per ogni giornata "g" compresa tra 1 e "n−1";
  • Per ogni incontro "i" compreso tra 1 e "n:2";
    • L'incontro "i" abbina due squadre, in considerazione dei seguenti criteri:
      1. non sono ancora state abbinate;
      2. le restanti squadre, non selezionate, non sono già state accoppiate.

Implementazioni[modifica | modifica wikitesto]

Vi sono funzioni che implementano l'algoritmo ponendo a parametro l'array con i nomi delle squadre, in numero pari, elaborando il calendario di un girone (stampato in video).

Nell'eventualità di un numero dispari di squadre, una di esse sarà posta "a riposo" ad ogni giornata/turno. I vincoli per squadre che condividano lo stesso campo sportivo sono risolvibili tramite l'alternanza "in casa/fuori casa".

Java[modifica | modifica wikitesto]

Algoritmo elaborato tramite Java.

public void AlgoritmoDiBerger(String[] squadre){
        
    int numero_squadre = squadre.length;
    int giornate = numero_squadre - 1;
      
    /* crea gli array per le due liste in casa e fuori */
    String[] casa = new String[numero_squadre /2];
    String[] trasferta = new String[numero_squadre /2];

    for (int i = 0; i < numero_squadre /2; i++) {
        casa [i] = squadre[i]; 
        trasferta[i] = squadre[numero_squadre - 1 - i]; 
    }
    
    for (int i = 0; i < giornate; i++) {
        /* stampa le partite di questa giornata */
        System.out.printf("%d^ Giornata\n",i+1);

        /* alterna le partite in casa e fuori */
        if (i % 2 == 0) {
            for (int j = 0; j < numero_squadre /2 ; j++)
                 System.out.printf("%d  %s - %s\n", j+1, trasferta[j], casa[j]); 
        }
        else {
            for (int j = 0; j < numero_squadre /2 ; j++) 
                 System.out.printf("%d  %s - %s\n", j+1, casa[j], trasferta[j]); 
        }
    
        // Ruota in gli elementi delle liste, tenendo fisso il primo elemento
        // Salva l'elemento fisso
        String pivot = casa [0];
  
        /* sposta in avanti gli elementi di "trasferta" inserendo 
           all'inizio l'elemento casa[1] e salva l'elemento uscente in "riporto" */
        String riporto = shiftRight(trasferta, casa [1]);

        /* sposta a sinistra gli elementi di "casa" inserendo all'ultimo 
           posto l'elemento "riporto" */
        shiftLeft(casa, riporto);

        // ripristina l'elemento fisso
        casa[0] = pivot ;
    } 
}

Variante perfettamente funzionante:

public void AlgoritmoDiBerger(String[] squadre){
 
    int numero_squadre = squadre.length;
    int giornate = numero_squadre - 1;
 
    /* crea gli array per le due liste in casa e fuori */
    String[] casa = new String[numero_squadre /2];
    String[] trasferta = new String[numero_squadre /2];
 
    for (int i = 0; i < numero_squadre /2; i++) {
        casa [i] = squadre[i]; 
        trasferta[i] = squadre[numero_squadre - 1 - i]; 
    }
 
    for (int i = 0; i < giornate; i++) {
        /* stampa le partite di questa giornata */
        System.out.printf("%d^ Giornata\n",i+1);
 
        /* alterna le partite in casa e fuori */
        if (i % 2 == 0) {
            for (int j = 0; j < numero_squadre /2 ; j++)
                 System.out.printf("%d  %s - %s\n", j+1, trasferta[j], casa[j]); 
        }
        else {
            for (int j = 0; j < numero_squadre /2 ; j++) 
                 System.out.printf("%d  %s - %s\n", j+1, casa[j], trasferta[j]); 
        }
 
        // Ruota in gli elementi delle liste, tenendo fisso il primo elemento
        // Salva l'elemento fisso
        String pivot = casa [0];
 
        /* sposta in avanti gli elementi di "trasferta" inserendo 
           all'inizio l'elemento casa[1] e salva l'elemento uscente in "riporto" */
		   
 		String riporto = trasferta[trasferta.length - 1];
		trasferta = shiftRight(trasferta, casa[1]);

 
        /* sposta a sinistra gli elementi di "casa" inserendo all'ultimo 
           posto l'elemento "riporto" */
		   
        casa = shiftLeft(casa, riporto);
 
        // ripristina l'elemento fisso
        casa[0] = pivot ;
    } 
}
 
 private String[] shiftLeft(String[] data, String add) {
		String[] temp = new String[data.length];
		for (int i = 0; i < data.length-1; i++) {
			temp[i] = data[i + 1];
		}
		temp[data.length - 1] = add;
		return temp;
	}

	private String[] shiftRight(String[] data, String add) {
		String[] temp = new String[data.length];
		for (int i = 1; i < data.length; i++) {
			temp[i] = data[i - 1];
		}
		temp[0] = add;
		return temp;
	}

PHP[modifica | modifica wikitesto]

Trasposizione dell'algoritmo Java in PHP.

 <?php

function AlgoritmoDiBerger($arrSquadre)
 {
 
    $numero_squadre = count($arrSquadre);
    if ($numero_squadre % 2 == 1) {
    	    $arrSquadre[]="BYE";   // numero giocatori dispari? aggiungere un riposo (BYE)!
    	    $numero_squadre++;
    }
    $giornate = $numero_squadre - 1;
    /* crea gli array per le due liste in casa e fuori */
    for ($i = 0; $i < $numero_squadre /2; $i++) 
    {
        $casa[$i] = $arrSquadre[$i]; 
        $trasferta[$i] = $arrSquadre[$numero_squadre - 1 - $i];

        
    }
 
    for ($i = 0; $i < $giornate; $i++) 
    {
        /* stampa le partite di questa giornata */
        echo '<BR>'.($i+1).'a Giornata<BR>';
 
        /* alterna le partite in casa e fuori */
        if (($i % 2) == 0) 
        {
            for ($j = 0; $j < $numero_squadre /2 ; $j++)
            {
                 echo ' '.$trasferta[$j].' - '.$casa[$j].'<BR>';
            }
        }
        else 
        {
            for ($j = 0; $j < $numero_squadre /2 ; $j++) 
            {
                 echo ' '.$casa[$j].' - '.$trasferta[$j].'<BR>';
            }
                 
        }
 
        // Ruota in gli elementi delle liste, tenendo fisso il primo elemento
        // Salva l'elemento fisso
        $pivot = $casa[0];
 
        /* sposta in avanti gli elementi di "trasferta" inserendo 
           all'inizio l'elemento casa[1] e salva l'elemento uscente in "riporto" */
        array_unshift($trasferta, $casa[1]);
        $riporto = array_pop($trasferta);
               
 
        /* sposta a sinistra gli elementi di "casa" inserendo all'ultimo 
           posto l'elemento "riporto" */
        array_shift($casa);
        array_push($casa, $riporto);
 
        // ripristina l'elemento fisso
        $casa[0] = $pivot ;
    } 
} 
?>

JavaScript[modifica | modifica wikitesto]

Trasposizione dell'algoritmo Java in JavaScript.

 <script>

function AlgoritmoDiBerger(arrSquadre)
{
    // Aggiunta di una "squadra" di comodo se sono dispari 
    (arrSquadre.length % 2 ) && arrSquadre.push('Riposo');
 
    for (var i = 0; i < arrSquadre.length - 1; i++) {
        
        document.write("<h1>" + (i+1) + "a Giornata</h1>\n");
        
        for (var j = 0; j < arrSquadre.length/2 ; j++) {

            // alterna le partite in casa e fuori
            document.write(
            (i % 2) ?
                arrSquadre[arrSquadre.length -j -1] + ' - ' + arrSquadre[j] + "\n" :
                arrSquadre[j] + ' - ' + arrSquadre[arrSquadre.length -j -1] + "\n"
                );
        }
        
        // Ultima squadra viene inserita nella posizione 1
        arrSquadre.splice(1,0,arrSquadre.pop());
    } 
} 
</script>

Note[modifica | modifica wikitesto]

  1. ^ Con "n=n−1".

Voci correlate[modifica | modifica wikitesto]