Problème lecture fichier

Voir le sujet précédent Voir le sujet suivant Aller en bas

Problème lecture fichier

Message  pascal le Ven 4 Mar 2011 - 3:21

Bonjour,


Je mène un projet sur la résolution du problème m voyageur de commerce.

Voilà, en premier lieu je cherche à parcourir les données dans un fichier qui a la forme suivante pour calculer la distance entre les villes et la sauvegarder dans un fichier. Toutesfois, ça ne se compile pas.

Pourriez-vous m'aider SVP?
Merci.
Code:
NAME: n100mosA.tsp, 100 nodes, semilla 0
COMMENT: Problema
DIMENSION: 101
CAPACITY: 218
EDGE_WEIGHT_TYPE: EUC_2D
NODE_COORD_SECTION
1 0.0000 0.0000
2 220.0000 -461.0000
3 -62.0000 -261.0000
4 298.0000 356.0000
5 -214.0000 -134.0000
6 113.0000 -49.0000
7 -399.0000 354.0000
.
.
101 234.000 346.000
DISPLAY_DATA_SECTION:
1 250 250
2 360 19
3 219 119
4 399 428
5 143 183
6 306 225
7 50 427
8 141 71
9 461 269
10 143 473
11 340 499
12 446 488
13 453 328
14 162 229
15 120 441
16 139 363
17 295 223
.
101 223 -234
DEMAND_SECTION
1 -214
2 7
3 9
4 -1
5 9
6 0
7 4
8 1
9 -5
10 0
11 -1
...
101 2
EOF
 
Je cherche à remplir les élements de ma structure par les données trouvées dans le fichier.
Là, je commence à lire le NODE_COORD_SECTION dans le fichier puis commencer le remplissage de ma variable de type struct
Voici le bout de code que j'ai réalisé. Toutefois, ca se plante Crying or Very sad
Des corrections?
Merci.
Code:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
 
 
 
int main ()
{
   
   struct ville                        /*definition d'un type structure nommé ville*/
   {
      int identifiant;
      double abscisse;
      double ordonnee;
                                 
            
   };
   struct    ville Ville[101];            /* variable de type structure ville*/
   double ** distance_entre_ville;         /*distance euclidiene entre les ville*/
      
   int i, j;
   int n = 101;
   int k = 101;
   
   /*ouverture du fichier de données pour lecture*/
   
   FILE * fichier;
   
   fichier = fopen("D:\\Codes \\TS2004t3\\n100mosA.tsp", "r");
   
   if(fichier == NULL)
   {
      printf("Impossible d'ouvrir fichier .tsp \n");
      exit (-1);
   }
   
   
   /*on commence à lire à la ligne 6: NODE_COORD_SECTION
   */
   for(i=0;i<6;i++)   
   
   while(fgetc(fichier)!='\n');
   for(i=0;i<k;i++)
   
      if (fscanf(fichier, "%d %lf %lf", &(Ville[i].identifiant), &(Ville[i].abscisse), &(Ville[i].ordonnee)) !=3)
      {
         printf("Erreur dans le format d'une ligne : ligne %d.\n", i);
                  exit(-1);
      }
   
   
   /*Allocation dynamique du tableau distance*/
      distance_entre_ville = (double ** ) malloc (k * sizeof (double));
      
   for (i=0;i<k;i++)
   {
 
      distance_entre_ville[i]=(double *)malloc(n * sizeof(double));
   }
      
 
   /*calcul distance*/
    for(i=0;i<k;i++)
   {
   for(j=0;j<i+1;j++)
   {
      if(i==j)
      {
         distance_entre_ville[i][j]= 0.0;
         
         distance_entre_ville[i][j]= distance_entre_ville[j][i] =  sqrt(pow((Ville[i].abscisse - Ville[j].abscisse),2.0)+pow((Ville[i].ordonnee - Ville[j].ordonnee),2.0));
      }
   }
   /*recopie contenu de la matrice distance entre les villes dans le fichier file*/
      
   
   FILE * file;
   
   file = fopen("D:\\Codes\\TS2004t3\\Distance_entre_ville.txt", "w");
   
   if(file == NULL)
   {
      printf("Impossible d'ouvrir fichier .txt \n");
      exit (-1);
   }
   for (i=0; i<k; i++)
   {
      for (j=0; j<n; j++)
      {
         fprintf(file, "%101lf",distance_entre_ville[i][j]);
            
      }
      fprintf (file, "\n" );
 
   }
 
      
   /*affichage matrice distance*/
   for(i=0;i<n;i++)
   {
      for(j=0;j<k;j++)
      {
         
         printf("Distance[%i][%i]= %lf \n",i, j, distance_entre_ville[i][j]);
      }
   }
      
    for(i=0;i<k;i++)
      free(distance_entre_ville[i]);
    free(distance_entre_ville);
   /*femeture fichiers*/
   fclose(fichier);
   fclose(file);
   
   getchar();
 
   
   return 0;
}
 

pascal
Bavard
Bavard

Messages : 20
Date d'inscription : 20/08/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  -ed- le Dim 6 Mar 2011 - 5:01

La parenthèse ouverte en ligne 64 n'est jamais fermée ...

Après correction, le programme indique "erreur ligne 7".

Peut être un problème de codage des nombres décimaux. En français, le séparateur est la ',' et non le '.'.


_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  pascal le Dim 6 Mar 2011 - 15:04

Merci de votre réponse.
La parenthèse ouverte en ligne 64 n'est jamais fermée ...

C'est réglé.
Merci beaucoup
Voilà mon nouveau programme. Toutefois, les résultats affichés sont bizarres. Sur l'écran, il m' affiche les élements de la matrice distance_entre_ville à partir de la ligne 98 colone 1 (
Code:
distance-entre_ville[98][1]=...
) et non pas l'élement de la matrice distance[0][0] alors que le fichier de sortie contient tous les élements (enfin je crois, j'ai 101 villes). C'est du à quoi cette contradiction entre les résultats afiichés et les résultats sauvegardés?
Des corrections??
Code:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

