Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Pseudocódigo:
i: = 1;
N: = tamanho do gráfico de entrada, o número de vértices
while (i <N) do
escolhe a borda peso mínimo entre todos um que ainda não foram escolhidos e são incidentes alguém que já faz parte da
produção;
se a saída ainda está vazia, ou seja, estamos na primeira iteração, então escolhe a ponta para baixo peso
fim se;
se A não é um ciclo com aqueles que fazem parte da saída, então A acrescentar à saída;
i: = i + 1;
fim se;
fim while;
Neste caso, podemos observar que o algoritmo de Prim a cada iteração constrói uma árvore que cresce até completar a
árvore geradora mínima do grafo de entrada.
Algoritmo de Prim implementado em JAVA:
import java.util.Scanner;
class Prim {
return false;
}
Leitura();
while(n_acabou){
int menor= 10; // Maior peso das arestas.
int aux= 0;
if(cont == vertice)
n_acabou = false;
System.out.print("\n\nCustos: [");
for(int ct=0; ct< vertice-1; ct++){
total= total+custos[ct];
System.out.print(" "+ custos[ct]);
}
System.out.print("]");
return total;
}
public static void main(String[] args){
System.out.println("\n\nCusto Total: "+ setPrim());
}
}
Algoritmo de Kruskal
Pseudocódigo:
i: = 1;
N: = tamanho do gráfico de entrada, o número de vértices
while (i <N) do
escolhe a borda peso mínimo entre todos um que ainda não foram escolhidos;
se A não é um ciclo com aqueles que fazem parte da saída, então
A acrescenta à saída;
i: = i + 1;
Fim se;
fim while;
Portanto, como observamos, o algoritmo de Kruskal irá gerar florestas diferentes, com arestas que vai selecionar e depois
são unidos para formar a árvore geradora mínima.
Kruskal() {
// Constructor
nodes = new HashSet[MAX_NODES]; // Cria matriz de componentes
allEdges = new TreeSet(new Edge()); // Cria fila de prioridade vazia
allNewEdges = new Vector(MAX_NODES); // Cria vetor para as bordas da arvore minima
geradora.
}
if (nodes[to] == null) {
// Cria um conjunto de componentes para os nós
nodes[to] = new HashSet(2*MAX_NODES);
nodes[to].add(new Integer(to));
}
line = buff.readLine();
}
buff.close();
} catch (IOException e) {
//
}
}
if (nodesAreInDifferentSets(curEdge.from, curEdge.to)) {
// System.out.println("Os nós estão em grupos diferentes...");
HashSet src, dst;
int dstHashSetIndex;
allNewEdges.add(curEdge);
// Adicionar nova aresta a arvore geradora mínima
} else {
// System.out.println("Os nós estão no mesmo conjunto...não há nada a fazer
aqui");
}
} else {
// Este é um problema sério
System.out.println("TreeSet should have contained this element!!");
System.exit(1);
}
}
}
private boolean nodesAreInDifferentSets(int a, int b) {
// retorna verdadeira se os nós do grafo (a,b) forem diferentes
// components ligados, ou seja, conjunto de ‘a’ é diferente
// do que para 'b'
return(!nodes[a].equals(nodes[b]));
}
if (cost1<cost2)
return(-1);
else if (cost1==cost2 && from1==from2 && to1==to2)
return(0);
else if (cost1==cost2)
return(-1);
else if (cost1>cost2)
return(1);
else
return(0);
}
public boolean equals(Object obj) {
// usado para comparação ao incluir e remover operações
Edge e = (Edge) obj;
return (cost==e.cost && from==e.from && to==e.to);
}
}
}
Algoritmo de Dijkstra
Pseudocódigo:
custo[0..N] = INF
foi = {}
custo[INI] = 0
foi = foi+{INI} /* uma notação para: INI foi incluído no conjunto foi */
k = INI
/* escolhe o vértice não pertencente a foi, mas que possui menor custo */
k = vértice tal que custo[k] == min(custo[i]),
sendo i um vértice não/span > pertencente a foi
aux = custo[k]
foi = foi+{aux}
}
Exemplos
Observe este exemplo abaixo, mostrando passo-a-passo o Dijkstra rodando. Tente acompanhar observando o pseudo-
código:
Notas:
- o conjunto foi é simbolizado pelos vértices em vermelho;
- os custos custo[i] estão escritos dentro dos vértices;
- ini = 1 e fim = 6.
//vertice inicial
private static String u;
//conjunto auxiliar T de vertices
private static ArrayList T = new ArrayList();
//infinito
private static final int infi = 100000000;
//conjunto V de vertices
private static ArrayList V = new ArrayList();
//Matriz de adjacencia [lin][col] , -1 senao existe aresta e > -1 = peso
private static long mAdj[][];
//distancia de u a v, L[] sincronizado com V
private static long L[];
//---------------------------------------------------------------
//---------------------------------------------------------------
try{
}
catch (FileNotFoundException e){
System.out.println("erro: Arquivo " + fname + " n 㯼 encontrado ");
}
catch (IOException e) {
System.out.println("erro: " + e);
}
catch (IndexOutOfBoundsException e) {
System.out.println("Arquivo " + fname + " invalido.");
}
//---------------------------------------------------------------
int i=0;
String aux = new String("");
while (i vert.length()) {
if (vert.charAt(i) != ',')
aux += vert.charAt(i);
else {
V.add(aux.trim());
aux = "";
}
i++;
}
V.add(aux.trim());
}
//---------------------------------------------------------------
//inicializa
for (int x=0; x V.size(); x++)
for (int y=0; y V.size(); y++)
mAdj[x][y] = infi;
int i=0;
String aux = new String("");
int r, s, p;
while (i arestas.length()) {
if (arestas.charAt(i) != '\n')
aux += arestas.charAt(i);
else{
//aux contem "v1-v2=p"
aux = aux.trim();
//posicao de v1 em V
r = V.indexOf(aux.substring(0, aux.indexOf('-')).trim());
//posicao de v2 em V
s = V.indexOf(aux.substring(aux.indexOf('-')+1, aux.indexOf('=')).trim());
//peso p de v1 para v2
p = Integer.parseInt(aux.substring(aux.indexOf('=')+1).trim());
//marca aresta (v1, v2) em mAdj
mAdj[r][s] = p;
aux = "";
}
i++;
}
aux = aux.trim();
//posicao de v1 em V
r = V.indexOf(aux.substring(0, aux.indexOf('-')).trim());
//posicao de v2 em V
s = V.indexOf(aux.substring(aux.indexOf('-')+1, aux.indexOf('=')).trim());
//peso p de v1 para v2
p = Integer.parseInt(aux.substring(aux.indexOf('=')+1).trim());
//marca aresta (v1, v2) em mAdj
mAdj[r][s] = p;
//---------------------------------------------------------------
System.out.print("\n");
}
//---------------------------------------------------------------
//calcula o L(v)
private static boolean buildL() {
try {
//posicao de u na matriz de adj
int pos = V.indexOf(u);
//L tem dimensao n
L = new long[V.size()];
//L(u)
L[pos] = 0;
}
catch (IndexOutOfBoundsException e) {
System.out.println(u + " nao esta em V");
return false;
}
return true;
//---------------------------------------------------------------
//imprime L(v)
private static void printL() {
System.out.print("\n");
for (int i=0; i V.size(); i++) {
if (L[i] != infi)
System.out.print(" " + L[i]);
else
System.out.print(" -");
}
}
//imprime L(v)
private static void printL2() {
System.out.print("\n");
for (int i=0; i V.size(); i++)
if (L[i] != infi)
System.out.println("L(" + V.get(i) + ")= " + L[i]);
else
System.out.println("L(" + V.get(i) + ")= infi");
}
//---------------------------------------------------------------
//constroi L(v)
if (!buildL()) return;
if (debug)
for (int k=0; k V.size(); k++)
System.out.print(" " + V.get(k));
while (!T.containsAll(V)) {
if (debug) printL();
String vLinha = findMinL();
T.add(vLinha);
updateL(vLinha);
}
if (debug)
System.out.println("\nfim");
else
printL2();
//---------------------------------------------------------------
//---------------------------------------------------------------
int i;
//V2 = V
ArrayList V2 = new ArrayList(V);
//remove T de V = V2
for (i=0; i T.size(); i++)
V2.remove(V2.indexOf(T.get(i)));
for (i=0; i V2.size(); i++) {
String vaux = (String)V2.get(i);
long w = L[V.indexOf(vLinha)] + mAdj[V.indexOf(vLinha)][V.indexOf(vaux)];
if (w L[V.indexOf(vaux)])
L[V.indexOf(vaux)] = w;
}
//---------------------------------------------------------------
//retorna v nao pertencente a T tal que L(v) 頭 inimo
private static String findMinL() {
int i;
//V2 = V
ArrayList V2 = new ArrayList(V);
//remove T de V = V2
for (i=0; i T.size(); i++)
V2.remove(V2.indexOf(T.get(i)));
if (L[V.indexOf(vaux)] = pmin) {
v = vaux;
pmin = L[V.indexOf(vaux)];
}
return v;
}
import java.io.*;
import java.util.*;
//vertice inicial
private static String u;
//conjunto auxiliar T de vertices
private static ArrayList T = new ArrayList();
//infinito
private static final int infi = 100000000;
//conjunto V de vertices
private static ArrayList V = new ArrayList();
//Matriz de adjacencia [lin][col] , -1 senao existe aresta e > -1 = peso
private static long mAdj[][];
//distancia de u a v, L[] sincronizado com V
private static long L[];
//---------------------------------------------------------------
//---------------------------------------------------------------
try{
}
catch (FileNotFoundException e){
System.out.println("erro: Arquivo " + fname + " n 㯼 encontrado ");
}
catch (IOException e) {
System.out.println("erro: " + e);
}
catch (IndexOutOfBoundsException e) {
System.out.println("Arquivo " + fname + " invalido.");
}
//---------------------------------------------------------------
if (vert.charAt(i) != ',')
aux += vert.charAt(i);
else {
V.add(aux.trim());
aux = "";
}
i++;
}
V.add(aux.trim());
}
//---------------------------------------------------------------
//inicializa
for (int x=0; x V.size(); x++)
for (int y=0; y V.size(); y++)
mAdj[x][y] = infi;
int i=0;
String aux = new String("");
int r, s, p;
while (i arestas.length()) {
if (arestas.charAt(i) != '\n')
aux += arestas.charAt(i);
else{
//aux contem "v1-v2=p"
aux = aux.trim();
//posicao de v1 em V
r = V.indexOf(aux.substring(0, aux.indexOf('-')).trim());
//posicao de v2 em V
s = V.indexOf(aux.substring(aux.indexOf('-')+1, aux.indexOf('=')).trim());
//peso p de v1 para v2
p = Integer.parseInt(aux.substring(aux.indexOf('=')+1).trim());
//marca aresta (v1, v2) em mAdj
mAdj[r][s] = p;
aux = "";
}
i++;
}
aux = aux.trim();
//posicao de v1 em V
r = V.indexOf(aux.substring(0, aux.indexOf('-')).trim());
//posicao de v2 em V
s = V.indexOf(aux.substring(aux.indexOf('-')+1, aux.indexOf('=')).trim());
//peso p de v1 para v2
p = Integer.parseInt(aux.substring(aux.indexOf('=')+1).trim());
//marca aresta (v1, v2) em mAdj
mAdj[r][s] = p;
//---------------------------------------------------------------
System.out.print("\n");
}
//---------------------------------------------------------------
//calcula o L(v)
private static boolean buildL() {
try {
//posicao de u na matriz de adj
int pos = V.indexOf(u);
//L tem dimensao n
L = new long[V.size()];
//L(u)
L[pos] = 0;
}
catch (IndexOutOfBoundsException e) {
System.out.println(u + " nao esta em V");
return false;
}
return true;
//---------------------------------------------------------------
//imprime L(v)
private static void printL() {
System.out.print("\n");
for (int i=0; i V.size(); i++) {
if (L[i] != infi)
System.out.print(" " + L[i]);
else
System.out.print(" -");
}
}
//imprime L(v)
private static void printL2() {
System.out.print("\n");
for (int i=0; i V.size(); i++)
if (L[i] != infi)
System.out.println("L(" + V.get(i) + ")= " + L[i]);
else
System.out.println("L(" + V.get(i) + ")= infi");
}
//---------------------------------------------------------------
u = vInicial;
//constroi L(v)
if (!buildL()) return;
if (debug)
for (int k=0; k V.size(); k++)
System.out.print(" " + V.get(k));
while (!T.containsAll(V)) {
if (debug) printL();
String vLinha = findMinL();
T.add(vLinha);
updateL(vLinha);
}
if (debug)
System.out.println("\nfim");
else
printL2();
//---------------------------------------------------------------
private static void printV() {
System.out.print("\n");
for (int k=0; k V.size(); k++)
System.out.print(" " + V.get(k));
//---------------------------------------------------------------
int i;
//V2 = V
ArrayList V2 = new ArrayList(V);
//remove T de V = V2
for (i=0; i T.size(); i++)
V2.remove(V2.indexOf(T.get(i)));
if (w L[V.indexOf(vaux)])
L[V.indexOf(vaux)] = w;
}
//---------------------------------------------------------------
//retorna v nao pertencente a T tal que L(v) 頭 inimo
private static String findMinL() {
int i;
//V2 = V
ArrayList V2 = new ArrayList(V);
//remove T de V = V2
for (i=0; i T.size(); i++)
V2.remove(V2.indexOf(T.get(i)));
if (L[V.indexOf(vaux)] = pmin) {
v = vaux;
pmin = L[V.indexOf(vaux)];
}
return v;
}
REFERÊNCIAS
Algoritmos simples de Kruskal y Prim. Disponível em: < http://tracer.lsi.upc.es/kp/SimpleAlgorithmsPage.htm#Prim>
Acesso em 03 mar. 2011.