Graph(intv){V=v;adj=newLinkedList[v];for(inti=0;i<v;++i)adj[i]=newLinkedList();}voidaddEdge(intv,intw){adj[v].add(w);}voidBFS(ints){booleanvisited[]=newboolean[V];LinkedList<Integer>queue=newLinkedList<Integer>();visited[s]=true;queue.add(s);while(queue.size()!=0){s=queue.poll();System.out.print(s+" ");Iterator<Integer>i=adj[s].listIterator();while(i.hasNext()){intn=i.next();if(!visited[n]){visited[n]=true;queue.add(n);}}}}publicstaticvoidmain(Stringargs[]){Graphg=newGraph(4);g.addEdge(0,1);g.addEdge(0,2);g.addEdge(1,2);g.addEdge(2,0);g.addEdge(2,3);g.addEdge(3,3);System.out.println("A seguir está a primeira travessia em largura "+"(starting from vertex 2)");g.BFS(2);}
O grafo da imagem possui 6 vértices porque você criou só com 4?
Os vértices do grafo da imagem são representados por letras, por que você está usando números?
L
loudhp
Já tentei usar letras mas não funciona
L
loudhp
O grafo da imagem possui 6 vértices porque você criou só com 4? Ah sim, não tinha observado esse detalhe
S
staroski
Você copiou essa classe de alguém?
Porque implementou ela esperando receber os vértices na forma de int?
L
loudhp
foi a forma que eu conseguir declarando int na variável V, tambem tentei usar uma string mesmo assim não vai
D
davidbuzatto
Pq grafos “didáticos” não crescem. A ideia é criar com tamanho fixo mesmo e focar nos algoritmos.
D
Solucao aceita
davidbuzatto
Tá aí:
importjava.util.LinkedList;importjava.util.Queue;/** * * @author David */publicclassGraph{privateintV;privateLinkedList<Integer>adj[];Graph(intv){V=v;adj=newLinkedList[v];for(inti=0;i<v;++i){adj[i]=newLinkedList();}}voidaddEdge(intv,intw){adj[v].add(w);adj[w].add(v);}voidBFS(ints){booleanvisited[]=newboolean[V];Queue<Integer>queue=newLinkedList<>();visited[s]=true;queue.add(s);while(!queue.isEmpty()){s=queue.poll();System.out.println(s+" ");for(intn:adj[s]){if(!visited[n]){visited[n]=true;queue.add(n);}}}}publicstaticvoidmain(Stringargs[]){Graphg=newGraph(4);g.addEdge(0,1);g.addEdge(0,2);g.addEdge(1,2);g.addEdge(2,3);System.out.println("A seguir está a primeira travessia em largura "+"(starting from vertex 2)");g.BFS(2);}}
Ao adicionar uma aresta em um grafo não dirigido, vc precisa fazer a ida e a volta. Veja o que mudou no método addEdge. Se já existe ida e volta, a chamada g.addEdge(2, 0); insere um “anomalia” no seu grafo, chamada de aresta paralela. Ela pode existir, não há problema, só vai fazer seu algoritmo demorar um pouco mais. Outra anomalia do seu exemplo, que tbm pode existir é o laço/loop criado na chamada g.addEdge(3, 3); que não terá efeito algum sobre a busca em largura, visto que o vértice atual será marcado como visitado assim que for alcançado. Na ordem em que estão feitas as inserções das arestas no meu exemplo, removendo as duas chamadas acima, você terá o array adj populado da seguinte forma:
adj[0]={2,1}adj[1]={2,0}adj[2]={3,1,0}adj[3]={2}
Os valores entre chaves representam as listas usadas. Lembre-se que as inserções são feitas na cauda/rabo/fim da lista e são feitas nas duas direções.
Você inicia a busca pelo vértice 2, então terá algo assim durante a execução:
// iníciovisited=F|F|F|F(F=false,T=true)0123queue={}// inserção da fonte na fila e marcação de visitadovisited=F|F|T|F0123queue={2}// a fila está vazia? não!s=2queue={}adjacentesde2:3:visitado?não!
visited[3]=true;=>visited=F|F|T|Tqueue={3}01231:visitado?não!
visited[1]=true;=>visited=F|T|T|Tqueue={1,3}01230:visitado?não!
visited[0]=true;=>visited=T|T|T|Tqueue={0,1,3}0123// perceba que no seu exemplo, todos os vértices// já estão visitados e a árvore de busca em largura // gerada já está pronta (seu exemplo não a codifica, // se quiser eu complemento para vc.// a ideia da busca em largura é obter essa árvore e// os custos associados a quantidade de "pulos" que se// da de um vértice a outro, sendo algo parecido com um// algoritmo de menor caminho, mas sem pesos nas arestas// continuando...// a fila está vazia? não!s=3queue={0,1}adjacentesde3:2:visitado?sim!
// a fila está vazia? não!s=1queue={0}adjacentesde1:2:visitado?sim!
0:visitado?sim!
// a fila está vazia? não!s=0queue={}adjacentesde0:2:visitado?sim!
1:visitado?sim!
// a fila está vazia? sim!
Só fiquei com uma duvida, esse exemplo que você modificou está completo?
D
davidbuzatto
Sim, só que não é armazenada a árvore e as distâncias. Ele mostra na saída os vértices que estão sendo processados no momento que saem da fila. O ideal seria ter algo mais robusto do ponto de vista de utilidade. Veja o terceiro link que te passei. O array edgeTo armazena o caminho da árvore e o array distTo armazena as distâncias da fonte até o vértice em questão. Acho que foi vc que perguntou sobre busca em profundidade há alguns dias atrás não foi? A ideia é a mesma.
L
loudhp
Sim foi eu mesmo, ah entendi
S
staroski
Meu questionamento não foi o int no construtor, que determina a quantidade de vértices, mas o motivo de ele usar int para representar os vértices sendo que no desenho eles são representados por letras.
Se ele quisesse representar o grafo do desenho, sua classe Graph seria adaptada para funcionar com char ou String ao invés de int, poderia até fazer algo mais elaborado com uma classe Vertex para servir de container genérico.
Mas enfim, a ideia seria representar o grafo da imagem dessa forma:
Um dos motivos, o principal na verdade, é o acesso direto ao índice do array que armazena as listas de adjacências, pq a ideia é ter uma implementação “ótima” de um grafo. É claro, vc poderia fazer um mapeamento char → int, mas se há a necessidade de armazenar rótulos para os vértices a abordagem normal é usar uma tabela de símbolos para associar o vértice (inteiro) com o rótulo.
L
loudhp
“Usar uma tabela de símbolos para associar o vértice (inteiro) com o rótulo” Desse modo poderia usar string ?