Tive problemas para criar a lógica do solução desse problema se puderem me ajudar seria ótimo:
se tem um conjunto de nós em uma rede no qual todos devem ser interligados direta ou indiretamente, cada interligação entre nós tem um custo e é preciso dar a implementação mais barata através do modo de colocar as interligações:
Se eu não me engano isso é árvore geradora minima, da uma olhada em Prim ou Kruskal q esse problema morre.
[]s!
Leonardo Gloria
DavidUser
Tinha pensado em pegar
nó inicial, nó final e custo
como por exemplo:
(N é a sigla para Nó)
N1 a N2 custa 10
N1 a N3 custa 11
N2 a N3 custa 12
N1 a N4 custa 13
enumerar as posições:
(L é sigla para ligação)
L1: N1 a N2
L2: N1 a N3
L3: N2 a N3
L4: N1 a N4
(ligações possíveis)
depois testar as ligações de acordo o grupo com combinações iguais a 3 que é o mínimo de ligações para quatro nós
e comparar qual o grupo de ligações mais barato:
Sequência 1: L1 L2 L3
Sequência 2: L1 L2 L4
Sequência 3: L1 L3 L4
Sequência 4: L2 L3 L4
(demais sequências conforme o aumento do numero de nós)
custoL1 + custoL2 + custoL3 = custo da Sequência 1
custoL1 + custoL2 + custoL4 = custo da Sequência 2
custoL1 + custoL3 + custoL4 = custo da Sequência 3
custoL2 + custoL3 + custoL4 = custo da Sequência 4
Só não sei se a lógica está correta…
renamed
Isso se resume a um algoritmo ligado a grafo onde você precisa descobrir o caminho de menos custo a dois vértices distintos, não é isso?
Você pode usar algoritmos prontos: Prim e Kruskal como já disse nosso colega acima.
For a graph with V vertices E edges, Kruskal’s algorithm runs in O(E log V) time and Prim’s algorithm can run in O(E + V log V) amortized time, if you use a Fibonacci Heap.
Prim’s algorithm is significantly faster in the limit when you’ve got a really dense graph with many more edges than vertices. Kruskal performs better in typical situations (sparse graphs) because it uses simpler data structures.
Se eu não me engano, para problemas como esse o pessoal prefere Kruskal, mas não estou muito certo.
Andre_Brito
Renato, a preferência por Kruskal pode ser pela facilidade de implementação. Prim, Prim Colorido e Boruvka, perto do Kruskal, pelo menos na minha opinião, são um pouco mais complexos de implementar.
Leonardo_Gloria
Exatamente! Se vc tiver pensando a nivel de competição e tentar comparar as possiveis soluções vai dar o famoso TLE!
[]s!
Leonardo Gloria
DavidUser
Decidi utilizar o algoritmo de Prim, sabem um bom exemplo de implementação para o algoritmo?
Paulo_Silveira
Eu iria sugerir Kruskal tambem… basta voce ordenar todas as arestas e sempre ir pegando a menor e ver se os dois componentes ja estao conectados. Se nao estao, adiciona a aresta e conecta os dois, ai verifica a proxima aresta. Eu era bom de Kruskal na maratona de programacao :).
E, se voce nao precisa de velocidade, nao precisa implementar o union-find (apesar de quem em Java fica bem facil com HashSets)
Leonardo_Gloria
Pow Paulo n sabia que você era maratonista se não trocava umas idéias contigo após a sua palestra sobre JPA no Jboss in bossa!
=)
[]s!
Leonardo Gloria
DavidUser
Obrigado pela ajuda pessoal!
Usando o algoritmo de Prim fiz meu próprio código na unha e até ficou legal.
DavidUser
Implementei uma classe Grafos que cria um grafo em um tipo de matriz e encontra o percurso mínimo:
/* * To change this template, choose Tools | Templates * and open the template in the editor. */packageredeotica;importjava.util.ArrayList;importjava.util.List;importjava.util.Scanner;/** * * @author David Kennedy S. A. */publicclassGrafo{privateintnumeroDeVertices,numeroDeArestas;privateint[][]arestasAComparar=newint[100][3];//CRIAR METODO MAIS EFICIENTE PARA DEFINIR NUMERO DE ARESTAS MÁXIMO A COMPARARprivateintindiceDoArray=0;privateboolean[]vertices;privateint[][]arestas;publicGrafo(intquantidadeDeVertices,intquantidadeDeArestas){numeroDeVertices=quantidadeDeVertices;numeroDeArestas=quantidadeDeArestas;vertices=newboolean[quantidadeDeVertices+1];//desconsiderar o vertice de indice 0arestas=newint[quantidadeDeArestas][3];//o numero de colunas é fixo "3"}privatevoidadicionaArestaParaComparar(intverticeInicial,intverticeFinal,intcomprimento){arestasAComparar[indiceDoArray][0]=verticeInicial;arestasAComparar[indiceDoArray][1]=verticeFinal;arestasAComparar[indiceDoArray][2]=comprimento;indiceDoArray++;}protectedvoidadicionaArestaParaComparar(int[]partida){for(inti=0;i<partida.length;i++){//corre as partidasfor(intj=0;j<numeroDeArestas;j++){if(arestas[j][0]==partida[i]&&vertices[arestas[j][1]]==false){adicionaArestaParaComparar(arestas[j][0],arestas[j][1],arestas[j][2]);}}}}privatevoidadicionaArestaParaComparar(Object[]partida){for(inti=0;i<partida.length;i++){//corre as partidasfor(intj=0;j<numeroDeArestas;j++){if(arestas[j][0]==partida[i]&&vertices[arestas[j][1]]==false){adicionaArestaParaComparar(arestas[j][0],arestas[j][1],arestas[j][2]);}if(arestas[j][1]==partida[i]&&vertices[arestas[j][0]]==false){adicionaArestaParaComparar(arestas[j][0],arestas[j][1],arestas[j][2]);}}}}protectedvoidlimpaArestasComparadas(){for(inti=0;i<arestasAComparar.length;i++){arestasAComparar[i][0]=0;arestasAComparar[i][1]=0;arestasAComparar[i][2]=0;}indiceDoArray=0;}privateint[]menorCaminho(){int[]aresta=newint[3];intcomp=9999999;for(inti=0;i<arestasAComparar.length&&arestasAComparar[i][2]!=0;i++){if(arestasAComparar[i][2]<comp){aresta[0]=arestasAComparar[i][0];aresta[1]=arestasAComparar[i][1];aresta[2]=arestasAComparar[i][2];comp=arestasAComparar[i][2];}}returnaresta;}protectedvoidimprimeMenorCaminho(){int[]aresta=menorCaminho();//troca aresta[1] e aresta[0] de lugar deixando sempre aresta[0] < aresta[1]intaux;if(aresta[0]>aresta[1]){aux=aresta[0];aresta[0]=aresta[1];aresta[1]=aux;}System.out.printf("%d %d %d\n",aresta[0],aresta[1],aresta[2]);}privatebooleanmarcaVerticeDoMenorCaminho(){int[]aresta=menorCaminho();//retorna "true" se o vertice inicial estiver marcadoif(vertices[aresta[0]]==true){vertices[aresta[1]]=true;returntrue;}else{returnfalse;}}protectedvoidimprimeSituacaoDosVertices(){for(inti=1;i<numeroDeVertices;i++)System.out.println("Vertice "+i+" = "+vertices[i]);}protectedvoidimprimeArestasParaComparação(){for(inti=0;i<10;i++){System.out.print(arestasAComparar[i][0]);System.out.print(" "+arestasAComparar[i][1]);System.out.println(" "+arestasAComparar[i][2]);}}publicvoidleEConstroiTabela(){Scannerscan=newScanner(System.in);for(inti=0;i<numeroDeArestas;i++){intx=scan.nextInt();//lê o nó inicial e coloca em contagem do 0inty=scan.nextInt();//lê o nó final e coloca em contagem do 0intz=scan.nextInt();//lê o custo ambientalarestas[i][0]=x;//atribui o indice do vertice inicialarestas[i][1]=y;//atribui o inice do vertice finalarestas[i][2]=z;//atribui o comprimento da aresta}}publicvoidencontraCaminhoMinimo(){List<Integer>partida=newArrayList<Integer>();partida.add(1);vertices[1]=true;for(inti=0;i<(numeroDeVertices-1);i++){adicionaArestaParaComparar(partida.toArray());imprimeMenorCaminho();partida.add(menorCaminho()[1]);marcaVerticeDoMenorCaminho();limpaArestasComparadas();}}}
agora é fácil usar uma classe com método principal para criar o grafo e encontrar o caminho mínimo
como por exemplo:
publicclassTestMainGrafo{publicstaticvoidmain(String[]args){Scannerscan=newScanner(System.in);intnumeroDeVertices,numeroDeArestas;System.out.print("Qual o numero de vertices? ");numeroDeVertices=scan.nextInt();System.out.print("Qual o numero de arestas? ");numeroDeArestas=scan.nextInt();System.out.println("Insira os valores da tabela:\n(vertice [espaço] vertice [espaço] comprimento)");Grafog=newGrafo(numeroDeVertices,numeroDeArestas);g.leEConstroiTabela();System.out.println("\nCaminho mínimo:\n");g.encontraCaminhoMinimo();}}
Exemplo de saída:
Qual o numero de vertices? 3
Qual o numero de arestas? 3
Insira os valores da tabela:
(vertice [espaço] vertice [espaço] comprimento)
1 2 10
2 3 10
3 1 10
Caminho mínimo:
1 2 10
1 3 10
DavidUser
ainda tem problemas para definir o tamanho de private int[][] arestasAComparar = new int[100][3];
na linha 19
DavidUser
Agora que o problema foi basicamente resolvido tenho problemas com o tamanho dos valores que o meu programa pode suporta… Alguma idéia de como aumentar sua capacidade para cálculos maiores