Προς το περιεχόμενο

Accessing struct members - C


Dr.Fuzzy

Προτεινόμενες αναρτήσεις

Καθότι έχω σκουριάσει λίγο, τα φώτα σας. Ποιος είναι πιο σωστός ή συνήθης τρόπος για να κάνω access τα members ενός struct μέσα από ένα function. Για παράδειγμα:

 

>
struct point
{
   double x;
   double y;
};

struct TSP_data
{
   char name[LINE_BUFFER_LENGTH];
   char edge_weight_type[LINE_BUFFER_LENGTH];
   int n;
   struct node *point;
} problem;

struct TSP_data* load_TSP_data(const char *TSP_filename)
{
   problem.n=1;
   FILE *TSP_file;
   char buffer[LINE_BUFFER_LENGTH];
   int i, j;
...
}

 

ή

 

>
struct point
{
   double x;
   double y;
};

struct TSP_data
{
   char name[LINE_BUFFER_LENGTH];
   char edge_weight_type[LINE_BUFFER_LENGTH];
   int n;
   struct node *point;
};

struct TSP_data* load_TSP_data(TSP_data * problem, const char *TSP_filename)
{
   problem.n=1;
   FILE *TSP_file;
   char buffer[LINE_BUFFER_LENGTH];
   int i, j;
...
}

 

Όποια άλλη πατάτα δείτε ρίξτε μου γιαούρτια να τη διορθώσω. :)

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Απαντ. 85
  • Δημ.
  • Τελ. απάντηση
"TSP" δηλ. Travelling Salesman Problem ;;;

 

Spot on! Ναι έχω φτιάξει ένα ant colony optimization αλγόριθμο σε MATLAB και τώρα θέλω να το υλοποιήσω σε CUDA. Οπότε αρχικά θα γίνει σε C και μετά θα το τροποποιήσω για GPU.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Έχω λύσει αυτό το πρόβλημα σε Fortran πριν πολύ καιρό, όταν ήμουν δεύτερο έτος.

Προσεγγιστικά, με annealing simulation.

Για δες την επισύναψη.

Δεν είναι βελτιστοποιημένο αλλά είναι αρκετά γρήγορο και πετυχαίνει μείωση πάνω από 80% στην αρχική διαδρομή.

Kαι ήταν και μικρό - λιγότερο από 500 γραμμές (μαζί με τα απλοϊκά γραφικά).

Aν χρησιμοποιηθεί ο λεγόμενος αλγόριθμος metropolis (ρωτάει) καθυστερεί περισσότερο αλλά η μείωση είναι η μέγιστη δυνατή (πάνω από 90%).

Πέραν του demo mode, έχω και ένα ενδεικτικό αρχείο με input data (για να το δει πρέπει να είναι στο ίδιο directory με το exe) για να παίξει λίγο κάποιος και με δικά του δεδομένα.

 

Πέραν αυτού, κάπου το έχω λυμμένο και στη C++ με νευρωνικά δίκτυα...

 

-

TSP_problem.zip

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καθότι έχω σκουριάσει λίγο, τα φώτα σας. Ποιος είναι πιο σωστός ή συνήθης τρόπος για να κάνω access τα members ενός struct μέσα από ένα function. Για παράδειγμα:

 

>
struct point
{
   double x;
   double y;
};

struct TSP_data
{
   char name[LINE_BUFFER_LENGTH];
   char edge_weight_type[LINE_BUFFER_LENGTH];
   int n;
   struct node *point;
} problem;

struct TSP_data* load_TSP_data(const char *TSP_filename)
{
   problem.n=1;
   FILE *TSP_file;
   char buffer[LINE_BUFFER_LENGTH];
   int i, j;
...
}

 

ή

 

>
struct point
{
   double x;
   double y;
};

struct TSP_data
{
   char name[LINE_BUFFER_LENGTH];
   char edge_weight_type[LINE_BUFFER_LENGTH];
   int n;
   struct node *point;
};

struct TSP_data* load_TSP_data(TSP_data * problem, const char *TSP_filename)
{
   problem.n=1;
   FILE *TSP_file;
   char buffer[LINE_BUFFER_LENGTH];
   int i, j;
...
}

 

Όποια άλλη πατάτα δείτε ρίξτε μου γιαούρτια να τη διορθώσω. :)

 

Είναι κακή η προσέγγιση με global μεταβλητές για πολλούς λόγους αλλα ο κύριος είναι η δύσκολη συντήρηση του προγράμματος στο μέλλον. Ασπούμε σαουτήν την περίπτωση έχεις ένα struct στο επόμενο βήμα όμως σου έρχεται ένα Requirement όπου έχεις πολλά τέτοια structs προφανώς με global μεταβλητή την struct στην πρώτη φάση δεν μπορείς να κανεις και πολλά πράγματα.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

@Smirnov (ο γνωστός μαθηματικός ; )

Λοίπον και εγώ το έχω λύσει με GA και νευρωνικά στο παρελθόν, μάλιστα το είχα υλοποιήσει και σε FPGA (μια δημοσίευση που είχα κάνει). Το ACO σε MATLAB είναι περίπου 100 γραμμές με τα γραφικά και είναι αρκετά γρήγορο, αλλά όπως είπα θέλω να παίξω με CUDA οπότε αναγκαστικά πρέπει να γίνει σε C αρχικά. Thanx για το attachment θα το κοιτάξω. To SA το γνωρίζω αλλά δεν το έχω δοκιμάσει. Γενικά, σε discrete combinatorial optimization problems όπως το TSP, το ACΟ και οι GA συγκλίνουν γρηγοτερα από νευρωνικά, PSO, SA (continuous)

 

@m1Cro

Οπότε η δεύτερη μέθοδος (να περνάω στο function pointer instance του struct) είναι προτιμότερη αν κατάλαβα καλά.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

@Smirnov (ο γνωστός μαθηματικός ; )

Λοίπον και εγώ το έχω λύσει με GA και νευρωνικά στο παρελθόν, μάλιστα το είχα υλοποιήσει και σε FPGA (μια δημοσίευση που είχα κάνει). Το ACO σε MATLAB είναι περίπου 100 γραμμές με τα γραφικά και είναι αρκετά γρήγορο, αλλά όπως είπα θέλω να παίξω με CUDA οπότε αναγκαστικά πρέπει να γίνει σε C αρχικά. Thanx για το attachment θα το κοιτάξω. To SA το γνωρίζω αλλά δεν το έχω δοκιμάσει. Γενικά, σε discrete combinatorial optimization problems όπως το TSP, το ACΟ και οι GA συγκλίνουν γρηγοτερα από νευρωνικά, PSO, SA (continuous)

 

@m1Cro

Οπότε η δεύτερη μέθοδος (να περνάω στο function pointer instance του struct) είναι προτιμότερη αν κατάλαβα καλά.

 

Ναι η δεύτερη περίπτωση είναι καλύτερη. Γιατί αν χρειαστεί να αλλάξεις κάτι θα δουλεύεις προσθετικά χωρίς να αγγίξεις τον ήδη υπάρχον κώδικα.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

@Smirnov (ο γνωστός μαθηματικός ; )

 

Λοίπον και εγώ το έχω λύσει με GA και νευρωνικά στο παρελθόν, μάλιστα το είχα υλοποιήσει και σε FPGA (μια δημοσίευση που είχα κάνει).

Το ACO σε MATLAB είναι περίπου 100 γραμμές με τα γραφικά και είναι αρκετά γρήγορο, αλλά όπως είπα θέλω να παίξω με CUDA οπότε αναγκαστικά πρέπει να γίνει σε C αρχικά.

Thanx για το attachment θα το κοιτάξω. To SA το γνωρίζω αλλά δεν το έχω δοκιμάσει. Γενικά, σε discrete combinatorial problems optimization όπως το TSP, το ACΟ και οι GA

συγκλίνουν γρηγοτερα από νευρωνικά, PSO, SA (continoues)

 

 

 

Ο V.I.Smirnov ήταν ένας ρώσσος μαθηματικός των αρχών του αιώνα, μεγάλη διάνοια.

Ανάμεσα στα άλλα έγραψε το 5-τομο σύγγραμμα "Α course on Ηigher Μathematics" που περιλαμβάνει την βασική ύλη των μαθηματικών που πρέπει

να γνωρίζει ένας θετικός επιστήμονας. Αν και πολύ παλιό υπάρχει σε όλες τις βιβλιοθήκες και είναι άριστη πηγή για πολλά θέματα επειδή είναι πολύ

καλογραμμένο. Κάποτε διάβασα τους τόμους ΙΙΙ και VI (μου πήρε δυο χρόνια περίπου) και επηρέασαν σημαντικά τον τρόπο σκέψης μου.

Τα κεφάλαια στις Σφαιρικές Αρμονικές, στις συναρτήσεις Bessel και Hankel, τα διπλά στρώματα δυναμικού και την συγγένεια των ολοκληρωτικών εξισώσεων με

τα προβλήματα Dirichlet και Newmann είναι από τις πιο καλογραμμένες εισαγωγές σ' αυτά τα θέματα αν και πέρασαν 70 χρόνια από τότε που τα έγραψε.

Αναφέρεται στην βιβλιογραφία των περισσότερων παλιών βιβλίων για τέτοια θέματα.

 

Το αρχείο που επισυνάπτω είναι απλώς ένα exe χωρίς τον κώδικα, απλώς το έβαλα επειδή έγινε κουβέντα για το TSP και το θυμήθηκα...

Ο αλγόριθμος που χρησιμοποίησα περιγράφεται στο Numerical Recipes.

Για μεγάλο πλήθος σημείων-πόλεων (πάνω από 200) η μείωση στην αρχική διαδρομή είναι μεγάλη, κατά μέσο όρο πάνω από 80% ,

και με το ειδικό flag "metropolis" που έχω βάλει πιάνει το 90%. Για λίγα σημεία πρέπει να πειραχτούν παράμετροι εντός του κώδικα.

Σε ότι αφορά τα νευρωνικά, δεν τα έχω μελετήσει σε βάθος αλλά από τις δοκιμές που είχα κάνει για το συγκεκριμένο πρόβλημα, ήταν

πιο αργά και λιγότερο αποτελεσματικά από το simulated annealing.

 

-

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Άλλη μια ερώτηση! Τι πατάτα έχω κάνει στην main και μου πετάει error;

 

/home/delk/Desktop/ACO/ACO.c|238|error: expected declaration specifiers or ‘...’ before ‘*’ token

/home/delk/Desktop/ACO/ACO.c|238|error: conflicting types for ‘load_TSP_data’

 

 

>
long int **distance; /* distance[i][j] matrix, from city[i] to city[j]*/

/*
*  load TSP data
*/
struct point
{
   double x;
   double y;
};

struct TSP_data
{
   char name[LINE_BUFFER_LENGTH];
   char edge_weight_type[LINE_BUFFER_LENGTH];
   long int n;
   struct point *node;
};

struct TSP_data* load_TSP_data(struct TSP_data *problem, const char *TSP_filename)
{
   problem->n=1;
   FILE *TSP_file;
   char buffer[LINE_BUFFER_LENGTH];
...
...
   return problem->node;
}

/*
*  main program
*/
int main(int argc, char *argv[])
{
   const char filename[] = "att48.tsp";

   struct TSP_data* load_TSP_data(struct TSP_data *problem, *filename);
   return 0; /* temp */
}

 

:-)

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Άλλη μια ερώτηση! Τι πατάτα έχω κάνει στην main και μου πετάει error;

 

Εμμμμ...Μίγμα κλήσης και ξανα-declaration της συνάρτησης load_TSP_data... ; :)

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

:X...ότι αφήνεις σε αφήνει! κάπως έτσι καλύτερα; Αν και πρέπει να περνάω και να επιστρέφω pointer του struct. Κάτι δεν μου κολλάει...έχω μπλέξει λίγο τα μπούτια μου!

 

>
/*
*  main program
*/
int main(int argc, char *argv[])
{
   const char filename[] = "att48.tsp";

   struct TSP_data *problem;

   problem = load_TSP_data(problem, *filename);

   return 0; /* temp */
}

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

:X...ότι αφήνεις σε αφήνει! κάπως έτσι καλύτερα; Αν και πρέπει να περνάω και να επιστρέφω pointer του struct. Κάτι δεν μου κολλάει

 

Όντως, δεν χρειάζεται να κάνεις και τα δύο. Αν πριν την κλήση της load_TSP_data έχεις δεσμεύσει με malloc μνήμη για τον problem pointer, τότε αρκεί να κάνεις μόνο το πρώτο. Αν όχι και θέλεις (και πρέπει, αφού η πρώτη εντολή μέσα στη συνάρτηση είναι προσπέλαση του problem->n member) η malloc να γίνεται μέσα στην load_TSP_data στην αρχή-αρχή της, αρκεί να κάνεις μόνο το δεύτερο.

 

Αλλά το ενδιαφέρον είναι ότι αυτό που κάνεις return στο τέλος της load_TSP_data (το problem->node δηλαδή) δεν είναι pointer σε struct TSP_data, αλλά pointer σε struct point. Άρα το return type της load_TSP_data δε μπορεί να είναι struct TSP_data*, ούτε μπορείς να κάνεις assign αυτό που επιστρέφει σε έναν pointer σε struct TSP_data. :rolleyes:

 

Τώρα μπερδεύτηκα κι εγώ! :P

 

 

Επίσης, στην κλήση της load_TSP_data, γιατί ως 2ο όρισμα *filename και όχι σκέτο filename;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

:X...ότι αφήνεις σε αφήνει! κάπως έτσι καλύτερα; Αν και πρέπει να περνάω και να επιστρέφω pointer του struct. Κάτι δεν μου κολλάει...έχω μπλέξει λίγο τα μπούτια μου!

 

>
/*
*  main program
*/
int main(int argc, char *argv[])
{
   const char filename[] = "att48.tsp";

   //struct TSP_data *problem;
   struct TSP_data problem;
   /*problem =*/ load_TSP_data(&problem, filename);
   return 0; /* temp */
}

 

Δεν υπαρχει λογος να επιστρεψεις τον pointer που μπενει ως arg.

ΥΓ:Ενα typedef θα ηταν πολυ βολικο σε αυτη τη περιπτωση :-)

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.


  • Δημιουργία νέου...