struct ville                        /*definition d'un type structure nommé ville*/
   {
      int identifiant;
      double abscisse;
      double ordonnee;
      int demande;                     /*demande du ville*/
      int capacite;

   };

int main ()
{
   struct    ville Ville[101];            /* variable de type structure ville*/
   double ** distance_entre_ville;         /*distance euclidiene entre les ville*/

   int i, j;
   int n = 101;
   int k = 101;

   /*ouverture du fichier de données pour lecture*/

   FILE * fichier;
   fichier = fopen("D:\\Codes\\TS2004t3\\n100mos.txt", "r");

   if(fichier == NULL)
   {
      printf("Impossible d'ouvrir fichier .txt \n");
      exit (-1);
   }


   /*on commence à lire à la ligne 6: NODE_COORD_SECTION
   */
   for(i=0;i<6;i++)

   while(fgetc(fichier)!='\n');
   for(i=0;i<k;i++)

      if (fscanf(fichier, "%d %lf %lf", &(Ville[i].identifiant), &(Ville[i].abscisse), &(Ville[i].ordonnee)) !=3)
      {
         printf("Erreur dans le format d'une ligne : ligne %d.\n", i);
            exit(-1);
      }


   /*Allocation dynamique du tableau distance*/
      distance_entre_ville = (double ** ) malloc (k * sizeof (double));

   for (i=0;i<k;i++)
   {

      distance_entre_ville[i]=(double *)malloc(n * sizeof(double));
   }


   /*calcul distance*/

    for(i=0;i<k;i++)
   {
      for(j=0;j<i+1;j++)
      {
         if(i==j)
         {
         distance_entre_ville[i][i]= 0.0;
         }

         distance_entre_ville[i][j]= distance_entre_ville[j][i] =  sqrt(pow((Ville[i].abscisse - Ville[j].abscisse),2.0)+pow((Ville[i].ordonnee - Ville[j].ordonnee),2.0));

      }
   }

   /*afficher sur l'écran da matrice distance_entre_ville*/
    for (i=0; i<k; i++)
   {
      for (j=0; j<i+1; j++)
      {
         printf("distance_entre_ville[%i][%i]= %lf\n",i, j, distance_entre_ville[i][j]);

      }

   }

    /*recopie contenu de la matrice distance entre les villes dans le fichier file*/
    FILE * sortie;
   sortie = fopen("D:\\Codes \\TS2004t3\\Distance_entre_ville.txt", "w");

   if(sortie == NULL)
   {
      printf("Impossible d'ouvrir fichier .txt \n");
      exit (-1);
   }
   for (i=0; i<k; i++)
   {
      for (j=0; j<i+1; j++)
      {
         fprintf(sortie, "%lf\n",distance_entre_ville[i][j]);

      }
      fprintf (sortie, "\n" );

   }

   /*déliberer mémoire*/

   for(i=0;i<k;i++)
      free(distance_entre_ville[i]);
    free(distance_entre_ville);

   /*femeture fichiers*/
   fclose(fichier);
   fclose(sortie);


   getchar();


   return 0;
}


Dernière édition par pascal le Dim 6 Mar 2011 - 16:34, édité 1 fois

pascal
Bavard
Bavard

Messages : 20
Date d'inscription : 20/08/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  -ed- le Dim 6 Mar 2011 - 16:30

Le fichier de données a changé de nom. A-t-il changé de contenu ?

_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  pascal le Dim 6 Mar 2011 - 16:37

-ed- a écrit:Le fichier de données a changé de nom. A-t-il changé de contenu ?
Il y a une contradiction entre les résultats affichés et les résultats sauvegardés dans le fichier sortie. Sur l'écran, il m' affiche les élements de la matrice distance_entre_ville à partir de la ligne 98 colone 1
Code:
distance-entre_ville[98][1]=...
et non pas l'élement de la matrice distance[0][0] alors que le fichier de sortie contient tous les élements (enfin je crois, j'ai 101 villes). C'est du à quoi cette contradiction ?
Des corrections??
Merci.

pascal
Bavard
Bavard

Messages : 20
Date d'inscription : 20/08/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  -ed- le Dim 6 Mar 2011 - 16:40

Je voudrais la dernière version du fichier de données. Avec celui que tu as posté hier, j'obtiens :
Code:
Erreur dans le format d'une ligne : ligne 7.

Process returned -1 (0xFFFFFFFF)  execution time : 0.107 s
Press any key to continue.

EDIT : je parle bien sûr du fichier d'entrée (celui qui est lu et qui s'appelait hier "n100mosA.tsp".

_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  pascal le Dim 6 Mar 2011 - 16:50

-ed- a écrit:Je voudrais la dernière version du fichier de données. Avec celui que tu as posté hier, j'obtiens :
Code:
Erreur dans le format d'une ligne : ligne 7.

Process returned -1 (0xFFFFFFFF)  execution time : 0.107 s
Press any key to continue.
Au fait, j'ai juste mis un exemple de la forme de données dans mon fichier. Toutefois, je poste les données de mon fichier. Le voici
Code:

NAME: n100mosA.tsp, 100 nodes, semilla 0
COMMENT: Problema de Mosheiov aleatorio de norma euclidea con depot en (0,0)
DIMENSION: 101
CAPACITY: 218
EDGE_WEIGHT_TYPE: EUC_2D
NODE_COORD_SECTION
1  0.0000  0.0000
2 220.0000 -461.0000
3 -62.0000 -261.0000
4 298.0000 356.0000
5 -214.0000 -134.0000
6 113.0000 -49.0000
7 -399.0000 354.0000
8 -218.0000 -357.0000
9 422.0000  38.0000
10 -214.0000 446.0000
11 181.0000 498.0000
12 392.0000 477.0000
13 407.0000 156.0000
14 -176.0000 -42.0000
15 -259.0000 382.0000
16 -221.0000 226.0000
17  91.0000 -53.0000
18  88.0000 341.0000
19 -262.0000 408.0000
20 118.0000 112.0000
21 368.0000 -43.0000
22 379.0000  34.0000
23 388.0000 -276.0000
24  85.0000  98.0000
25 -388.0000 -287.0000
26 -433.0000  79.0000
27 -95.0000 130.0000
28  6.0000 -220.0000
29 150.0000 -111.0000
30 -323.0000 -170.0000
31 -235.0000 -168.0000
32 -363.0000 -385.0000
33 -397.0000 429.0000
34 -95.0000 153.0000
35 357.0000 -162.0000
36 273.0000  99.0000
37 -286.0000 -402.0000
38 204.0000 184.0000
39 443.0000 -239.0000
40 -124.0000 248.0000
41 -495.0000 372.0000
42 -347.0000 174.0000
43  5.0000 320.0000
44 -313.0000 -260.0000
45 438.0000 305.0000
46 -164.0000 -476.0000
47 -106.0000  34.0000
48  75.0000 -479.0000
49 462.0000 484.0000
50 -434.0000 125.0000
51 331.0000  70.0000
52 -263.0000 -332.0000
53 137.0000 -250.0000
54 228.0000 120.0000
55 -176.0000 201.0000
56 275.0000 423.0000
57 -437.0000 312.0000
58 -308.0000  66.0000
59 248.0000 -380.0000
60 121.0000 -449.0000
61 469.0000 -165.0000
62  78.0000  25.0000
63  32.0000 -453.0000
64 -227.0000 -41.0000
65 -365.0000  31.0000
66 -64.0000  82.0000
67 -339.0000 168.0000
68 143.0000 315.0000
69  28.0000 477.0000
70 -405.0000 324.0000
71 -255.0000 269.0000
72 -478.0000 325.0000
73 -203.0000 308.0000
74 -236.0000 227.0000
75 -437.0000 141.0000
76 -419.0000 -452.0000
77 -171.0000 248.0000
78 -316.0000 -386.0000
79 244.0000 260.0000
80  -5.0000 392.0000
81 -366.0000 -138.0000
82 152.0000  73.0000
83 -29.0000 -245.0000
84 475.0000 -480.0000
85 323.0000 322.0000
86 -47.0000 411.0000
87 -343.0000 -251.0000
88 -24.0000 412.0000
89 220.0000 -63.0000
90 -244.0000 -111.0000
91 341.0000 -52.0000
92  -6.0000 355.0000
93 342.0000 256.0000
94 -332.0000 -295.0000
95  57.0000 317.0000
96 428.0000 -498.0000
97  52.0000 -285.0000
98 -220.0000 -416.0000
99 347.0000 175.0000
100 300.0000 -485.0000
101  0.0000  0.0000
DISPLAY_DATA_SECTION:
 1  250  250
 2  360  19
 3  219  119
 4  399  428
 5  143  183
 6  306  225
 7  50  427
 8  141  71
 9  461  269
10  143  473
11  340  499
12  446  488
13  453  328
14  162  229
15  120  441
16  139  363
17  295  223
18  294  420
19  119  454
20  309  306
21  434  228
22  439  267
23  444  112
24  292  299
25  56  106
26  33  289
27  202  315
28  253  140
29  325  194
30  88  165
31  132  166
32  68  57
33  51  464
34  202  326
35  428  169
36  386  299
37  107  49
38  352  342
39  471  130
40  188  374
41    2  436
42  76  337
43  252  410
44  93  120
45  469  402
46  168  12
47  197  267
48  287  10
49  481  492
50  33  312
51  415  285
52  118  84
53  318  125
54  364  310
55  162  350
56  387  461
57  31  406
58  96  283
59  374  60
60  310  25
61  484  167
62  289  262
63  266  23
64  136  229
65  67  265
66  218  291
67  80  334
68  321  407
69  264  488
70  47  412
71  122  384
72  11  412
73  148  404
74  132  363
75  31  320
76  40  24
77  164  374
78  92  57
79  372  380
80  247  446
81  67  181
82  326  286
83  235  127
84  487  10
85  411  411
86  226  455
87  78  124
88  238  456
89  360  218
90  128  194
91  420  224
92  247  427
93  421  378
94  84  102
95  278  408
96  464    1
97  276  107
98  140  42
99  423  337
100  400    7
101  250  250
DEMAND_SECTION
1 -214
2 7
3 9
4 -1
5 9
6 0
7 4
8 1
9 -5
10 0
11 -1
12 2
13 5
14 -1
15 -6
16 -4
17 4
18 -2
19 0
20 0
21 -8
22 -3
23 -2
24 9
25 6
26 -8
27 6
28 -3
29 -5
30 0
31 -7
32 -4
33 -8
34 8
35 -1
36 -1
37 7
38 4
39 8
40 0
41 5
42 -7
43 1
44 2
45 -5
46 3
47 -7
48 -3
49 9
50 5
51 8
52 -1
53 1
54 8
55 -1
56 -1
57 -10
58 0
59 -1
60 -5
61 7
62 4
63 -4
64 -3
65 -3
66 7
67 6
68 1
69 1
70 5
71 0
72 -9
73 -4
74 -3
75 -6
76 2
77 -1
78 -4
79 2
80 -9
81 5
82 -4
83 8
84 1
85 -7
86 4
87 -8
88 8
89 1
90 -8
91 -3
92 0
93 -3
94 -9
95 8
96 4
97 -5
98 9
99 -4
100 -10
101 218
EOF

Le voici la dernière version du mon programme:
Code:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

struct ville                        /*definition d'un type structure nommé ville*/
   {
      int identifiant;
      double abscisse;
      double ordonnee;
      
   };

int main ()
{
   struct    ville Ville[101];            /* variable de type structure ville*/
   double ** distance_entre_ville;         /*distance euclidiene entre les ville*/

   int i, j;
   int n = 101;
   int k = 101;

   /*ouverture du fichier de données pour lecture*/

   FILE * fichier;
   fichier = fopen("D:\\Codes\\TS2004t3\\n100mos.txt", "r");

   if(fichier == NULL)
   {
      printf("Impossible d'ouvrir fichier .txt \n");
      exit (-1);
   }


   /*on commence à lire à la ligne 6: NODE_COORD_SECTION
   */
   for(i=0;i<6;i++)

   while(fgetc(fichier)!='\n');
   for(i=0;i<k;i++)

      if (fscanf(fichier, "%d %lf %lf", &(Ville[i].identifiant), &(Ville[i].abscisse), &(Ville[i].ordonnee)) !=3)
      {
         printf("Erreur dans le format d'une ligne : ligne %d.\n", i);
            exit(-1);
      }


   /*Allocation dynamique du tableau distance*/
      distance_entre_ville = (double ** ) malloc (k * sizeof (double));

   for (i=0;i<k;i++)
   {

      distance_entre_ville[i]=(double *)malloc(n * sizeof(double));
   }


   /*calcul distance*/

    for(i=0;i<k;i++)
   {
      for(j=0;j<i+1;j++)
      {
         if(i==j)
         {
         distance_entre_ville[i][i]= 0.0;
         }

         distance_entre_ville[i][j]= distance_entre_ville[j][i] =  sqrt(pow((Ville[i].abscisse - Ville[j].abscisse),2.0)+pow((Ville[i].ordonnee - Ville[j].ordonnee),2.0));

      }
   }

   /*afficher sur l'écran la matrice distance_entre_ville*/

    for (i=0; i<k; i++)
   {
      for (j=0; j<i+1; j++)
      {

            printf("distance_entre_ville[%i][%i]= %lf\n",i, j, distance_entre_ville[i][j]);

      }

   }

    /*recopie contenu de la matrice distance entre les villes dans le fichier file*/
    FILE * sortie;
   sortie = fopen("D:\\Codes\\TS2004t3\\Distance_entre_ville.txt", "w");

   if(sortie == NULL)
   {
      printf("Impossible d'ouvrir fichier .txt \n");
      exit (-1);
   }
   for (i=0; i<k; i++)
   {
      for (j=0; j<i+1; j++)
      {
         fprintf(sortie, "%lf\n",distance_entre_ville[i][j]);

      }
      fprintf (sortie, "\n" );

   }

   /*déliberer mémoire*/

   for(i=0;i<k;i++)
      free(distance_entre_ville[i]);
    free(distance_entre_ville);

   /*femeture fichiers*/
   fclose(fichier);
   fclose(sortie);


   getchar();


   return 0;
}
Merci de votre aide.

pascal
Bavard
Bavard

Messages : 20
Date d'inscription : 20/08/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  -ed- le Dim 6 Mar 2011 - 17:07

J'avoue que ne sais pas très bien à quoi correspondent ces données et que je ne vois pas trop quel est le problème. Je vais vérifier le codage pour voir si tout est correct. Ne pas hésiter à mettre des traces (printf(...)) pour vérifier la valeur de telle ou telle variable.

_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  pascal le Dim 6 Mar 2011 - 17:21

-ed- a écrit:J'avoue que ne sais pas très bien à quoi correspondent ces données et que je ne vois pas trop quel est le problème. Je vais vérifier le codage pour voir si tout est correct. Ne pas hésiter à mettre des traces (printf(...)) pour vérifier la valeur de telle ou telle variable.
En fait, NODE_COORD_SECTION : marque le début de la partie des données.
Chaque ligne représente une ville par le tuple (idVille, abscisse, ordonnée).
La fin du fichier de données est marqué par la chaine EOF qui est écrite en toute lettre (ce
n’est pas le caractère EOF du langage C).
En premier lieu je veux calculer la distance entre les villes. On a 100 villes.
J'espère que je vous fait compris.


