Visualizzazione risultati 1 fino 12 di 12

Discussione: Estrazione statistiche

  1. #1
    Guest

    Predefinito Estrazione statistiche

    Chiedo scusa per il titolo ma no trovo un modo semplice per sintetizzare la richiesta.

    La situazione è questa.
    Una competizione suddivisa in manche. Ogni manche composta da diverse prove.
    Ogni prova, se superata, assegna un numero di punti.

    Tutti questi dati sono registrati in una tabella in cui ogni rigo contiene il gareggiante, il numero della manche, la prova e i punti.

    Ora il problema non è la classifica ma un dato statistico.

    Mi occorre poter recuperare, per ognuno, la striscia positiva (quante manche consecutive vinte) tenendo presente che ci possono essere e ci sono casi di ex equo, e, se possibile anche la striscia massima (numero massimo di manche consecutive vinte).

    Idee? Suggerimenti?

  2. #2
    darbula non è connesso AlterGuru 2500
    Data registrazione
    24-04-2011
    Messaggi
    2,896

    Predefinito

    Cosa si intende per manche consecutive vinte? Allora ogni manche è suddivisa da x prove con y punteggi, ma se io perdo tutte le prove della prima manche avanzo ugualmente alla seconda manche?

  3. #3
    Guest

    Predefinito

    Si. Si partecipa comunque.
    Piuttosti che manche immagina delle vere e proprie partite indipendenti.

  4. #4
    Guest

    Predefinito

    La domanda è tipo: dato un torneo di calcio, quante vittorie di seguito ha fatto ogni squadra e quale è il numero massimo di vittorie di fila?

  5. #5
    darbula non è connesso AlterGuru 2500
    Data registrazione
    24-04-2011
    Messaggi
    2,896

    Predefinito

    Ancora non è chiaro.. Puoi fonire un esempio dei dati originali specificando se i punti sono totali (se passi la prova i punti vengono sommati)? Anche la tua domanda è confusa.. Se tu vuoi sapere quante manche consecutive sono state vinte ... Equivale a dire che si devono vincere tutte le prove per più di una manche... Discorso diverso se vuoi sapere chi è il primo di quella manche e della manche successiva (dato basato sui i punti totali di ogni manche e non per forza deve superare tutte le prove)
    Ultima modifica di darbula : 16-02-2017 alle ore 18.38.01

  6. #6
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,954

    Predefinito

    A scanso di equivoci: recuperare i dati dalla base di dati ed elaborarli con PHP è un'opzione, o è necessario che tutto avvenga tramite SQL?

  7. #7
    Guest

    Predefinito

    Dunque, cerco di spiegare meglio la dinamica

    Una competizione suddivisa in Manche (gare, tutte indipendenti, per cui tutti possono partecipare ad ogni manche).
    Ogni manche prevede un certo numero di giochi (uno al giorno), sempre uguale, e per ogni gioco sono previsti dei punti (diversi da gioco a gioco).

    Per cui per ogni manche si crea una classifica in base ai punti ottenuti (da 0 per gioco non valido al max previsto) e naturalmente ci possono essere più utenti "vincitori".

    Ora se io vinco la manche 1, 2, 3 e poi la 5 e la 6 ma nella 4 sarò più indietro in classifica, io avrò, all'inizio della manche 7, come striscia attuale 2(*) (5 e 6) e come striscia max 3(**) (1, 2 e 3).
    Ed è questi 2(*) e 3(**) che mi interessa trovare.

    La tabella è strutturata così (dati di esempio)

    Codice:
    +-----------+--------+-------+-------+
    | Giogatore | Manche | Giogo | Punti |
    +-----------+--------+-------+-------+
    | Utente 1  |      1 |     A |    50 |
    | Utente 2  |      1 |     A |    40 |
    | Utente 3  |      1 |     A |    30 |
    | Utente 1  |      1 |     B |    40 |
    | Utente 2  |      1 |     B |    50 |
    | Utente 3  |      1 |     B |    30 |
    | Utente 1  |      1 |     C |    40 |
    | Utente 2  |      1 |     C |    40 |
    | Utente 3  |      1 |     C |    40 |
    | Utente 1  |      2 |     D |    50 |
    | Utente 2  |      2 |     D |    30 |
    | Utente 3  |      2 |     D |    40 |
    | Utente 1  |      2 |     E |    40 |
    | Utente 2  |      2 |     E |    30 |
    | Utente 3  |      2 |     E |    50 |
    +-----------+--------+-------+-------+
    non è strettamente necessario risolvere la cosa in SQL (anche se a me farebbe molto comodo).
    Potrei cmq trattare i dati anche con PHP.

    Non so se adesso la cosa è più chiara.
    Ultima modifica di vplaza : 16-02-2017 alle ore 22.56.38

  8. #8
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,954

    Predefinito

    Mh, un'implementazione in PHP mi viene abbastanza naturale (sia n il numero di giocatrori, m il numero di manche disputate):
    • costruisco la matrice M n x m tale che M[i ][j] = punteggio del giocatore i nella manche j (facile da ottenere con una singola query SQL, usando opportunamente SUM)
    • trasformo M in una matrice booleana M' (sempre n x m) tale che M'[ i][j] = true sse il giocatore i ha vinto la manche j o, in termini più precisi: M'[ i][j] = \/0 <= k < n . M[ i][j] >= M[k][j], da notare che in questo modo vincitori a parimerito hanno tutti valore true
    • trasformo M' in M'' (sempre n x m) tale che M''[ i][j] = serie di vittore consecutive del giocatore i alla fine della manche j; concretamente la relazione è data da (\/0 <= i < n):
      • M''[ i][0] = M'[ i][0] ? 1 : 0
      • M''[ i][j + 1] = M'[ i][j + 1] ? M''[ i][j] + 1 : 0

      ogni riga può essere processata indipendentemente, per cui suggerirei l'uso di funzioni come array_map
    • alla fine, dato un giocatore i, la serie di vittorie consecutive per quel giocatore è data M''[ i][m-1], mentre la sua serie più lunga è data da max(M''[ i])

    Volendo i passi 2 e 3 si possono unire in uno solo.

    In SQL non mi è chiaro come ottenere lo stesso risultato...senza incasinare troppo l'interrogazione...

  9. #9
    Guest

    Predefinito

    Proverò.

    Non mi è chiaro però il punto 3.
    Come fai a passare da M' a M''?

  10. #10
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,954

    Predefinito

    Vediamo... le righe possono essere processate indipendentemente, quindi prendiamo una riga di M', che riporta true o false se il giocatore ha vinto/perso ciascuna manche:
    Codice PHP:
    $row = [true, true, true, false, true, true, false];
    questo vettore va trasformato in uno che riporti la serie di vittore consecutive al termine di ogni manche, quindi il risultato desiderato è:
    Codice PHP:
    $series = [1, 2, 3, 0, 1, 2, 0];
    L'idea è di scorrere il vettore, incrementando di uno ogni volta che si incontra una vittoria, ed azzerando quando si incontra una sconfitta:
    Codice PHP:
    function compute_series(array $row) {
    $series = array();

    $series[0] = $row[0] ? 1 : 0;
    for (
    $i = 1; $i < count($row); ++$i) {
    if (
    $row[$i]) {
    $series[$i] = $series[$i - 1] + 1;
    } else {
    $series[$i] = 0;
    }
    // For one-liners: $series[$i] = $row[$i] ? ($series[$i - 1] + 1) : 0;
    }

    return
    $series;
    }
    Se M' è rappresentata per righe, ad esempio:
    Codice PHP:
    $M_prime = [
    'player1' => [true, true, false, ..., false],
    'player2' => [false, false,true, ..., true],
    ...
    'playerN' => [false, true, false, ..., false]
    ]
    si può sfruttare l'indipendenza tra le righe ed usare array_map:
    Codice PHP:
    $M_second = array_map('compute_series', $M_prime);
    Se l'occupazione in memoria è un problema (O(n * m)) sono quasi sicuro si possa trasformare in una versione con programmazione dinamica (O(n)).

  11. #11
    Guest

    Predefinito

    Grazie.

    Vedo cosa riesco a fare.

  12. #12
    darbula non è connesso AlterGuru 2500
    Data registrazione
    24-04-2011
    Messaggi
    2,896

    Predefinito

    Se si possiede privilegi nel server MySQL è la stringa di tutti i Punti (non supera tot lunghezza) si poteva pensare a GROUP_CONCAT.. Cmq. Vogliamo ottere le manche consecutive, quindi dal momento che le Manche non sono uguali per tutti i giocatori e che la somma dei punti a zero non è di certo una vittoria.. La SQL è questa
    Codice PHP:
    SELECT Manche, SUM(Punti) tot, Giocatore FROM table GROUP BY Manche,Giocatore HAVING SUM(Manche) > 1 AND tot > 0;
    Recupero solo chi a giocato più di una Manche e che abbia un punteggio maggiore a zero.. Ps. Per una statistica generale (grafico) occorre x Manche iniziale e y Manche finale mobili... Perché in alcuni casi potremmo avere dei vincitori di singole manche ma non di Manche consecutive.

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •