[C] Calcolo percorso breve

di il
6 risposte

[C] Calcolo percorso breve

Ciao ragazzi, sto cercando di risolvere un esercizio:

"Dati un vertice sorgente, uno destinazione e una tipologia di distanze (d1 oppure d2 oppure
d3) inseriti dall’utente, calcola il percorso più breve tra sorgente e destinazione, mostrando a
monitor tale percorso e la relativa distanza."

Essendo che la struttura dati in questione è un grafo orientato e che d1 d2 e d3 sono i pesi del grafo (numeri reali tipo 1.2, 3.4, 5.6 etc, tutti positivi) pensavo di utilizzare l'algoritmo di Dijkstra, è la soluzione migliore per il mio caso? Ho a disposizione lo pseudocodice da alcune dispense, ma ho bisogno di aiuto per implementarlo in C.

Ci sono due cose che non mi sono chiare:
1) questa riga nella funzione 'inizializza':
vertice_p->distanza_min = INFINITO;
come implemento questo INFINITO?
2) /costruisci un insieme per i vertici già considerati (inizialmente vuoto) .;
/costruisci una struttura per i vertici da considerare (inizialmente tutti) .;
non sono sicuro di aver capito come svolgere questa parte.

void dijkstra(vertice grafo t *grafo p,
                               vertice grafo t *sorgente p)
{
     vertice grafo t *vertice p;
     arco grafo t *arco p;

     inizializza(grafo p,
                      sorgente p);

     /costruisci un insieme per i vertici già considerati (inizialmente vuoto) .;
     /costruisci una struttura per i vertici da considerare (inizialmente tutti) .;

     while (/la struttura non è vuota .)
     {
               /rimuovi dalla struttura il vertice vertice p con distanza min minima .;
               /inserisci vertice p nell’insieme dei vertici già considerati .;

                for (arco p = vertice p->lista archi p;
                        (arco p != NULL);
                       arco p = arco p->arco succ p)
                     if (arco p->vertice adiac p non è nell’insieme dei vertici già considerati .)
                             riduci(arco p,
                                         vertice p);
      }
}
void inizializza(vertice_grafo_t *grafo_p,
                                    vertice_grafo_t *sorgente_p)
{
      vertice_grafo_t *vertice_p;
      for (vertice_p = grafo_p;
             (vertice_p != NULL);
            vertice_p = vertice_p->vertice_succ_p)
       {
             vertice_p->distanza_min = INFINITO;
             vertice_p->padre_p = NULL;
       }
       sorgente_p->distanza_min = 0.0;
}
void riduci(arco_grafo_t *arco_p,
                            vertice_grafo_t *vertice_p) /* vertice da cui l’arco esce */
{
      if (arco_p->vertice_adiac_p->distanza_min > vertice_p->distanza_min + arco_p->peso)
      {
          arco_p->vertice_adiac_p->distanza_min = vertice_p->distanza_min + arco_p->peso;
          arco_p->vertice_adiac_p->padre_p = vertice_p;
      }
}
Spero in qualche risposta visto che nel thread che ho creato qualche settimana fa non rispose nessuno.

6 Risposte

  • Re: [C] Calcolo percorso breve

    1) INFINITO: qualuque numero MOOOOLTO grande va bene. A seconda del tipo di numero che usi, e' definito il numero piu' grande esprimibile: int, long, long long, float, double, long double. Tra l'altro, se cerchi un po' con Google, trovi anche il .h che contiene le definizioni di tali valori.

    2) fondamentalmente ti serve sapere quali nodi del grafi hai processato e quali devi ancora processare.
    Non esiste una soluzione unica. Immagina una possibile soluzione e descrivila. Poi se ne parla.

    Molto dipende da come identificherai i nodi del grafo:

    1) mediante un intero?
    2) mediante una stringa?
    3) mediante il puntatore
    4) mediante un numero generato a caso?
    5) qualche altro meccanismo?
  • Re: [C] Calcolo percorso breve

    Innanzitutto ti ringrazio per la risposta.

    Tornando all'esercizio:
    1) chiarissimo, il tipo che uso è double.

    2) è quello il problema purtroppo. Perdona la mia scarsezza in programmazione ma non saprei proprio come fare.

    Per quanto riguarda "Molto dipende da come identificherai i nodi del grafo":
    I nodi del grafo sono stringhe, per la precisione sono 5 nodi:
    v_a, v_b, v_c, v_d, v_e

    Per evitare di creare confusione sappi che questo esercizio funziona così:
    -Acquisisco dei dati da un file di testo (fatto)
    -Li inserisco in una struttura dati: grafo (fatto)
    -Calcolo il percorso più breve tra vertice sorgente (inserito da tastiera) e vertice destinazione (idem) in base ad una tipologia di distanza (d1, d2 o d3, sempre inserita da tastiera): da fare.

    Questi sono i dati acquisiti da file (per darti un'idea):
    5
    3
    v_a v_b 8.2 5.3 9.7
    v_a v_c 2.5 1.4 3.2
    v_a v_e 3.6 5.0 2.7
    3
    v_b v_a 1.4 5.2 0.1
    v_b v_c 8.5 11.4 0.2
    v_b v_e 6.9 2.4 2.8
    2
    v_c v_d 2.7 6.2 1.1
    v_c v_e 3.8 4.4 3.4
    3
    v_d v_a 18.2 7.3 19.7
    v_d v_c 12.5 1.6 5.4
    v_d v_e 11.6 3.2 12.7
    1
    v_e v_a 12.6 16.2 14.1
    
    Il file segue questo formato:
    <Numero totale dei vertici>
    <Numero di vertici direttamente collegati al vertice A>
    <vertice_A> <vertice_B> <d1> <d2> <d3>
    <vertice_A> <vertice_M> <d1> <d2> <d3>
    ...
    <vertice_A> <vertice_Z> <d1> <d2> <d3>
    <Numero di vertici direttamente collegati al vertice B>
    <vertice_B> <vertice_C> <d1> <d2> <d3>
    <vertice_B> <vertice_X> <d1> <d2> <d3>
    ...
  • Re: [C] Calcolo percorso breve

    Ora che ci penso, per rappresentare questi due:
    /costruisci un insieme per i vertici già considerati (inizialmente vuoto) .;
    /costruisci una struttura per i vertici da considerare (inizialmente tutti) .;

    potrei utilizzare code o pile, giusto?
    Alla fin fine l'algoritmo di Dijkstra prevede inserimenti e rimozioni, mi sembra un buon compromesso, mi sbaglio?
  • Re: [C] Calcolo percorso breve

    Sono ancora bloccato su questo:
    /costruisci un insieme per i vertici già considerati (inizialmente vuoto) .;
    /costruisci una struttura per i vertici da considerare (inizialmente tutti) .;

    qualcuno sa dirmi qualcosa di più?
  • Re: [C] Calcolo percorso breve

    Griever ha scritto:


    Sono ancora bloccato su questo:
    /costruisci un insieme per i vertici già considerati (inizialmente vuoto) .;
    /costruisci una struttura per i vertici da considerare (inizialmente tutti) .;

    qualcuno sa dirmi qualcosa di più?
    Dove sta' il problema?

    Qualunque struttura dati che possa contenere una collezione di oggetti va bene.

    Quali strutture dati che possono contenere collezioni di oggetti conosci?

    Un po' di iniziativa, suvvia!

    Non stai sparando ad un innocente!
  • Re: [C] Calcolo percorso breve

    Per l'insieme dei vertici già considerati (inizialmente vuoto) penso che una coda vada benissimo.

    Per la struttura in cui inizialmente ci sono tutti i vertici invece non saprei in quanto nell'algoritmo dice di rimuovere il vertice con distanza_min minima. E' possibile fare ciò in code/pile? Da quello che ho capito sulle dispense, le code usano il principio FIFO e le pile LIFO, ma potrei sbagliarmi.

    Poi altra cosa, una volta decisa la struttura in cui devono essere presenti tutti i vertici, devo fare un'altra funzione in cui inserisco tutti i vertici del grafo in questa struttura?
    Troppi dubbi. z_z
Devi accedere o registrarti per scrivere nel forum
6 risposte