Dernière édition par pascal le Dim 6 Mar 2011 - 17:32, édité 1 fois

pascal
Bavard
Bavard

Messages : 20
Date d'inscription : 20/08/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  -ed- le Dim 6 Mar 2011 - 17:29

101 villes, ça veut dire 101 x (101-1) combinaisons, c'est à dire plus de 10.000 ? C'est bien prévu ?

OK. J'imagine que c'est une simplification temporaire, mais les informations de type 'taille' (le fameux 101) ne sont pas lues dans le fichier (les 6 premières lignes sont sautées), mais codées en dur dans le programme. C'est provisoire ?


Dernière édition par -ed- le Dim 6 Mar 2011 - 18:04, édité 1 fois

_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  pascal le Dim 6 Mar 2011 - 17:33

-ed- a écrit:101 villes, ça veut dire 101 x (101-1) combinaisons, c'est à dire plus de 10.000 ?

OK. J'imagine que c'est une simplification temporaire, mais les informations de type 'taille' (le fameux 101) ne sont pas lues dans le fichier (les 6 premières lignes sont sautées), mais codées en dur dans le programme. C'est provisoire ?
En fait, je me suis trompée. C'est 100 villes Basketball

pascal
Bavard
Bavard

Messages : 20
Date d'inscription : 20/08/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  -ed- le Dim 6 Mar 2011 - 17:34

"trompée" ? C'est Pascale ?

Pourtant n et k valent 101. C'est normal ?

EDIT : J'ai réécrit le code qui saute les 6 lignes pour qu'il soit plus sûr (éviter les boucles imbriquées) et plus adaptable... La trace confirme que les 6 lignes ont bien été lues.
Code:

  /*on commence à lire à la ligne 6: NODE_COORD_SECTION
  for (i = 0; i < 6; i++)
      while (fgetc (fichier) != '\n')
        ;
  */
  {
      int c;
      i = 0;
      while ( (c = fgetc (fichier)) != EOF && i < 6)
      {
        /* trace */
        putchar (c);

        if (c == '\n')
        {
            i++;
        }
      }
  }

Sinon, il y a bien 100 villes + un 'marqueur' de fin liste en 101 qui a pour coordonnées 0,0 (ça fait un peu ceinture et bretelles, mais pourquoi pas ...).

Le tableau de structure statique (Ville[]) a la bonne taille et il est correctement rempli.

Ensuite, je vois une allocation dynamique d'un tableau de k x k. En toute logique, ça devrait être (k-1) x (k-1), puisque la dernière valeur n'est pas une ville, mais un marqueur ...

Attention, la formule appliquée pour le calcul de la taille du tableau de pointeur est fausse.

La formule générale pour créeer un tableau dynamique de N éléments de type T est :

Code:
T *ap = malloc (N * sizeof *ap);
Ce qui devient ici :

Code:
double ** distance_entre_ville = malloc (k * sizeof *distance_entre_ville );

de même, l'allocation de chaque ligne se fait comme ceci (n est initile. k suffit, car la matrice est carrée par nature):
Code:

            for (i = 0; i < k; i++)
            {
              distance_entre_ville[i] = malloc (k * sizeof *distance_entre_ville[i]);
            }


_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  -ed- le Dim 6 Mar 2011 - 18:36

