IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

[Tableaux] Algorithme de simultanéité


Sujet :

Langage PHP

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 56
    Points : 21
    Points
    21
    Par défaut [Tableaux] Algorithme de simultanéité
    Bonjour à tous,


    Je dispose d'une base de données qui contient grosso modo 3 informations primordiales...

    Adresse IP, Heure de connexion, Heure de déconnexion.

    En fait, j'aurai besoin de faire un découpage par heure et d'afficher un "pique". En gros, indiquer par heure combien il y a eu d'IP différente EN MEME TEMPS.
    Je ne vois pas trop comment établir mon algorithme afin qu'il soit pas trop long à s'exécuter. En effet, l'algorithme pourra rencontrer plusieurs milliers de lignes et du coup, il ne faudrait pas qu'il soit trop trop long à s'exécuter. J'ai bien eu l'idée de parcours chaque minute de l'heure et pour chacune de ces minutes de voir quelle IP était "présente" et de ne conserver que le max de ce parcours. Mais c'est relativement lourd.


    Comment procéderiez-vous ? J'espère que j'ai exposé assez clairement mon problème

  2. #2
    Membre confirmé Avatar de papyphp
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    438
    Détails du profil
    Informations personnelles :
    Âge : 73
    Localisation : Belgique

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 438
    Points : 587
    Points
    587
    Par défaut
    Bonjour et bienvenue sur ce forum,

    plutot que de le faire par minute je le ferais par heure

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $max=0;
    for ($i=0; $i<24; $i++)
    {
      $req='select distinct ip from table where heure_de connection > $i and heure_de_connection < ($i+1)';
      $res=mysql_query($req);
      $nb=mysql_num_rows($res);
      if ($max<$nb)
        $max=$nb;
    }
    Dans la boucle, il faut transformer $i en heure
    Il y a de cette façon 24 requêtes à effectuer
    Lu kinze d' awousse, la Vierje arandje û dusbrôle lu timp.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 56
    Points : 21
    Points
    21
    Par défaut
    Bonsoir et merci de ta réponse si rapide.

    Ton algo ne correspond pas. En fait, il va me donner uniquement le nombre d'ip différentes que j'ai eu pendant une même heure.

    Or moi, ce que j'aimerais obtenir, c'est pas le max d'auditeurs dans l'heure, mais le max d'auditeurs qui était présent à un même moment dans l'heure !!!

    PS : Je précise que mes formats heures sont HH:mm:ss

  4. #4
    Membre confirmé Avatar de papyphp
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    438
    Détails du profil
    Informations personnelles :
    Âge : 73
    Localisation : Belgique

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 438
    Points : 587
    Points
    587
    Par défaut
    Je ne suis pas top top en mysql mais regarde du coté de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select distinct ip count(*) from table group by extract(hour_minute from heure_connection)
    Je ne suis pas certain qu'on puisse faire un 'count' sur un select distinct ni un 'group by' sur une expression
    Lu kinze d' awousse, la Vierje arandje û dusbrôle lu timp.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 56
    Points : 21
    Points
    21
    Par défaut
    Bonsoir et merci à toi.

    Je crains que ta solution ne soit pas non plus la bonne.
    En effet, la personne qui s'est connecté à 14h30 et qui est parti à 14h45 était aussi présente à 14h31 14h32 14h33 14h34 etc.... jusqu'à 14h45 !!

    Du coup ton exemple qui extrait les minutes des horaires présents dans ma table ne va tester que 14h30 et 14h45 et pas ceux compris entre ces deux là....

  6. #6
    Membre confirmé Avatar de papyphp
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    438
    Détails du profil
    Informations personnelles :
    Âge : 73
    Localisation : Belgique

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 438
    Points : 587
    Points
    587
    Par défaut
    Exact,

    Très bourrin

    Tu crée un tableau dont les clefs sont des string '00:00', '00:01', '00:02', ... '23:59'
    en gros 1440 lignes
    Chaque cellule est mise à zero
    tu lis chaque enregistrement
    Tu calcules le nombre de minutes de connection (nb)
    tu transformes l'heure de connection en un string ('12:54')
    tu incrémentes la case du tableau correspondante (tab['12:54']++) et les (nb-1) cases suivantes
    tu ordonne le tableau
    Lu kinze d' awousse, la Vierje arandje û dusbrôle lu timp.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 56
    Points : 21
    Points
    21
    Par défaut
    Merci pour ta nouvelle réponse

    Effectivement, c plutôt bourrin. Surtout quand on sait que je gère également les secondes !!!! Du coup, c + de 1440 lignes que j'aurai !

    A savoir également que cet algo, en temps normal, devra gérer + d'une journée ;-) Mais si j'arrive déjà à gérer une seule journée, je m'occuperai du reste après.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 56
    Points : 21
    Points
    21
    Par défaut
    Pour répondre à mon propre message, on m'a apporté une solution relativement satisfaisante :

    Je construis un tableau comme suit :
    champ1| champ2
    14h30 | connexion
    14h35 | déconnexion
    14h32 | connexion
    14h34 | déconnexion
    14h36 | connexion
    14h44 | déconnexion
    14h37 | connexion
    15h00 | déconnexion

    Ensuite, je trie ce tableau:
    14h30 | connexion
    14h32 | connexion
    14h34 | déconnexion
    14h35 | déconnexion
    14h36 | connexion
    14h37 | connexion
    14h44 | déconnexion
    15h00 | déconnexion


    Enfin, je parcours ce tableau et je fais des inserts dans une table temporaire:
    int i = 0;
    pour chaque ligne de la map {
    if (champ2='connexion'){
    i++;
    insert into table_stats(champ1,i)
    }
    else { //donc 'déconnexion'
    i--;
    insert into table_stats(champ1,i)

    }
    }
    et j'obtiens :
    14h30 | 1
    14h32 | 2
    14h34 | 1
    14h35 | 0
    14h36 | 1
    14h37 | 2
    14h44 | 1
    15h00 | 0

    Du coup, maintenant, je suis capable de dégager le max présent dans cette table et le début de la période où ce max a été atteint.

  9. #9
    Membre confirmé Avatar de papyphp
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    438
    Détails du profil
    Informations personnelles :
    Âge : 73
    Localisation : Belgique

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 438
    Points : 587
    Points
    587
    Par défaut
    Très intéressant

    fais attention au point suivant

    $tableau['12h30']='connection';

    risque de poser un problème de clef : si plusieurs personnes se connectent à 12h30 il n'y aura qu'une ligne avec 'connection' pour la clef '12h30'

    de même si une personne se connecte et une autre se déconnecte à 12h30 tu aura soit 'connection' soit 'déconnection' en fonction de l'enregistrement qui sera lu en dernier

    donc tu lis ta table si $tableau['12h30'] existe et si connection incrémentation de $tableau si déconnection décrémentation de $tableau

    champ1| champ2
    14h30 | +1
    14h35 | -1
    14h32 | +2
    14h34 | -1
    14h36 |+3
    14h44 | -1
    14h37 | -2
    15h00 | -1

    tu tries
    champ1| champ2
    14h30 | +1
    14h32 | +2
    14h34 | -1
    14h35 | -1
    14h36 | +3
    14h37 | -2
    14h44 | -1
    15h00 | -1

    puis

    Enfin, je parcours ce tableau et je fais des inserts dans une table temporaire:
    int i = 0;
    pour chaque ligne de la map {
    i+=champ2;
    insert into table_stats(champ1,i)
    }

    et j'obtiens :
    14h30 | 1
    14h32 | 3
    14h34 | 2
    14h35 | 1
    14h36 | 4
    14h37 | 2
    14h44 | 1
    15h00 | 0

    Qu'en penses-tu ?
    Lu kinze d' awousse, la Vierje arandje û dusbrôle lu timp.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 56
    Points : 21
    Points
    21
    Par défaut
    En fait, je ne pense pas avoir un problème.

    Tout d'abord, je gère tout ça à l'aide de tableau, et non de table. Du coup, aucun problème de clés à priori (redondance autorisé genre 12h30 'connexion' et 12h30 'deconnexion').

    De plus, je manipule les formats heure sous un format HH:mm:ss . Du coup, il est peu probable (pas impossible certes, mais extrêmement rare) que deux personnes se connectent exactement à la même seconde.

    Donc je pourrais avoir 12:30:10 'connexion' et 12:30:11 'connexion'. De même, ma table initiale où je lis toutes mes infos, disposent d'un 3e champ qui compose et termine ma clé composé. Du coup, il est tout à fait possible d'obtenir dans mon tableau deux lignes identiques... qui me feront bien comptabilisé au final le bon nombre de connexion....

  11. #11
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Points : 29 985
    Points
    29 985
    Par défaut
    Salut

    Peut-être peux-tu essayer quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT
       COUNT(*),
       DATE_FORMAT(FROM_UNIXTIME(`session_start`), '%H') AS debut_session,
       DATE_FORMAT(FROM_UNIXTIME(`session_time`), '%H') AS fin_session
    FROM `ta_table`
    GROUP BY session_ip
    HAVING (debut_session - fin_session) > 1
    Je l'ai testé avec mon forum à l'instant, ça a l'air de fonctionner.
    Je suis parti du principe que tu as tes heures au format timestamp et qu'elles sont stockées en int.

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 56
    Points : 21
    Points
    21
    Par défaut
    Je ne comprends pas très bien ta requête....

    Tu pars de l'heure de connexion, et de l'heure de déconnexion (apparamment tu n'en conserves que les heures - %H - et non les minutes)
    et tu exécutes une différence entre la première et la deuxième.

    J'ai beau relire ta requête, je ne la comprends pas
    comment une différence entre une date antérieure à une autre peut-elle être supérieure à 1 ?
    Et pourquoi le group by session_ip ?

  13. #13
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Points : 29 985
    Points
    29 985
    Par défaut
    Oh, si tu veux les minutes, prends %i à la place de %H.
    Tu peux faire d'autres comparaisons dans le HAVING, comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    HAVING (fin_session - debut_session) >= 30
       AND (fin_session - debut_session) <= 50
    Cela te donnerait les membres restés entre 30 et 50 minutes.
    Tu as raison, j'ai inversé ma comparaison tout à l'heure.
    Il se trouve que je ne sais pas vraiment avec quels champs j'ai fait mes tests tout à l'heure :/

    Le GROUP BY permet de traiter les IP identiques (correspondant aux critères du SELECT) comme un groupe, ce qui nous permet ensuite de faire un COUNT du nombre d'éléments qu'il y a dans ce groupe.
    Souci : je ne sais pas exactement ce qu'il se passe pour les utilisateurs s'étant déconnectés puis reconnectés (ayant changé de session) dans l'intervalle de temps spécifié dans le HAVING. Peut-être faut-il effectuer un traitement ultérieur...


    PS : Je peux être complètement parti en vrille, c'est tout à fait possible...


    [Edit] Ah, j'ai oublié l'aspect "par heure"... Je m'étais orienté dans une mauvaise direction.
    Peu-être qu'une boucle et un WHERE pourraient régler ce manque ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT
       COUNT(*) AS total,
       DATE_FORMAT(FROM_UNIXTIME(`session_start`), '%i') AS debut_session,
       DATE_FORMAT(FROM_UNIXTIME(`session_time`), '%i') AS fin_session
    FROM `phpbb_rnz_sessions`
    WHERE DATE_FORMAT(FROM_UNIXTIME(`session_start`), '%H') = $i
    GROUP BY session_ip
    HAVING (fin_session - debut_session) > 30

    [Edit bis] Si tu souhaites uniquement le maxi, tu peux ajouter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ORDER BY total DESC
    LIMIT 1
    ...

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 56
    Points : 21
    Points
    21
    Par défaut
    Bonjour,

    Ta requête est intéressante car, développant un outil de "stats", elle me permettra d'ajouter une fonction "nombre de connecté étant resté xxx minutes".

    Cependant, si je ne m'abuse, ta dernière requête ne remplit toujours pas mon besoin initiale.

    A sa lecture, je dirais que, à partir d'un paramètre correspondant à l'heure désirée, tu me listes toutes les personnes qui sont restées connectés plus de 30 minutes.
    Ceci est très bien, mais moi, je recherche la "simultanéité". Je veux le maximum du nombre de personnes qui ont été connecté en même temps !
    Il faut pouvoir comparer les périodes de connexion de chacun pour voir lesquelles se chevauchent, toutes les calculer, et ressortir le plus grand nombre trouver.

    Perso, je pense que la solution php que j'ai donné plus haut est la bonne (ou l'une des bonnes solutions si y en a d'autres), mais qu'en mySQL pur, ça risque de ne pas être possible....

Discussions similaires

  1. [Tableaux] Algorithme pour les combinaisons
    Par Death83 dans le forum Langage
    Réponses: 33
    Dernier message: 09/08/2010, 14h31
  2. Fusion des tableaux algorithme
    Par KnightofEmpire dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 22/11/2008, 12h39
  3. [Algorithme] Sèche sur un sujet Tableaux/Collections
    Par Vash_vador dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 08/03/2008, 16h13
  4. [Tableaux] Aide pour un algorithme sur les tableaux
    Par sara21 dans le forum Langage
    Réponses: 7
    Dernier message: 20/05/2007, 10h28
  5. [Tableaux] Algorithme tri de vecteurs
    Par pelloq1 dans le forum Langage
    Réponses: 3
    Dernier message: 30/01/2007, 18h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo