Grafi - Matrice di Adiacenza

di il
14 risposte

Grafi - Matrice di Adiacenza

Salve a tutti, sto studiando la struttura di dati grafo, e provandone le implementazioni, al che mi è sorto un dubbio che non riesco a risolvere dai libri di testo. Nel caso in cui io debba implementare un grafo con la rappresentazione tramite matrice di adiacenza, ma i miei nodi sono di un tipo generico void *, come faccio ad implementare la struct in modo tale che resti costante la funzione che verifica l'adiacenza tra due nodi? E' possibile farlo? Non riesco a reperire del materiale dove poter approfondire l'argomento.
Grazie mille

14 Risposte

  • Re: Grafi - Matrice di Adiacenza

    Di preciso cosa non è chiaro?
  • Re: Grafi - Matrice di Adiacenza

    Non mi è chiaro come faccio ad implementare la matrice di adiacenza di un grafo che contiene nodi di tipo generico
  • Re: Grafi - Matrice di Adiacenza

    Parliamo di C presumo, non C++.
    In C la matrice di adicenza diventa:
    
    struct Graph {
        int num_vertex;
        void** adj; // < questa
    };
    
    Il problema è come caratterizzare le operazioni sul grafo/matrice in base a com'è fatto il nodo.
    L'unico modo è usare dei puntatore a funzione, che in input ricevono come parametro i nodi generici (void*) e al loro interno fanno un cast al tipo di nodo reale con le relative operazioni da fare. In base all'implementazione della funzione del grafo è possibile individuare il codice invariante (ossia che non fa riferimento specifico al tipo di nodo) e il codice variante (ossia quello in cui è richiesto il tipo specifico di nodo, in genere confronti e assegnazioni). Questo in linea generale.
    Se la cosa ti pare confusa, pensa al quicksort: uno dei parametri prevede un puntatore a funzione a cui vengono passati dei void* e che tu hai il compito di caratterizzare a seconda di cosa stai ordinando.
  • Re: Grafi - Matrice di Adiacenza

    Il discorso dei puntatori a funzione mi è abbastanza chiaro. Infatti io immagino di avere una struttura dati Graph generica, in cui tramite un void * graphAdt implemento rispettivamente liste di adiacenza e matrice di adiacenza. Il punto che non mi è chiaro è il seguente.. Nel primo caso io immagino di avere un array di puntatori, ognuno dei quali punta ad una lista. Ogni nodo della lista è una struct con le varie informazioni.
    Nel caso della matrice di adiacenza, ho difficoltà in quanto non ho id interi, e quindi l'adiacenza non è più una costante come se avessi degli int.. e quindi non riesco ad implementare la struct in maniera tale da non perdere i vantaggi della rappresentazione di un grafo come matrice di adiacenza.
    Non so se ho reso meglio il mio problema, o l'ho confuso ancora di più... ?!
  • Re: Grafi - Matrice di Adiacenza

    Meglio se posti un po' di codice perché mi sfugge di che id stai parlando. Così come mi sfugge il perché l'adiacenza non sia più una costante.
  • Re: Grafi - Matrice di Adiacenza

    Ma stiamo parlando di MATRICE DI ADIANCENZA o LISTA DI ADIACENZA:

    NON E' LA STESSA COSA!

    Se e' una MATRICE di adiacenza, stai sbagliando TOTALMENTE implementazione.

    Se e' una LISTA di adiacenza, i tuoi puntatori non dovrebbero essere di tipo VOID.

    Oppure possono essere di tipo VOID, ma la TUA funzione di controllo delle adiacenze SA ESATTAMENTE di che tipo e' il puntatore: riceve un VOID ma lo casta al tipo corretto.
  • Re: Grafi - Matrice di Adiacenza

    migliorabile ha scritto:


    Ma stiamo parlando di MATRICE DI ADIANCENZA o LISTA DI ADIACENZA:

    NON E' LA STESSA COSA!
    Certo che non sono la stessa cosa! Stiamo parlando di entrambi.. La lista di adiacenza ho capito come implementarla.
    Se e' una LISTA di adiacenza, i tuoi puntatori non dovrebbero essere di tipo VOID.

    Oppure possono essere di tipo VOID, ma la TUA funzione di controllo delle adiacenze SA ESATTAMENTE di che tipo e' il puntatore: riceve un VOID ma lo casta al tipo corretto.
    esatto! e io ho fatto il secondo modo.
    Se e' una MATRICE di adiacenza, stai sbagliando TOTALMENTE implementazione.
    Infatti in questo caso non riesco a trovare neanche il principio dell'implementazione!

    Quindi il mio problema sta nell'implementare appunto la rappresentazione con matrice di adiacenza, di un grafo i cui nodi siano una struttura generica.
    Sia ad esempio in una libreria graph (in cui tutte le funzioni utilizzeranno il void* tramite gli opportuni puntatori a funzione per i due tipi di implementazione a cui farò corrispondere due differenti librerie)
    typedef struct graph{
        int size;
        void * graphAdt;
    }graph;
    
    per quanto riguarda le liste di adiacenza, ho pensato ad una struttura di questo tipo:
    #define CAPACITY 10;
    
    typedef struct node{
        void * key; //tipo generico
        char color; // 'b','g','n, //per le visite di ampiezza e profondità
      //  double p; // IL PESO E' SULL'ARCO NON SUL NODO!!!!! //trovare soluzione
        struct node * adj; //next
    }node;
    
    typedef struct graphList{
        int capacity;
        int size; //indice corrente
        struct node ** list; //array di liste di node
    }graphList;
    
  • Re: Grafi - Matrice di Adiacenza

    Guarda che una MATRICE DI INCIDENZA si implementa in modo BANALE:

    e' una MATRICE

    con tante righe e tante colonne quanti sono i nodi del grafo,

    e nella cella MA[j] ci metti 1 se il nodo i e' collegato al nodo j!

    BANALE

    E come fai a sapere chi e' il nodo i e chi il nodo j?

    BANALE, ad ogni nodo assegni un ID univoco (un intero)!
  • Re: Grafi - Matrice di Adiacenza

    migliorabile ha scritto:


    Guarda che una MATRICE DI INCIDENZA si implementa in modo BANALE:

    e' una MATRICE

    con tante righe e tante colonne quanti sono i nodi del grafo,

    e nella cella MA[j] ci metti 1 se il nodo i e' collegato al nodo j!

    BANALE

    E come fai a sapere che e' il nodo i e chi il nodo j?

    BANALE, ad ogni nodo assegni un ID univoco (un intero)!


    e come è dichiarata ed inizializzata MA??
    Capisco che può essere una cosa banale per lei, ma per me che sto studiando, non tanto.. C'è qualcosa di sicuramente molto sciocco che mi sfugge e non riesco a proseguire
  • Re: Grafi - Matrice di Adiacenza

    Scusa il doppio post, ma mi era sfuggito il tuo ultimo rigo..
    BANALE, ad ogni nodo assegni un ID univoco (un intero)!
    Il mio discorso girava proprio intorno a questi int, senza i quali appunto la matrice non avrebbe senso. E allora quello che dico.. Nel momento in cui io assegno un id univoco ad ogni nodo, ma la key del nodo è un void* (perchè è un puntatore ad un tipo generico), la mia funzione di INSERTARCH riceve due void*.. e prima di andare ad inserire l'1 in matrice devo effettuare una ricerca per individuare i rispettivi id.. e allora ritorno alla mia domanda di partenza.. la mia funzione insertArch avrà una complessità O(|V|)e non più O(1) come dovrebbe essere nelle rappresentazioni con matrice di adiacenza... va bene, quindi, lo stesso??
  • Re: Grafi - Matrice di Adiacenza

    Domandona di rito, MA PERCHE' continui a voler usare i void* ???

    Il void* e' un arzigogolo che serve per fare delle cose strane: uno lo usa quando SA ESATTAMENTE come/quando/perche' va usato.

    TU NON USARE puntatori di tipo void: USA PUNTATORI a strutture dati BEN SPECIFICHE!!!!!
  • Re: Grafi - Matrice di Adiacenza

    Devo usare void* in quanto la chiave del mio nodo può esssere di un tipo qualsiasi, e ho per ogni tipo le rispettive librerie per gestire le varie funzioni utilizzando i rispettivi puntatori a funzioni, per i tipi concreti.
    La scelta del tipo di dato sarà fatta a runtime, per cui sono obbligata ad usare void*.
  • Re: Grafi - Matrice di Adiacenza

    Ci sono SOLO due cose che nella vita si DEVONO fare (in Italia una di queste e' opzionale ):
    pagare le tasse, e morire (il piu' tardi possibile, ma da li non si scappa ).

    Il fatto che una libreria richieda puntatori di tipo void vuol SOLO dire che a LEI NON INTERESSA sapere la struttura dell'oggetto puntato.
    Da nessuna parte c'e' scritto che ANCHE TU DEBBA usare puntatori void!

    Insomma, il programma DEVE FARE QUELLO CHE VUOI TU, NON quello che vuole lui.
    TROVA UN MODO a costo di prendere a martellate la libreria
  • Re: Grafi - Matrice di Adiacenza

    Ahahahhah.. non è tra le mie conoscenze e competenze, -ammesso che esista, un altro modo per scrivere una funzione di inserimento che vada bene per QUALUNQUE tipo di dato sceglie l'utente di inserire.
    Il fatto che una libreria richieda puntatori di tipo void vuol SOLO dire che a LEI NON INTERESSA sapere la struttura dell'oggetto puntato
    È proprio quello che devo fare io, quindi non soffermiamoci su questo in quanto il mio problema è successivo a questa scelta di implementazione.
Devi accedere o registrarti per scrivere nel forum
14 risposte