Ensuite, le point important et un peu élaboré est le calcul de la distance euclidienne (à vol d'oiseau). Je vois qu'une certaine optimisation a été réalisée pour économiser des calculs.

Le principe est donc de parcourir une moitié de tableau (triangle), de faire le calcul, et de stocker dans les 2 cases correspondantes aux 2 combinaisons, car une distance n'est pas 'orientée.

C'est astucieux et c'est correct.

Je ne vois pas d'erreur dans l'exécution. Le contenu du fichier de sortie semble correct (pour tester le principe, j'aurais utilisé un fichier de 10 villes, c'est plus facile à tester).

On aurait pu aussi allouer une matrice 'en triangle' pour économiser de la mémoire (du moins théoriquement). Enfin, je pense qu'il est inutile de stocker les valeurs '0'.

Sinon, j'ai un peu amélioré le codage :

Code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>


#if 1
#define INPUT_FILE "n100mosA.tsp"
#else
#define INPUT_FILE "D:\\Codes\\TS2004t3\\n100mos.txt"
#endif

#if 1
#define OUTPUT_FILE "Distance_entre_ville.txt"
#else
#define OUTPUT_FILE "D:\\Codes\\TS2004t3\\Distance_entre_ville.txt"
#endif

#define TRACE 1
/* 1=trace
  0=pas de trace */

struct ville                        /*definition d'un type structure nommé ville*/
{
  int identifiant;
  double abscisse;
  double ordonnee;
};

int main (void)
{
  struct    ville Ville[101];            /* variable de type structure ville */
  int k = 101;
  /* ouverture du fichier de données pour lecture */
  FILE * fichier = fopen (INPUT_FILE, "r");

  if (fichier == NULL)
  {
      printf ("Impossible d'ouvrir fichier .txt \n");
      exit (-1);
  }
  else
  {

      /*on commence à lire à la ligne 6: NODE_COORD_SECTION
      for (i = 0; i < 6; i++)
        while (fgetc (fichier) != '\n')
            ;
      */
      {
        int c;
        int i = 0;
        while ( (c = fgetc (fichier)) != EOF && i < 6)
        {
#if TRACE
            /* trace */
            putchar (c);
#endif
            if (c == '\n')
            {
              i++;
            }
        }
      }

      {
        int i;
        for (i = 0; i < k; i++)
        {
            if (fscanf (fichier, "%d %lf %lf", &Ville[i].identifiant, &Ville[i].abscisse, &Ville[i].ordonnee) != 3)
            {
              printf ("Erreur dans le format d'une ligne : ligne %d.\n", i);
              exit (-1);
            }
        }
      }

      fclose (fichier);


#if TRACE
      /* trace : relecture du tableau */
      {  int i;
        for (i = 0; i < k; i++)
        {
            printf ("%4d %6.0f %6.0f\n", Ville[i].identifiant, Ville[i].abscisse, Ville[i].ordonnee);
        }
      }

      getchar();
#endif
  }

  {
      /*Allocation dynamique du tableau distance
      distance_entre_ville = (double **) malloc (k * sizeof (double));
      */
      /* distance euclidiene entre les ville */
      double ** distance_entre_ville = malloc (k * sizeof * distance_entre_ville);
      if (distance_entre_ville != NULL)
      {
        {
            int i;
            for (i = 0; i < k; i++)
            {
              distance_entre_ville[i] = malloc (k * sizeof * distance_entre_ville[i]);
            }
        }

        /* calcul distance */
        {
            int i;
            for (i = 0; i < k; i++)
            {
              int j;
              for (j = 0; j < i + 1; j++)
              {
                  if (i == j)
                  {
                    distance_entre_ville[i][i] = 0.0;
                  }
                  else
                  {
                    assert (i < 101);
                    assert (j < 101);
                    distance_entre_ville[i][j] = distance_entre_ville[j][i] =  sqrt (pow ( (Ville[i].abscisse - Ville[j].abscisse), 2.0) + pow ( (Ville[i].ordonnee - Ville[j].ordonnee), 2.0));
#if TRACE
                    printf ("i=%4d j=%4d\n", i, j);
#endif
                  }
              }
#if 0
              getchar ();
#endif
            }
        }


        /*afficher sur l'écran la matrice distance_entre_ville*/
        {
            int i;
            for (i = 0; i < k; i++)
            {  int j;
              for (j = 0; j < k; j++)
              {
                  printf ("distance_entre_ville[%i][%i]= %f\n", i, j, distance_entre_ville[i][j]);
              }
            }
        }

        {
            /*recopie contenu de la matrice distance entre les villes dans le fichier file*/
            FILE * sortie = fopen (OUTPUT_FILE, "w");

            if (sortie == NULL)
            {
              printf ("Impossible d'ouvrir fichier .txt \n");
              exit (-1);
            }
            else
            {
              int i;
              for (i = 0; i < k; i++)
              {
                  int j;
                  for (j = 0; j < i + 1; j++)
                  {
                    fprintf (sortie, "%f\n", distance_entre_ville[i][j]);
                  }
                  fprintf (sortie, "\n");
              }/*femeture fichiers*/
              fclose (sortie);
            }

            /* liberer mémoire */
            {
              int i;
              for (i = 0; i < k; i++)
              {
                  free (distance_entre_ville[i]);
              }
            }
            free (distance_entre_ville);
        }
      }
  }
  return 0;
}
selon des principes largement exposés sur mon site de programmation C (notamment la réduction de la portée des variables). Le code est maintenant prêt à être découpé en fonctions...

_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  pascal le Dim 6 Mar 2011 - 19:09

-ed- a écrit:Ensuite, le point important et un peu élaboré est le calcul de la distance euclidienne (à vol d'oiseau). Je vois qu'une certaine optimisation a été réalisée pour économiser des calculs.

Le principe est donc de parcourir une moitié de tableau (triangle), de faire le calcul, et de stocker dans les 2 cases correspondantes aux 2 combinaisons, car une distance n'est pas 'orientée.

C'est astucieux et c'est correct.

Je ne vois pas d'erreur dans l'exécution. Le contenu du fichier de sortie semble correct (pour tester le principe, j'aurais utilisé un fichier de 10 villes, c'est plus facile à tester).

On aurait pu aussi allouer une matrice 'en triangle' pour économiser de la mémoire (du moins théoriquement). Enfin, je pense qu'il est inutile de stocker les valeurs '0'.

Sinon, j'ai un peu amélioré le codage :

Code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>


#if 1
#define INPUT_FILE "n100mosA.tsp"
#else
#define INPUT_FILE "D:\\Codes\\TS2004t3\\n100mos.txt"
#endif

#if 1
#define OUTPUT_FILE "Distance_entre_ville.txt"
#else
#define OUTPUT_FILE "D:\\Codes\\TS2004t3\\Distance_entre_ville.txt"
#endif

#define TRACE 1
/* 1=trace
  0=pas de trace */

struct ville                        /*definition d'un type structure nommé ville*/
{
  int identifiant;
  double abscisse;
  double ordonnee;
};

int main (void)
{
  struct    ville Ville[101];            /* variable de type structure ville */
  int k = 101;
  /* ouverture du fichier de données pour lecture */
  FILE * fichier = fopen (INPUT_FILE, "r");

  if (fichier == NULL)
  {
      printf ("Impossible d'ouvrir fichier .txt \n");
      exit (-1);
  }
  else
  {

      /*on commence à lire à la ligne 6: NODE_COORD_SECTION
      for (i = 0; i < 6; i++)
        while (fgetc (fichier) != '\n')
            ;
      */
      {
        int c;
        int i = 0;
        while ( (c = fgetc (fichier)) != EOF && i < 6)
        {
#if TRACE
            /* trace */
            putchar (c);
#endif
            if (c == '\n')
            {
              i++;
            }
        }
      }

      {
        int i;
        for (i = 0; i < k; i++)
        {
            if (fscanf (fichier, "%d %lf %lf", &Ville[i].identifiant, &Ville[i].abscisse, &Ville[i].ordonnee) != 3)
            {
              printf ("Erreur dans le format d'une ligne : ligne %d.\n", i);
              exit (-1);
            }
        }
      }

      fclose (fichier);


#if TRACE
      /* trace : relecture du tableau */
      {  int i;
        for (i = 0; i < k; i++)
        {
            printf ("%4d %6.0f %6.0f\n", Ville[i].identifiant, Ville[i].abscisse, Ville[i].ordonnee);
        }
      }

      getchar();
#endif
  }

  {
      /*Allocation dynamique du tableau distance
      distance_entre_ville = (double **) malloc (k * sizeof (double));
      */
      /* distance euclidiene entre les ville */
      double ** distance_entre_ville = malloc (k * sizeof * distance_entre_ville);
      if (distance_entre_ville != NULL)
      {
        {
            int i;
            for (i = 0; i < k; i++)
            {
              distance_entre_ville[i] = malloc (k * sizeof * distance_entre_ville[i]);
            }
        }

        /* calcul distance */
        {
            int i;
            for (i = 0; i < k; i++)
            {
              int j;
              for (j = 0; j < i + 1; j++)
              {
                  if (i == j)
                  {
                    distance_entre_ville[i][i] = 0.0;
                  }
                  else
                  {
                    assert (i < 101);
                    assert (j < 101);
                    distance_entre_ville[i][j] = distance_entre_ville[j][i] =  sqrt (pow ( (Ville[i].abscisse - Ville[j].abscisse), 2.0) + pow ( (Ville[i].ordonnee - Ville[j].ordonnee), 2.0));
#if TRACE
                    printf ("i=%4d j=%4d\n", i, j);
#endif
                  }
              }
#if 0
              getchar ();
#endif
            }
        }


        /*afficher sur l'écran la matrice distance_entre_ville*/
        {
            int i;
            for (i = 0; i < k; i++)
            {  int j;
              for (j = 0; j < k; j++)
              {
                  printf ("distance_entre_ville[%i][%i]= %f\n", i, j, distance_entre_ville[i][j]);
              }
            }
        }

        {
            /*recopie contenu de la matrice distance entre les villes dans le fichier file*/
            FILE * sortie = fopen (OUTPUT_FILE, "w");

            if (sortie == NULL)
            {
              printf ("Impossible d'ouvrir fichier .txt \n");
              exit (-1);
            }
            else
            {
              int i;
              for (i = 0; i < k; i++)
              {
                  int j;
                  for (j = 0; j < i + 1; j++)
                  {
                    fprintf (sortie, "%f\n", distance_entre_ville[i][j]);
                  }
                  fprintf (sortie, "\n");
              }/*femeture fichiers*/
              fclose (sortie);
            }

            /* liberer mémoire */
            {
              int i;
              for (i = 0; i < k; i++)
              {
                  free (distance_entre_ville[i]);
              }
            }
            free (distance_entre_ville);
        }
      }
  }
  return 0;
}
selon des principes largement exposés sur mon site de programmation C (notamment la réduction de la portée des variables). Le code est maintenant prêt à être découpé en fonctions...

Je vous en remercie beaucoup.
Par rapport à l'allocation dynamique d'un tableau de deux dimensions, dans le cours que ils ont fait comme ça l'allocation. Le compilateur n'a pas détecté cette erreur, bizarre non?
En fait, le principe du ce problème c'est le dédoublement de la ville 0 (en fait ca correspond au dépot) en 0 et 101(si le nombre de ville est 100.pour forcer que le voyageur y retourne.

Sinon, comment faire pour lire les données de demande (DEMAND_SECTION) dans le fichier données?
Merci encore.

pascal
Bavard
Bavard

Messages : 20
Date d'inscription : 20/08/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  -ed- le Dim 6 Mar 2011 - 19:37

pascal a écrit:
Par rapport à l'allocation dynamique d'un tableau de deux dimensions, dans le cours que ils ont fait comme ça l'allocation. Le compilateur n'a pas détecté cette erreur, bizarre non?
Le compilateur ne peut pas détecter l’erreur. La syntaxe est correcte, mais le comportement est indéfini.

En fait, le principe du ce problème c'est le dédoublement de la ville 0 (en fait ca correspond au dépot) en 0 et 101(si le nombre de ville est 100.pour forcer que le voyageur y retourner.
Pour calculer les distances, je pense que c'es inutile. Ca devient utile pour la suite (calcul du chemin le plus court).

Sinon, comment faire pour lire les données de demande (DEMAND_SECTION) dans le fichier données?
Merci encore.
Si le format du fichier est fixe. il faut découper la lecture en autant de champs attendus (texte, numériques) avec fscanf(), vérifier que la conversion est correcte et ensuite exploiter chaque champ lu. Attention scanf() avec "%s" lit du texte en s’arrêtant a premier blanc (espace, tabulation, fin de ligne).

Si le format est variable, il faut adopter une stratégie plus souple et donc plus élaborée. Que dit le cahier des charges sur la définition du fichier ?

_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  pascal le Mar 8 Mar 2011 - 0:11

-ed- a écrit:
pascal a écrit:
Par rapport à l'allocation dynamique d'un tableau de deux dimensions, dans le cours que ils ont fait comme ça l'allocation. Le compilateur n'a pas détecté cette erreur, bizarre non?
Le compilateur ne peut pas détecter l’erreur. La syntaxe est correcte, mais le comportement est indéfini.

En fait, le principe du ce problème c'est le dédoublement de la ville 0 (en fait ca correspond au dépot) en 0 et 101(si le nombre de ville est 100.pour forcer que le voyageur y retourner.
Pour calculer les distances, je pense que c'es inutile. Ca devient utile pour la suite (calcul du chemin le plus court).

Sinon, comment faire pour lire les données de demande (DEMAND_SECTION) dans le fichier données?
Merci encore.
Si le format du fichier est fixe. il faut découper la lecture en autant de champs attendus (texte, numériques) avec fscanf(), vérifier que la conversion est correcte et ensuite exploiter chaque champ lu. Attention scanf() avec "%s" lit du texte en s’arrêtant a premier blanc (espace, tabulation, fin de ligne).

Si le format est variable, il faut adopter une stratégie plus souple et donc plus élaborée. Que dit le cahier des charges sur la définition du fichier ?
Bonjour,

Merci beaucoup de votre aide.
Le cahier de charge malheureusement n'est pas très détaillé.
Bon, je vais tester mon algo sur ce jeu de données après je vais voir...

Là, la deuxième étape consiste à construire une tournée initiale. En premier lieu les villes sont ajoutées à une liste à partir de laquelle l'algorithme procède à l'insertion itérative des villes dans la tournée. Chaque ville est insérée à la position tel que la distance totale de la tournée est minimale.
J'avoue que je ne sais pas comment procéder.
Pourriez-vous m'aider?
Merci.

pascal
Bavard
Bavard

Messages : 20
Date d'inscription : 20/08/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  -ed- le Mar 8 Mar 2011 - 1:38

C'est essentiellement un problème d'algorithme, et je ne suis pas du tout spécialisé pour ça. Je recommande le forum 'algorithmes' de developpez.com.

_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  pascal le Mer 9 Mar 2011 - 18:00

-ed- a écrit:C'est essentiellement un problème d'algorithme, et je ne suis pas du tout spécialisé pour ça. Je recommande le forum 'algorithmes' de developpez.com.
En fait, voici l'algorithme de construction des routes
/*Algorithme Clark and Wright*/
/*Au debut on cree N routes (0, i, 0) pour i =1..N, ensuite on calcul le
gain S(i, j) = ci0 + c0j - cij , (avec cij la distance entre i et j et c0j est la distance entre la ville i et le dépot 0), aprés ces gains seront rangées par ordre décroisant,
puis on essaye de fusionner ces routes sans violer les contraintes du probleme (contraintes capacité et de respect de charge du camion dans la route, de l'intervalle de temps de passage chez la ville) jusqu'à ce qu'aucune liaison ne soit possible.
*/
Selon vous quel est le type de donnée le mieux adapté pour construire les routes?

J'ai choisi la structure de données type tableau à deux dimensions.
Mon idée c'est d'obtenir résultat sous cette forme.
Code:

                              identifiantville
n°de route                 
0                                            0              1                0
1                                            0              2                0



Est ce logique?

Voici mon essai:
[//*Au debut on cree N routes (0, i, 0) pour i =1..N
Code:

void Creation_route(struct ville Ville[101])
{
    int k = 101;
    int n = 3;    //nombre de ville

    int i, j;

  int **route = (int **)malloc( sizeof(int**) * k);// tabelau sauvegarder route

  for(i = 0; i < n; i++)
  route[i] = (int *) malloc( sizeof(int *) * n);
  for (i=0;i<n;i++)
    {

      route[i]=(int *)malloc(n * sizeof(int));
    }


    /*on va constituer une solution*/
    /* On va creer une route */


    for (i=1 ; i<k; i++) //nombre de la route
    {
        for (j=0 ; j<n; j++) // taille de route
        {
            if (j == 0 || j == 3)
            {
            /* On met le depot au debut */
            /* et On le met à la fin */
                route[i][j] = Ville[0].identifiant;
            }
        route[i][j]= Ville[i].identifiant;
        for (i=0 ; i<k; i++)
        {
          for (j=0 ; j<n; j++)
          {

              printf("afficher route %d",  route[i][j]);

          }

        for(i=0;i<n;i++)
        free(route[i]);
                free(route);


        }

    }

Est ce correcte?
Merci d'avance de votre aide.

pascal
Bavard
Bavard

Messages : 20
Date d'inscription : 20/08/2009

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Problème lecture fichier

Message  Contenu sponsorisé Aujourd'hui à 21:20


Contenu sponsorisé


Revenir en haut Aller en bas

Voir le sujet précédent Voir le sujet suivant Revenir en haut

- Sujets similaires

 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum