Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14
  1. #1
    Utente di HTML.it
    Registrato dal
    Aug 2004
    Messaggi
    17

    ki lo sa risolvere??

    salve ragazzi avrei bisogno di un piccolo aiuto.

    Sono una studentessa e tra i miei corsi c'è programmazione in c, mi dispiace dirvelo ma sono una vera FRANA con i computer!!!

    devo presentare un progetto e non sò proprio da dove iniziare, qualkuno di voi può aiutarmi?? gliene sarei davvero grata!!

    questo è il progetto :

    DISTANZA MASSIMA TRA NODI DI UN GRAFO:

    Ricordiamo che in un grafo orientato, dati due nodi s e v, si dice che v è raggiungibile da s se esiste un cammino da s a v e, in questo caso, la distanza di v da s è la lunghezza del cammino più corto da s a v:

    a - progettare un algoritmo per risolvere il seguente problema:

    dato un grafo orientato G di n nodi e m lati, e un nodo s di G, determinare l'insieme dei nodi di G raggiungibili da s che si trovano a distanza massima da s

    b - Valutare in funzione di n e m il tempo di calcolo dell'algoritmo nel caso peggiore.

    1 kiss x tutti.... Ciauzzzz

  2. #2
    ciao e benvenuta su questo forum
    in futuro cerca di usare titoli + significativi per saper come leggi qui
    Vascello fantasma dei mentecatti nonchè baronetto della scara corona alcolica, piccolo spuccello di pezza dislessico e ubriaco- Colui che ha modificato l'orribile scritta - Gran Evacuatore Mentecatto - Tristo Mietitore Mentecatto chi usa uTonter danneggia anche te

  3. #3
    Utente di HTML.it L'avatar di unicorn
    Registrato dal
    Aug 2004
    Messaggi
    176

    Re: ki lo sa risolvere??

    Originariamente inviato da gazzella
    salve ragazzi avrei bisogno di un piccolo aiuto.

    Sono una studentessa e tra i miei corsi c'è programmazione in c, mi dispiace dirvelo ma sono una vera FRANA con i computer!!!

    devo presentare un progetto e non sò proprio da dove iniziare, qualkuno di voi può aiutarmi?? gliene sarei davvero grata!!

    questo è il progetto :

    DISTANZA MASSIMA TRA NODI DI UN GRAFO:

    Ricordiamo che in un grafo orientato, dati due nodi s e v, si dice che v è raggiungibile da s se esiste un cammino da s a v e, in questo caso, la distanza di v da s è la lunghezza del cammino più corto da s a v:

    a - progettare un algoritmo per risolvere il seguente problema:

    dato un grafo orientato G di n nodi e m lati, e un nodo s di G, determinare l'insieme dei nodi di G raggiungibili da s che si trovano a distanza massima da s

    b - Valutare in funzione di n e m il tempo di calcolo dell'algoritmo nel caso peggiore.

    1 kiss x tutti.... Ciauzzzz
    In un grafo orientato, se non ricordo male, il caso peggiore si ha quando ogni nodo ha un solo collegamento a quello successivo, per cui se ci sono ad es. n nodi la lunghezza del grafo sarà n-1 che oltre ad essere l'altezza è anche il caso peggiore.
    Spero di averti aiutato, comunque prendi quello che ti ho scritto con le pinze. :maLOL:

  4. #4
    Utente di HTML.it
    Registrato dal
    Aug 2004
    Messaggi
    17
    grazie...

    Ciò di cui ho bisogno è però qualke dritta su come impostare il programma... avrei bisogno di "codice puro"

  5. #5
    Utente di HTML.it L'avatar di unicorn
    Registrato dal
    Aug 2004
    Messaggi
    176
    Originariamente inviato da gazzella
    grazie...

    Ciò di cui ho bisogno è però qualke dritta su come impostare il programma... avrei bisogno di "codice puro"
    Poichè in genere quando si parla di grafi ci si riferisce ad alberi, posso passarti qualcosa su quest'ultimi.

  6. #6
    Utente di HTML.it
    Registrato dal
    Aug 2004
    Messaggi
    17
    ok, grazie...
    non so proprio da dove iniziare con questo progetto se hai qualke idea te ne sarei grata

  7. #7
    Utente di HTML.it L'avatar di unicorn
    Registrato dal
    Aug 2004
    Messaggi
    176
    Originariamente inviato da gazzella
    ok, grazie...
    non so proprio da dove iniziare con questo progetto se hai qualke idea te ne sarei grata
    Ecco il codice

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

    struct nodo {
    int key; /* valore del nodo */
    struct nodo * up; /* punta al padre */
    struct nodo * left; /* punta al sottoalbero sinistro */
    struct nodo * right; /* punta al sottoalbero destro */
    };

    typedef struct nodo nodo;

    /* Crea un albero vuoto */

    nodo *t_create(void) {
    return NULL;
    }


    /* Crea un nuovo nodo contenente il valore n e
    restituisce l'indirizzo del nodo creato */
    nodo *creanodo(int n){
    nodo *q;

    q = malloc(sizeof(nodo));
    if (q==NULL) {
    fprintf(stderr, "malloc(): errore allocazione memoria\n");
    exit(-1);
    }
    q->key = n;
    q->left = q->right = q->up = NULL;
    return q;
    }


    /* Inserisce nell'albero di radice r un nuovo nodo contenente n
    e restituisce un puntatore all'albero ottenuto */
    nodo *t_insert(nodo *r, int n){
    nodo *q, *pq;
    if(r==NULL) /* l'albero e' vuoto */
    return creanodo(n);
    else{ /* discendi l'albero fino a trovare il punto di inserimento */
    q = r;
    while(q != NULL){
    pq = q;
    q = (n < q->key) ? q->left : q->right;
    }
    /* ora pq punta al padre del nuovo nodo */
    q = creanodo(n);
    if (n < pq ->key)
    pq->left = q;
    else
    pq->right = q;
    q->up = pq;
    return r;
    }
    }

    /* Cerca nell'albero di radice r un nodo di valore n.
    Se il nodo esiste restituisce un puntatore ad esso,
    altrimenti restituisce NULL */

    nodo *t_find(nodo *r, int n){
    while (r!=NULL && r->key != n)
    r = (n < r->key) ? r->left : r->right;
    return r;
    }

    /* restituisce un puntatore al minimo nodo
    dell'albero di radice r */
    nodo * t_min(nodo *r){
    for( ; r->left!= NULL; r=r->left);
    return r;
    }


    /* restituisce un puntatore al massimo nodo
    dell'albero di radice r */
    nodo * t_max(nodo *r){
    for( ; r->right!= NULL; r=r->right);
    return r;
    }

    /* Restituisce il massimo fra a e b */
    int max(int a, int b){
    return a > b ? a : b ;
    }

    /* Calcola l'altezza dell'albero di radice r */
    int t_height(nodo *r){
    int h1, h2;
    if(r == NULL)
    return -1;
    else{
    h1 = t_height(r->left);
    h2 = t_height(r->right);
    return max(h1, h2) + 1;
    }
    }


    int main(){

    int c, h;
    int cx;
    nodo *root; /*puntatore alla radice dell'albero*/
    nodo *m,*M;

    root=t_create(); /*creo un nuovo albero*/
    do{
    /* cerca il primo carattere c diverso da spazio */
    for( c=getchar() ; isspace(c);c=getchar() );
    switch(c){
    case '+':
    scanf("%d", &cx);
    if( t_find(root,cx) == NULL) /*se il punto non c'e nell'albero, allora inseriscilo*/
    root = t_insert(root,cx);
    break;
    case 'h': /*stampa l'altezza dell'albero */
    printf("\n");
    h=t_height(root);
    printf("%d\n", h);
    break;
    case 'm':
    printf("\n");
    m=t_min(root);
    printf("%d\n", m->key);
    break;
    case 'M':
    printf("\n");
    M=t_max(root);
    printf("%d\n", M->key);
    break;

    }
    }while(c!='q' && c!= 'Q');

    return 0;
    }


    Ti consiglio di compilarlo e vedere come funziona, così puoi avere un'idea.

  8. #8
    Utente di HTML.it
    Registrato dal
    Aug 2004
    Messaggi
    17
    ciao, grazie x il codice.. xò ho avuto un'altra illuminazione :master:

    non è del tutto vero ke qnd si parla di grafi ci si riferisce agli alberi, in quanto qst ultimi sono grafi particolari.. ovvero i grafi connessi e aciclici.

    credo ke mi venga rikiesta prima una rappresentazione del grafo.. quindi stavo pensando di utilizzare le LISTE DI ADIACENZA concatenate o sequenziali..
    dopodikè effettuare una visita o mediante la ricerca in profondità o in ampiezza...

    Ora se non sbaglio credo di dover individuare il percorso con distanza max da s.. quindi utilizzare del codice ke sia l'inverso
    (diciamo) dell'algoritmo di Dijkstra (algoritmo ke individua il percorso minimo)...

    Qst è quanto ho capito...

  9. #9
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    Il codice che ti è stato proposto in effetti riguarda gli alberi, e nenache alberi qlsiasi, ma alberi binari radicati, in cui è presente cioè una radice e ogni nodo ha al piu due figli (destro e sinistro). Iniza a implementare il codice per la rappresentazione del grafo orientato e poi pensa all'algoritmo per risolvere il problema; molsto probabilmente si basera su una visita del grafo,


  10. #10
    STRUTTURE DATI e LABORATORIO II
    Esercitazione n° 18

    Distanza tra nodi di un grafo


    Ricordiamo che in un grafo orientato , dati due nodi s e v , si dice che v è raggiungibile da s se esiste un cammino da s a v e, in questo caso, la distanza di v da s è la lunghezza del più corto cammino da s a v.

    Scrivere un algoritmo che, dato un grafo orientato rappresentato mediante liste di adiacenza, determini per ogni nodo l’insieme dei nodi raggiungibili da s che si trovano a distanza massima da s.


    Suggerimento Si può generalizzare determinando, per ogni nodo del grafo, i nodi che si trovano a distanza 1, poi quelli a distanza 2, etc….sino a determinare quelli a distanza massima.


    Buon lavoro
    !
    codice:
     #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    
    #define TRUE 1
    #define FALSE 0
    
    typedef short int Bool;
    
    //------GRAFO----------
    typedef struct vert
    {
    	int vertice;
       struct vert *next;
    }Vert;
    typedef Vert* pVert;
    pVert *Grafo;
    Bool *Visitato;
    int CreaGrafoOrientato();
    void Distanze(int n);
    int AmpiezzaModificata(int v,int buf[]);
    //---------------------
    
    //-----------CODA--------------
    typedef struct ele
    {
    	int vertice;
    	struct ele *next;
    }Ele;
    typedef Ele* pEle;
    void AddCoda(pEle *davanti,pEle* dietro,int item);
    int DelCoda(pEle *davanti,pEle* dietro);
    //-----------------------------
                                  //FUNZIONI AUSILIARIE
    void FreeMem(int n);       //libera la memoria delle liste di adiacenza
    pVert Inserisci(pVert t); //inserisce un lato orientato
    void *myalloc(int n);
    int Menu();
    main()
    {
       int n=0,choice;
       do
       {
          choice=Menu();
          if(choice=='1'||choice=='2'||choice=='3')
       		switch(choice)
          	{
             	case '1': //crea
                	clrscr();
                   if(n)	FreeMem(n);
                	n=CreaGrafoOrientato();
                   Visitato=(Bool*)myalloc(n*sizeof(Bool));
                   printf("\nPremi un tasto.");
                   getch();
                   break;
               	case '2': //Nodi a distanza massima per ogni nodo
                	clrscr();
                   if(n)	Distanze(n);
                   else printf("Crea il grafo prima!!!");
                   printf("\nPremi un tasto.");
                   getch();
                	break;
               	default: //termina
                	clrscr();
                	printf("Arrivederci!!");
             }
       }while(choice!='3');
       if(n)	FreeMem(n);
       free(Grafo);
    	fflush(stdin);
       getchar();
    }
    int Menu()
    {
    	//stampa il menu'
    	clrscr();
       printf("\n\t\t\tMENU");
      	printf("\n\n\t\t(1)Crea il grafo orientato\n\n");
      	printf("\t\t(2)Nodi a distanza massima\n\n");
       printf("\t\t(3)Termina\n");
       return getch();
    }
    void *myalloc(int n)
    {
    	void *p=malloc(n);
       if(!p)
       {
       	printf("\nErrore malloc!!");
          fflush(stdin);
       	getchar();
       }
       return p;
    }
    
    pVert Inserisci(pVert list,int i)
    {
    	//inserisce un vertice nella lista di adiacenza di un'altro se esso non è già presente
    	pVert temp,prev,t;
       prev=t=list;
       while(t&&t->vertice!=i)//cerca il vertice memorizzando il precedente
       {
       	prev=t;
          t=t->next;
       }
       if(!t) //non c'era quindi possiamo inserire
       {
       	temp=(pVert)myalloc(sizeof(Vert));
          temp->next=NULL;temp->vertice=i;
          if(!list)	list=temp;//la lista era vuota
          else prev->next=temp;//c'era almeno un elemento
       }
       return list;
    }
    int CreaGrafoOrientato(void)
    {
    	//E' uguale a quella usata per creare i lati nei grafi non orintati dell'eserc precedente
       //con la differenza che i lati sono orientati quindi la funzione inserisci viene
       //chiamata una sola volta (per inserire il secondo vertice nella lista del primo)
    	int a,b,n,i;
    	do
       {
    		printf("Introduci il numero di vertici del grafo (minimo uno),verranno "
    			"creati tutti i vertici con etichetta da zero al numero che hai specificato - 1:\n");
          scanf("%d",&n);
       }while(n<1);
       Grafo=(pVert *)myalloc(n*sizeof(pVert));
       for(i=0;i<n;i++) Grafo[i]=NULL;
       printf("\nOra introduci i lati del grafo come coppie  ordinate di vertici (prima il vertice di partenza dell'arco)\nPremi un tasto");
       getch();
       clrscr();
       while(1)
       {
       	clrscr();
    		printf("Introduci due interi separati da uno spazio"
                 "(uno dei valori uguale a -1 termina):\n");
          scanf("%d %d",&a,&b);
          if(a==-1||b==-1)	break;  //si vuole smettere di inserire lati
          else if(a<0||a>n-1||b<0||b>n-1)//una coppia deve essere di vertici validi
          {
          	printf("Uno o entrambi i vertici della coppia non appartengono al grafo!\n"
                    "Premi un tasto");
             continue;
          }
          Grafo[a]=Inserisci(Grafo[a],b);//crea un lato orientato
       }                                          
       return n;
    }
    
    void Distanze(int n)
    {
    	//per ogni vertice stampa i vertici a distanza massima.Le distanze dei vertici da quello
       //di partenza (ruolo svolto a tutno da tutti i vertici) sono memorizzate in 'buf' dalla
       //funzione ampiezza modificata che rende anche il valore della distanza massima
    
    	int i,j,maxdist; //maxdist riceve il valore corrispondente alla distanza massima
       int *buf=(int*)myalloc(n*sizeof(int));//viene riempito con le distanze
    	for(i=0;i<n;i++)
       	{
             for(j=0;j<n;j++) {Visitato[j]=FALSE;buf[j]=-1;}//reinizializzazione dei vettori di supporto
             maxdist=AmpiezzaModificata(i,buf);
       		if(maxdist) printf("Nodi a distanza massima(cioe' %d) da %d :\n",maxdist,i);
             else printf("Nessun vertice e' raggiungibile da %d",i);
             for(j=0;j<n;j++) if(buf[j]==maxdist)	printf("%d ",j);//stampa i vertici dell'ultimo livello
             printf("\n\n");
       	}
    }
    
    int AmpiezzaModificata(int v,int buf[])
    {
    	/*Effettua una visita in ampiezza ma senza stampare nulla, soltanto classificando i nodi
         visitati per distanza da v e memorizzando tali distanze in buf.la distanza massima+1
         rimane memorizzata nella variabile livello alla fine della visita.
         La divisione dei nodi per livello è realizzata dal ciclo while più interno.
         Il primo livello è costiuito dai noi della lista di adiacenza di v,il secondo dai
         nodi delle liste di adiacenza di ognuno di essi non ancora visitati,il terzo dai nodi
         delle liste di adiacenza di questi ultimi non ancora visitati,e così via...
         L'idea è di tenere aggionata una variabile aux che memorizzi l'ultimo vertice del
         livello corrente.La prima volta aux coincide col vertice di partenza,la seconda con
         l'ultimo vertice della sua lista di adiacenza,la terza con l'ultimo vertice della lista
         di adiacenza dell'aux precedente,e così via..
         Nel test del ciclo interno aux viene confrontato con 'v',cioè con l'ultimo vertice
         estratto dalla coda (che non vi si trova più quindi).in altre parole il ciclo while
         interno non fa che ritardare l'incremento di 'livello' a quando dalla coda viene
         estratto aux,quando ciò avviene aux viene aggiornato con 'dietro->vertice',che è proprio
         l'ultimo vertice non visitato della lista di aux (perchè v==aux è già stato estratto e i
         suoi vertici adiacenti già accodati).
         Il problema del primo confronto,che deve sempre avere v!=aux (altrimenti non si comincia
         il ciclo) viene risolto dando a v un valore non accettabile per l'immissione dei vertici
         del grafo quando lo si crea,cioè -1.
         OSSERVAZIONE:'livello' viene incrementato una volta in più perchè l'algoritmo non
         può sapere a priori di trovarsi all'ultimo livello,cioè che per l'ultimo aux estrarrà
         dalla coda solo vertici con liste di adiacenza già visitate.
       */
    	pEle davanti,dietro;
       int aux,livello=0;
       pVert w;
       davanti=dietro=NULL;
       Visitato[v]=TRUE;
       AddCoda(&davanti,&dietro,v);
       v=-1;
       while(davanti)//finchè la coda non è vuota
       {
          aux=dietro->vertice;//ultimo vertice del livello
          livello++;
         	while(v!=aux)//finchè non hai estratto l'ultimo vertice del livello
          {
          	v=DelCoda(&davanti,&dietro);
          	for(w=Grafo[v];w;w=w->next)
          		if(!Visitato[w->vertice])
             	{
                   buf[w->vertice]=livello;// memorizza il livello attuale
                	Visitato[w->vertice]=TRUE;//contrassegna come visitato
                	AddCoda(&davanti,&dietro,w->vertice);//accoda
             	}
       	}
       }
       return livello-1;//perchè livello viene necessariamente incrementato una volta in più
    }
    void FreeMem(int n)
    {
    	//libera la memoria di tutte le liste di adiacenza
    	pVert temp,t;int i;
       for(i=0;i<n;i++)
       {
       	t=Grafo[i];
       	while(t)
       	{
       		temp=t;
          	t=t->next;
          	free(temp);
       	}
          Grafo[i]=NULL;
       }
    }
    void AddCoda(pEle *davanti,pEle* dietro,int item)
    {
    	//Aggiunge a una coda implementata con una lista concatenata
       //la coda con questa implementazione non ha limiti di spazio (tutta la memoria al limite)
    	pEle p=(pEle)myalloc(sizeof(Ele));
       p->next=NULL;
       p->vertice=item;
       if(!*davanti) *davanti=p; //la coda era vuota
       else (*dietro)->next=p;//c'era almeno un elemento
       (*dietro)=p; //si aggiorna sempre dietro
    }
    int DelCoda(pEle *davanti,pEle* dietro)
    {
    	//cancella da una coda implementata con una lista concatenata
    	int item;pEle temp;
    	if(!*davanti)	return -1; //coda vuota
       item=(*davanti)->vertice;
       temp=(*davanti);
       *davanti=(*davanti)->next;//cancellazione in testa
       free(temp);
       if(!*davanti) *dietro=NULL;//non è strettamente necessario perchè l'inserimento
                                  //aggiorna sempre *dietro senza controllarlo
       return item;
    }
    Il centro dell'attenzione non è sempre un buon posto in cui trovarsi

    Mai discutere con uno stupido, la gente potrebbe non capire la differenza. (O. W.)

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.