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

Caml Discussion :

ocaml: matrice de table


Sujet :

Caml

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 63
    Points : 54
    Points
    54
    Par défaut ocaml: matrice de table
    Salut à tous,

    J'ai un soucis quand j'essaye de faire une matrice dont chaque élément serait une array:

    Je fais qqch du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    alpha = ref matrice.(a).(b).(c) in
    des opérations sur alpha
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    matrice.(a).(b).(c) <- !alpha
    Et quand je fais ça, je me rend compte que tous les éléments de la matrice finale sont les mêmes.

    Quelqu'un pourrait me donner un coup de main et m'expliquer d'où vient le problème, d'autant qu'il n'y a pas l'équivalent quand on manipule une matrice de listes.

  2. #2
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Ton problème vient très probablement d'une mauvaise initialisation de ta matrice : c'est un problème classique sur lequel beaucoup de gens qui débutent butent.

    Comment fais-tu pour créer ta matrice et l'initialiser ?
    When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 63
    Points : 54
    Points
    54
    Par défaut
    De la façon suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    let table = Array.make (longueur_c) 0 in
    let matrice = Array.make_matrix (longueur_a) (longueur_b) table in

  4. #4
    alex_pi
    Invité(e)
    Par défaut
    Montre nous (entre les balises appropriées) ton code de création de matrice, c'est là qu'est l'erreur.

    (Et pourquoi tu colles ça dans une référence ???)

  5. #5
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par Amergin Voir le message
    De la façon suivante:
    let table = Array.make (longueur_c) 0 in
    let matrice = Array.make_matrix (longueur_a) (longueur_b) table in
    Je suis trop lent :-) Le tableau "table" est donc partagé partout dans ta matrice ! Il faut que tu reparcours les deux première dimension de ta matrice en remettant un "Array.make (longueur_c) 0" dedans (en refaisant bien l'appel de fonction à chaque fois !)

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 63
    Points : 54
    Points
    54
    Par défaut
    Et je mets ça dans une référence parce que je vais faire des choses du genre

  7. #7
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par Amergin Voir le message
    Et je mets ça dans une référence parce que je vais faire des choses du genre
    alpha:=!alpha+1;
    Je ne peux pas juger n'ayant pas ton code sous les yeux, mais il y a toutes les chances que tu puisses avantageusement te passer d'une telle référence. Tu ne pourrais pas nous donner tout ton code d'un coup, soit entre balise, soit sur un truc comme http://www.rafb.net/paste/ ?

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 63
    Points : 54
    Points
    54
    Par défaut
    Citation Envoyé par alex_pi Voir le message
    Je suis trop lent :-) Le tableau "table" est donc partagé partout dans ta matrice ! Il faut que tu reparcours les deux première dimension de ta matrice en remettant un "Array.make (longueur_c) 0" dedans (en refaisant bien l'appel de fonction à chaque fois !)
    Je vois en gros l'idée mais par contre j'ai du mal à imaginer comment tu ferais ça.
    J'aurais bien vu qqch comme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     let matrice = Array.make_matrix (longueur_a) (longueur_b) in
        for a=0 to longueur_a-1
        do
          for b=0 to longueur_b-1
          do
    	  let table = Array.make_matrix (longueur_c+1) in
    	  let matrice_de_table =  matrice table in
    ...
          done;
        done;
    mais du coup ma matrice _de_table n'est définie que dans la boucle...

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    Deux méthodes (parmis d'autres) :

    1) créer une matrice de tables vides, et la remplir case par case :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    let matrice = Array.make_matrix longueur_a longueur_b [| |] in
    for a=0 to longueur_a-1 do
     for b=0 to longueur_b-1 do
      matrice.(a).(b) <- Array.make longueur_c
     done
    done
    Ainsi, j'ai initialisé chaque case de la matrice par une table vide ( [| |] ) avant de les remplir une par une, donc avec des tables "différentes".


    2) au lieu d'imaginer ça comme une matrice de tables, on peut voir ça comme une table de matrices. Il existe une fonction, Array.init, qui permet d'initialiser des tableaux avec des objets "différents" (sans copie) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    let matrice = Array.init longueur_a (fun _ -> Array.make_matric longueur_b longueur_c 0)
    Pour la culture, l'argument pris en paramètre de la fonction, que j'ignore ici en l'appelant "_", est l'indice de l'élément à initialiser. Par exemple Array.init 3 (fun i -> 2*i) renvoie [|0; 2; 4|].

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 63
    Points : 54
    Points
    54
    Par défaut
    Ok, ça fonctionne bien (j'ai repris ta première méthode bluestorm) et c'est plus raisonnable que l'horreur que je proposais.
    Merci tous .

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 63
    Points : 54
    Points
    54
    Par défaut
    Citation Envoyé par alex_pi Voir le message
    Je ne peux pas juger n'ayant pas ton code sous les yeux, mais il y a toutes les chances que tu puisses avantageusement te passer d'une telle référence. Tu ne pourrais pas nous donner tout ton code d'un coup, soit entre balise, soit sur un truc comme http://www.rafb.net/paste/ ?
    Au passage, je te donne une version un peu résumée du code si tu veux me donner ton avis dessus alex_pi, mais attention les yeux ce n'est pas du grand caml ...

    tete renvoie le premier élément d'une liste,
    queue renvoie tous les éléments d'une liste sauf le premier
    graphe_bip et graphe_inverse sont des tables de listes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
     
    let distrib_triplet graphe_bip graphe_inverse =
     
      let long = Array.length graphe_bip in
      let long_inverse = Array.length graphe_inverse in
      let long_deg_even = 10 in
      let long_deg_acteur = 10 in
     
      let matrice_distribution_eae  = Array.make_matrix 10 10 ([||]) in
        for a=0 to 9
        do
          for b=0 to 9
          do
    	begin
    	  matrice_distribution.(a).(b) <- Array.make 10 0;
    	end
          done;
        done;
     
      let even = ref [] in
      let acteur = ref [] in
      let id_acteur = ref 0 in
      let id_even = ref 0 in
      let connec_even = ref 0 in
      let connec_acteur = ref 0 in
      let connec_even_bis = ref 0 in
      let nombre = ref 0 in
     
        for i=0 to long-1
        do
          begin
    	even := graphe_bip.(i);
    	connec_even := List.length !even;
    	while !even <> []
    	do
    	  begin
    	    id_acteur := tete !even;
    	    connec_acteur := List.length (graphe_inverse.(!id_acteur));
    	    acteur := (graphe_inverse.(!id_acteur));
    	    while !acteur <> []
    	    do 
    	      begin
    		id_even := tete !acteur;
    		if (!id_even > i) then
    		  begin
    		    connec_even_bis := List.length (graphe_bip.(!id_even));
    		    nombre := (matrice_distribution_eae.(!connec_even).(!connec_acteur).(!connec_even_bis));
    		    nombre := !nombre +1;
    		    matrice_distribution.(!connec_even).(!connec_acteur).(!connec_even_bis) <- !nombre;
    		  end;
    		acteur := queue !acteur;
    	      end;
    	    done;
    	    even := queue !even;
    	  end
    	done;
          end
        done;
        matrice_distribution;;

  12. #12
    alex_pi
    Invité(e)
    Par défaut
    Je suis désolé, mais je ne comprends *rien* à ton code... Simplement, ce que l'on peut dire, c'est que tu ne fais pas dutout du Caml... Je te rappelle que Caml est un langage fonctionnel, qui manipule donc des fonctions, et tu n'en définis pas une seule. C'est déjà mal parti. Ensuite tu nous fais tout un bloc de définition de références. La aussi, aïe.

    Bon après pour le parcours de matrice, j'admets que c'est plutôt normal de faire ça par boucle for plutôt qu'à coup de récursion pas forcément naturelle. Mais vu que je ne comprends globalement rien au code, je ne saurais pas dire s'il ne serait pas plus simple de définir une fonction iteri pour parcourir toute une matrice.

    Comment as-tu appris Caml ? Viens tu de la programmation impérative (là je suis pret à parier que oui :-)). C'est difficile au début, mais il faudrait vraiment que tu te forces à abandonner les réflexes que tu tiens de ton utilisation d'autres langages, sinon tu ne vas rien gagner à être passé à Caml, mis à part une syntaxe lourde.

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 63
    Points : 54
    Points
    54
    Par défaut
    Citation Envoyé par alex_pi Voir le message
    Je suis désolé, mais je ne comprends *rien* à ton code... Simplement, ce que l'on peut dire, c'est que tu ne fais pas dutout du Caml... Je te rappelle que Caml est un langage fonctionnel, qui manipule donc des fonctions, et tu n'en définis pas une seule. C'est déjà mal parti. Ensuite tu nous fais tout un bloc de définition de références. La aussi, aïe.

    Bon après pour le parcours de matrice, j'admets que c'est plutôt normal de faire ça par boucle for plutôt qu'à coup de récursion pas forcément naturelle. Mais vu que je ne comprends globalement rien au code, je ne saurais pas dire s'il ne serait pas plus simple de définir une fonction iteri pour parcourir toute une matrice.

    Comment as-tu appris Caml ? Viens tu de la programmation impérative (là je suis pret à parier que oui :-)). C'est difficile au début, mais il faudrait vraiment que tu te forces à abandonner les réflexes que tu tiens de ton utilisation d'autres langages, sinon tu ne vas rien gagner à être passé à Caml, mis à part une syntaxe lourde.
    Bon...

    J'aurais peut-être du m'expliquer sur le but du code:

    on travaille sur un graphe avec deux types de noeuds (acteur/evenement),
    dans graphe_bip chaque ligne est un événement et on met dedans la liste des id des acteurs qui lui sont liés
    dans graphe_inverse, c'est le même graphe mais chaque ligne est un acteur et on met dedans les id des événements qui lui sont liés

    un noeud, acteur ou événement, a une certaine propriété (sa connectivité) qui correspond au nombre de noeuds auxquels le noeud est connecté

    ce que l'on souhaite faire, c'est dénombrer les triplets de connectivité du graphe, par exemple je veux pouvoir dire qu'il y a 10 triplets de la forme 2-3-4 avec
    2 la connectivité d'un événement A
    3 d'un acteur B
    4 d'un autre événement C
    (il faut qu'on trouve la chaîne A-B-C dans le graphe)

    Et donc dans la matrice que l'on produit:
    en ligne la connectivité de l'événement 1
    en colonne la connectivité de l'acteur
    dans la table la connectivité de l'événement 2
    alors matrice.(2).(3).(4) = 10 avec l'exemple de tout à l'heure

    Voilà, je ne sais pas si c'est bien plus clair...

    Et pour répondre à ta question, même si j'utilise quelques fonctions dans ce code (tete, queue), je ne suis effectivement pas familier avec les langages fonctionnels et je me suis (mal) formé complétement sur le tas au Caml.
    Donc si tu as des conseils sur un bon tutoriel de Caml bien propre ou autre chose, you are wellcome...

  14. #14
    Membre régulier
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Points : 84
    Points
    84
    Par défaut
    tuto que j'ai trouvé facile d'accès pour débuter :

    http://damien-guichard.developpez.com/tutoriels/ocaml/

    L'auteur fréquente ce forum ... il y a un post que tu peux faire remonter pour engager la conversation : [Vos questions] suscitées par le tutoriel "L'approche qualité avec Objective-Caml"

    Avec ça tu dois pouvoir bien avancer, comme moi : j'ai découvert le fonctionnel il y a peu et je trouve cela fantastique, je croyais que l'inférence de type était un gadget et je découvre que c'est une aide infiniment précieuse ...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] Matrice ou Table Multi-Dimension
    Par JetLibre dans le forum VB.NET
    Réponses: 16
    Dernier message: 17/04/2013, 22h29
  2. [ocaml] Récupérer matrice de pixels d'une image
    Par tagazok dans le forum Caml
    Réponses: 3
    Dernier message: 04/01/2010, 18h00
  3. Transformation matrice / table
    Par spirou33 dans le forum Access
    Réponses: 6
    Dernier message: 25/10/2007, 16h28
  4. Réponses: 3
    Dernier message: 17/07/2007, 10h15
  5. Réponses: 8
    Dernier message: 16/04/2007, 16h10

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