Сохраните результат многих циклов - PullRequest
1 голос
/ 01 мая 2019

У меня есть код на python, и сейчас я пытаюсь написать его на c (для оптимизации скорости), потому что я никогда не использовал c!

Ранее я использовал для сохранения полученных данных в словаре или в списке массивов, но я не знаю, какова подходящая структура и как хранить ее здесь в c.

Я читаю данные из файла, называемого (попытка), затем обрабатываю их, используя функции, написанные в коде. Три for loops используются для получения необходимых данных, но я не знаю, как их хранить!

код, который содержит петли

for (i=0; i<m; i++){
   igraph_edge(&graph, i, &from, &to);
   igraph_neighbors(&graph, &v1, from, IGRAPH_ALL);
   igraph_neighbors(&graph, &v2, to, IGRAPH_ALL);
   for (j=0; j < igraph_vector_size(&v2); j++) {
     for (k=0; k < igraph_vector_size(&v1); k++) {
       printf("%li %d %f %d %f\n", i, from, VECTOR(v1)[k] ,to, VECTOR(v2)[j]);     
     } 
   }
}     

 //EDIT: concerning the different data types, at the end all elements inside the loops could have have the same type so


int n1, n2;
for (i=0; i<m; i++){
    igraph_edge(&graph, i, &from, &to);
    igraph_neighbors(&graph, &v1, from, IGRAPH_ALL);
    igraph_neighbors(&graph, &v2, to, IGRAPH_ALL);
    for (j=0; j < igraph_vector_size(&v2); j++) {
      for (k=0; k < igraph_vector_size(&v1); k++) {
        n1 =  floor(VECTOR(v1)[k]);
        n2 =  floor(VECTOR(v2)[j]);
        printf("%li %d %d %d %d\n", i, from, n1 ,to, n2);                        
      }
    }
 }  

Результат находится на форме

0 1 2.000000 2 1.000000
0 1 2.000000 2 3.000000
0 1 2.000000 2 4.000000
1 2 1.000000 3 2.000000
1 2 3.000000 3 2.000000
1 2 4.000000 3 2.000000
          .
          .
          .

Вместо того, чтобы печатать эти данные, я хотел бы сохранить их как

data = [ [ [1, 2.000000, 2 ,1.000000], [1, 2.000000, 2, 3.000000], [1, 2.000000, 2, 4.000000] ], [  [2, 1.000000, 3, 2.000000], [2, 3.000000, 3, 2.000000], ...  ], ... ]

Тогда, если мне нужно получить доступ к данным

  1. для индекса 0, data[0]= [ [1, 2.000000, 2 1.000000], [1, 2.000000, 2, 3.000000], [1, 2.000000, 2, 4.000000] ]

  2. и data[0][2]=[1 2.000000 2 4.000000]

  3. и data[0][2][3]= [4.000000] data[0][2][3]= 4.000000

Возможно ли это в моем случае? Я был бы очень очень благодарен за любую помощь.

П.С .: Я буду очень рад объяснить что-то непонятное.

Сложение

Вот полный код (при необходимости)

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

#define sigma 1

void print_vector(igraph_vector_t *v, FILE *file) {
     long int i;
     for (i=0; i < igraph_vector_size(v); i++) {
        fprintf(file, "%li \n", (long int) VECTOR(*v)[i]);
     }
     fprintf(file,"\n");
 }


float rbf(int a, int b);

float rbf(int a, int b) {
  double inverse;
  double exp(double x;);
  double x;
  double result;

  inverse = ( 1/(sigma*sigma) );
  x = (- inverse * ( (a - b)*(a - b) ) );
  result = exp(x);
  return (result); 
} 

int main(void)
{

     igraph_t graph; 
     igraph_bool_t false;
     igraph_bool_t connected1, connected2, connected3, connected4, connected5, connected6;
     int ret;
     float rhs1;
     float rhs2;
     igraph_vector_t v1, v2;
     long int i, j, k, n, m ;
     igraph_integer_t from, to;
     igraph_adjlist_t adjlist;
     FILE *file;
     file = fopen("attempt", "r");
     if(!file){
        return 1;
     }

     igraph_read_graph_edgelist(&graph, file, 
                                0, false);

     fclose(file);

     igraph_vector_init(&v1, (igraph_vcount(&graph)) );
     igraph_vector_init(&v2, (igraph_vcount(&graph)) );
     igraph_adjlist_init(&graph, &adjlist, IGRAPH_ALL);

     n = igraph_vcount(&graph);
     m = igraph_ecount(&graph);
     for (i=0; i<m; i++){
        igraph_edge(&graph, i, &from, &to);
        igraph_neighbors(&graph, &v1, from, IGRAPH_ALL);
        igraph_neighbors(&graph, &v2, to, IGRAPH_ALL);
        for (j=0; j < igraph_vector_size(&v2); j++) {
          for (k=0; k < igraph_vector_size(&v1); k++) {
            printf("%li %d %f %d %f\n", i, from, VECTOR(v1)[k] ,to, VECTOR(v2)[j]);                        
          }
        }
     }

     //igraph_destroy(&graph);
}

и попытка файла содержит эти пробные данные

1 2
2 3
2 4
3 4
4 5

1 Ответ

2 голосов
/ 01 мая 2019

хотел бы сохранить его

вам нужна структура для каждого элемента, например

typedef Struct Data {
  int from;
  float vfrom;
  int to;
  float vto;
} Data;

Затем Data**.

Обратите внимание, что это не позволяет иметь data[0][2][3]= [4.000000], иначе необходимо иметь float ***, а это не практично, это data[0][2].vto == 4.000000

Например, заменить

 for (i=0; i<m; i++){
    igraph_edge(&graph, i, &from, &to);
    igraph_neighbors(&graph, &v1, from, IGRAPH_ALL);
    igraph_neighbors(&graph, &v2, to, IGRAPH_ALL);
    for (j=0; j < igraph_vector_size(&v2); j++) {
      for (k=0; k < igraph_vector_size(&v1); k++) {
        printf("%li %d %f %d %f\n", i, from, VECTOR(v1)[k] ,to, VECTOR(v2)[j]);                        
      }
    }
 }

на

 Data ** all = malloc(m * sizeof(Data*));

 for (i=0; i<m; i++){
    igraph_edge(&graph, i, &from, &to);
    igraph_neighbors(&graph, &v1, from, IGRAPH_ALL);
    igraph_neighbors(&graph, &v2, to, IGRAPH_ALL);
    all[i] = malloc(igraph_vector_size(&v2)*graph_vector_size(&v1)*sizeof(Data));

    int idx = 0;

    for (j=0; j < igraph_vector_size(&v2); j++) {
      for (k=0; k < igraph_vector_size(&v1); k++) {
        all[i][idx].from = from;
        all[i][idx].vfrom = VECTOR(v1)[k];
        all[i][idx].to = to;
        all[i][idx].vto = VECTOR(v2)[j];
        idx += 1;
      }
    }
 }

Обратите внимание, что будет трудно использовать Data** после того, как число записей во всех подмассивах неизвестно и одинаково, возможно, вам нужно сохранить эти числа, длячто:

typedef Struct Data {
  int from;
  float vfrom;
  int to;
  float vto;
} Data;

typedef Datas {
   int n;
   Data * datas;
} Datas;

позволяет делать:

 Datas * all = malloc(m * sizeof(Datas));

 for (i=0; i<m; i++){
    igraph_edge(&graph, i, &from, &to);
    igraph_neighbors(&graph, &v1, from, IGRAPH_ALL);
    igraph_neighbors(&graph, &v2, to, IGRAPH_ALL);

    int jsup = igraph_vector_size(&v2);
    int ksup = igraph_vector_size(&v1);
    Data * a = malloc(jsup * ksup * sizeof(Data));

    all[i].n = jsup * ksup;
    all[i].datas = a;

    for (j=0; j < jsup; j++) {
      for (k=0; k < ksup; k++) {
        a->from = from;
        a->vfrom = VECTOR(v1)[k];
        a->to = to;
        a->vto = VECTOR(v2)[j];
        a += 1;
      }
    }
 }

, затем

printf("data : [");

for (i=0; i<m; i++) {
  Data * a = all[i].datas;

  printf(" [");

  for (int j = 0; j != all[i].n; ++j)
    printf(" [%d %f %d %f]", a[j].from, a[j].vfrom, a[j].to, a[j].vto);

  printf(" ]");
}

puts(" ]");

Вот полная программа:

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

#define sigma 1

void print_vector(igraph_vector_t *v, FILE *file) {
     long int i;
     for (i=0; i < igraph_vector_size(v); i++) {
        fprintf(file, "%li \n", (long int) VECTOR(*v)[i]);
     }
     fprintf(file,"\n");
 }


float rbf(int a, int b);

float rbf(int a, int b) {
  double inverse;
  double exp(double x;);
  double x;
  double result;

  inverse = ( 1/(sigma*sigma) );
  x = (- inverse * ( (a - b)*(a - b) ) );
  result = exp(x);
  return (result); 
} 

typedef struct Data {
  int from;
  float vfrom;
  int to;
  float vto;
} Data;

typedef struct Datas {
   int n;
   Data * datas;
} Datas;


int main(void)
{

     igraph_t graph; 
     igraph_bool_t false;
     igraph_bool_t connected1, connected2, connected3, connected4, connected5, connected6;
     int ret;
     float rhs1;
     float rhs2;
     igraph_vector_t v1, v2;
     long int i, j, k, n, m ;
     igraph_integer_t from, to;
     igraph_adjlist_t adjlist;
     FILE *file;
     file = fopen("attempt", "r");
     if(!file){
        return 1;
     }

     igraph_read_graph_edgelist(&graph, file, 
                                0, false);

     fclose(file);

     igraph_vector_init(&v1, (igraph_vcount(&graph)) );
     igraph_vector_init(&v2, (igraph_vcount(&graph)) );
     igraph_adjlist_init(&graph, &adjlist, IGRAPH_ALL);

     n = igraph_vcount(&graph);
     m = igraph_ecount(&graph);
     Datas * all = malloc(m * sizeof(Datas));

     for (i=0; i<m; i++){
       igraph_edge(&graph, i, &from, &to);
       igraph_neighbors(&graph, &v1, from, IGRAPH_ALL);
       igraph_neighbors(&graph, &v2, to, IGRAPH_ALL);

       int jsup = igraph_vector_size(&v2);
       int ksup = igraph_vector_size(&v1);
       Data * a = malloc(jsup * ksup * sizeof(Data));

       all[i].n = jsup * ksup;
       all[i].datas = a;

       for (j=0; j < jsup; j++) {
         for (k=0; k < ksup; k++) {
           a->from = from;
           a->vfrom = VECTOR(v1)[k];
           a->to = to;
           a->vto = VECTOR(v2)[j];
           printf("%d %f %d %f\n", a->from, a->vfrom, a->to, a->vto);
           a += 1;
         }
       }
     }

     printf("data : [");

     for (i=0; i<m; i++) {
       Data * a = all[i].datas;

       printf(" [");

       for (int j = 0; j != all[i].n; ++j)
         printf(" [%d %f %d %f]", a[j].from, a[j].vfrom, a[j].to, a[j].vto);

       printf(" ]");
     }

     puts(" ]");

     /* free resources */
     igraph_destroy(&graph);
     igraph_vector_destroy(&v1);
     igraph_vector_destroy(&v2);
     igraph_adjlist_destroy(&adjlist);

     for (i=0; i<m; i++)
       free(all[i].datas);
     free(all);         

     return 0;
}

с файлом попытка , содержащая

1 2
2 3
2 4
3 4
4 5

выполнение:

pi@raspberrypi:/tmp $ ./a.out
1 2.000000 2 1.000000
1 2.000000 2 3.000000
1 2.000000 2 4.000000
2 1.000000 3 2.000000
2 3.000000 3 2.000000
2 4.000000 3 2.000000
2 1.000000 3 4.000000
2 3.000000 3 4.000000
2 4.000000 3 4.000000
2 1.000000 4 2.000000
2 3.000000 4 2.000000
2 4.000000 4 2.000000
2 1.000000 4 3.000000
2 3.000000 4 3.000000
2 4.000000 4 3.000000
2 1.000000 4 5.000000
2 3.000000 4 5.000000
2 4.000000 4 5.000000
3 2.000000 4 2.000000
3 4.000000 4 2.000000
3 2.000000 4 3.000000
3 4.000000 4 3.000000
3 2.000000 4 5.000000
3 4.000000 4 5.000000
4 2.000000 5 4.000000
4 3.000000 5 4.000000
4 5.000000 5 4.000000
data : [ [ [1 2.000000 2 1.000000] [1 2.000000 2 3.000000] [1 2.000000 2 4.000000] ] [ [2 1.000000 3 2.000000] [2 3.000000 3 2.000000] [2 4.000000 3 2.000000] [2 1.000000 3 4.000000] [2 3.000000 3 4.000000] [2 4.000000 3 4.000000] ] [ [2 1.000000 4 2.000000] [2 3.000000 4 2.000000] [2 4.000000 4 2.000000] [2 1.000000 4 3.000000] [2 3.000000 4 3.000000] [2 4.000000 4 3.000000] [2 1.000000 4 5.000000] [2 3.000000 4 5.000000] [2 4.000000 4 5.000000] ] [ [3 2.000000 4 2.000000] [3 4.000000 4 2.000000] [3 2.000000 4 3.000000] [3 4.000000 4 3.000000] [3 2.000000 4 5.000000] [3 4.000000 4 5.000000] ] [ [4 2.000000 5 4.000000] [4 3.000000 5 4.000000] [4 5.000000 5 4.000000] ] ]
...