Beruflich Dokumente
Kultur Dokumente
Un ejemplo de rbol expandido mnimo. Cada punto representa un vrtice, el cual puede ser
un rbol por s mismo. Se usa el Algoritmo para buscar las distancias ms cortas (rbol
expandido) que conectan todos los puntos o vrtices.
Funciona de la siguiente manera:
se crea un bosque B (un conjunto de rboles), donde cada vrtice del grafo es un
rbol separado
se crea un conjunto C que contenga a todas las aristas del grafo
mientras C es no vaco
o eliminar una arista de peso mnimo de C
o si esa arista conecta dos rboles diferentes se aade al bosque, combinando
los dos rboles en un solo rbol
o en caso contrario, se desecha la arista
Contenido
[ocultar]
Paso 1: Con los arcos de G crear una lista L de arcos, en orden ascendente de peso. Los
arcos con el mismo peso son ordenados arbitrariamente.
Paso 2. Seleccionar el arco (i,j) que est al comienzo de L. Si ste forma un circuito en T no
se transfiere a T y se borra de L y se repite el paso 2. Si no forma circuito en T se transfiere
a T y se borra de L.
Limitaciones[editar]
Las nicas limitaciones que se presentan con el problema de la implementacin del
algoritmo de Kruskal es la creacin de un algoritmo adicional que nos compruebe que al
adicionar una arista al grafo no nos haga un ciclo.
El algoritmo implementado es el siguiente:
public boolean HayCiclo(Grafo g,Arco aVerificar,Nodo terminal,String N)
{
ArrayList<Enlace> aux=terminal.getEnlaces();
if(aux.size()==0)
return false;
if(terminal.existeEnlace(aVerificar.getInicial())!=-1)
return true;
for(int i=0;i<aux.size();i++)
{
Enlace nodo=aux.get(i);
if(nodo.getDestino().equals(N)==false)
if(
HayCiclo(g,aVerificar,g.getNodo(nodo.getDestino()),terminal.getNombre()))
return
true;
}
return false;
}
Solucin[editar]
En la implementacin del algoritmo de Kruskal en Java, se hizo uso de una estructura de
datos adicional llamada grafo y adicionalmente se implement una interfaz grfica.
Estructura Grafo[editar]
Clase Enlace[editar]
Clase Nodo[editar]
Hace referencia a un nodo del grafo, guardando un nombre y una serie de enlaces a otros
nodos.
import java.util.ArrayList;
import javax.swing.JOptionPane;
public class Nodo
{
private String nombre;
private ArrayList<Enlace> enlaces;
private int enlacesExistentes;
miEnlace = enlaces.get(posi);
return miEnlace.getPeso();
}
public String NodoPosicion(int posi)
{
Enlace miEnlace;
miEnlace = enlaces.get(posi);
return miEnlace.getDestino();
}
boolean eliminarEnlace(int posicion)
{
if (posicion >= 0 && posicion <= enlaces.size())
{
enlaces.remove(posicion);
enlacesExistentes--;
return true;
}
else
JOptionPane.showMessageDialog(null, "No hay
enlace en la posicion " + posicion);
return false;
}
}
Clase Arco[editar]
Guarda la referencia del nodo inicial, nodo terminal y peso de un determinado arco del
grafo.
public class Arco
{
private String inicial;
private String terminal;
private float peso;
public Arco(String ini, String ter, float pes)
{
inicial = ini;
terminal = ter;
peso = pes;
}
public float getPeso()
{
return peso;
}
public void setPeso(float peso)
{
this.peso = peso;
}
public String getInicial()
{
return inicial;
}
public void setInicial(String inicial)
{
this.inicial = inicial;
}
public String getTerminal()
{
return terminal;
}
public void setTerminal(String terminal)
{
this.terminal = terminal;
}
public String toString()
{
return "(" + inicial + ", " + terminal + ", " + peso +
")";
}
}
Clase Grafo[editar]
if(i==-1)
aristas.add(nuevo);
else
aristas.add(i,nuevo);
nodos.get(nodoInicial).agregarEnlace(nodoTerminal,peso);
nodos.get(nodoTerminal).agregarEnlace(nodoInicial,peso);
}
public boolean busarArista(Arco arco)
{
for(int i=0;i<aristas.size();i++)
{
Arco otro=aristas.get(i);
if(arco.getInicial().equals(otro.getInicial())&&arco.getTerminal().equals
(otro.getTerminal())&&arco.getPeso()==otro.getPeso())
{
aristas.remove(otro);
return true;
}
}
return false;
}
public int buscarIndice(float peso)
{
for(int i=0;i<aristas.size();i++)
{
if(peso<aristas.get(i).getPeso())
return i;
}
return -1;
}
public Hashtable getNodos()
{
return nodos;
}
public void setNodos(Hashtable<String,Nodo > muchos)
{
nodos=muchos;
}
public ArrayList<String> getNombres()
{
return nombres;
}
public Nodo getNodo(String nombre)
{
return (Nodo)nodos.get(nombre);
}
public ArrayList<Arco> getAristas() {
return aristas;
}
public void setAristas(ArrayList<Arco> aristas) {
this.aristas = aristas;
}
Interfaz Grfica[editar]
Clase Lienzo[editar]
Clase Punto[editar]
Permite dibujar un punto sobre el lienzo. Hace referencia a la posicin del punto sobre el
lienzo.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
public class Punto
{
private Point ubicacion;
private String nombre;
private Color colorPunto = Color.BLUE;
private static final int RADIO = 10;
public Punto(int x, int y, String nombre)
{
ubicacion = new Point(x, y);
this.nombre = nombre;
}
public void pintarPunto(Graphics g)
{
g.setColor(Color.BLACK);
g.drawString(nombre, ubicacion.x - 3, ubicacion.y - 3);
g.setColor(colorPunto);
g.fillOval(ubicacion.x, ubicacion.y, 10, 10);
}
public void pintarPunto(Graphics g, Color color)
{
g.setColor(Color.BLACK);
g.drawString(nombre, ubicacion.x - 3, ubicacion.y - 3);
g.setColor(color);
g.fillOval(ubicacion.x, ubicacion.y, 10, 10);
}
public boolean ecuacionDeCirculo(Point punto)
{
return (((punto.x - ubicacion.x) * (punto.x ubicacion.x) + (punto.y - ubicacion.y) * (punto.y - ubicacion.y)) <=
(RADIO * RADIO));
}
Clase Arista[editar]
Permite dibujar una arista entre dos puntos sobre el lienzo. Hace referencia a los puntos.
import
import
import
import
import
java.awt.Color;
java.awt.Graphics;
java.awt.Graphics2D;
java.awt.Point;
java.awt.geom.QuadCurve2D;
this.peso = peso;
}
public void pintarRecta(Graphics ga)
{
inicial = a.getUbicacion();
terminal = b.getUbicacion();
Graphics2D g = (Graphics2D) ga;
double a = (inicial.y - terminal.y);
double b = (inicial.x - terminal.x);
double m = a / b;
double grado = Math.atan(m);
switch (tipo)
{
case 0:
g.setColor(color);
g.drawLine(inicial.x + 5, inicial.y + 5,
terminal.x + 5, terminal.y + 5);
g.setColor(aux);
g.drawString(peso + "", (inicial.x +
terminal.x) / 2, (inicial.y + terminal.y) / 2);
break;
case 1:
g.setColor(color);
g.drawOval(inicial.x - 10, inicial.y 30, 30, 30);
g.setColor(aux);
g.drawString(peso + "", inicial.x - 3,
inicial.y - 30);
break;
case 2:
Point control = null;
if (grado > 0)
{
if (grado <= 45 && grado >= 0)
control = new
Point((inicial.x + terminal.x) / 2 - 10, (inicial.y + terminal.y) / 2 +
50);
if (grado <= 90 && grado > 45)
control = new
Point((inicial.x + terminal.x) / 2 + 50, (inicial.y + terminal.y) / 2 +
10);
}
else
{
if (grado >= -45 && grado <= 0)
control = new
Point((inicial.x + terminal.x) / 2 - 30, (inicial.y + terminal.y) / 2 10);
if (grado >= -90 && grado < -45)
control = new
Point((inicial.x + terminal.x) / 2 - 50, (inicial.y + terminal.y) / 2 10);
}
Point tempInicial = new Point(inicial.x +
5, inicial.y + 5),
tempFinal = new Point(terminal.x + 5,
terminal.y + 5);
QuadCurve2D.Double quad = new
QuadCurve2D.Double();
quad.setCurve(tempInicial, control,
tempFinal);
g.setColor(aux);
g.drawString(peso + "", control.x,
control.y);
g.setColor(color);
g.draw(quad);
break;
}
}
public Point getUbicacion()
{
return ubicacionExt;
}
public int getTipo()
{
return tipo;
}
public Arco getArista()
{
return arista;
}
public void setArista(Arco arista)
{
this.arista = arista;
}
public void getColor()
{
color = new Color(0, 128, 128);
aux = Color.RED;
}
public void setColor(Color color)
{
if (color.equals(new Color(0, 128, 128)))
aux = Color.RED;
else
aux = Color.BLUE;
this.color = color;
}
}
Paquete Principal[editar]
Clase AlgoritmoKruskal[editar]
//Implementacin del Algoritmo voraz de Kruskal.
import java.util.ArrayList;
public class AlgoritmoKruskal
{
@SuppressWarnings("unchecked")
public Grafo aplicarKruskal(Grafo grafo)
{
Grafo rbol=new Grafo();
ArrayList<String> nodos=grafo.getNombres();
for(int j=0;j<nodos.size();j++)
{
rbol.ingresarNodo(nodos.get(j));
}
ArrayList<Arco>
L=(ArrayList<Arco>)grafo.getAristas().clone();
Arco pro=L.get(0);
rbol.adicionarEnlace(pro.getInicial(),
pro.getTerminal(), pro.getPeso());
L.remove(pro);
while(L.size()!=0)
{
pro=L.get(0);
if(HayCiclo(rbol,
pro,rbol.getNodo(pro.getTerminal()) , pro.getTerminal())==false)
rbol.adicionarEnlace(pro.getInicial(),
pro.getTerminal(), pro.getPeso());
L.remove(pro);
}
return rbol;
}
public boolean HayCiclo(Grafo g,Arco aVerificar,Nodo
terminal,String N)
{
ArrayList<Enlace> aux=terminal.getEnlaces();
if(aux.size()==0)
return false;
if(terminal.existeEnlace(aVerificar.getInicial())!=-1)
return true;
for(int i=0;i<aux.size();i++)
{
Enlace nodo=aux.get(i);
if(nodo.getDestino().equals(N)==false)
if(
HayCiclo(g,aVerificar,g.getNodo(nodo.getDestino()),terminal.getNombre()))
return true;
}
return false;
}
}
VENTANA[editar]
import java.awt.Color;
import
import
import
import
import
import
import
import
import
import
import
import
java.awt.Container;
java.awt.Cursor;
java.awt.Font;
java.awt.Point;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.awt.event.ItemEvent;
java.awt.event.ItemListener;
java.awt.event.MouseEvent;
java.awt.event.MouseListener;
java.awt.event.MouseMotionListener;
java.util.ArrayList;
import
import
import
import
import
import
import
import
import
import
javax.swing.BorderFactory;
javax.swing.ButtonGroup;
javax.swing.JButton;
javax.swing.JComboBox;
javax.swing.JFrame;
javax.swing.JLabel;
javax.swing.JOptionPane;
javax.swing.JRadioButton;
javax.swing.JScrollPane;
javax.swing.JTextArea;
{
nombre =
JOptionPane.showInputDialog(null,"Ingrese la Etiqueta del Nodo");
nombre.length();
}
catch(NullPointerException e)
{
return;
}
if(grafo.getNombres().contains(nombre)||nombre==null)
{
JOptionPane.showMessageDialog(null,"La Etiqueta es incorrecta, recuerde
que no debe haber otra igual","Ingrese de nuevo la
Etiqueta",JOptionPane.ERROR_MESSAGE );
nombre="hay";
}
}
while(nombre=="hay");
Punto punto = new Punto((int)
evento.getPoint().getX() - 5, (int) evento.getPoint().getY() - 5,
nombre);
grafo.ingresarNodo(nombre);
punto.pintarPunto(lienzo.getGraphics());
puntos.add(punto);
lienzo.setPuntos(puntos);
}
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==aplicar)
{
AlgoritmoKruskal nuevo=new AlgoritmoKruskal();
Grafo kruskal= new Grafo();
kruskal=nuevo.aplicarKruskal(grafo);
lienzo.cambiarGrafo(kruskal);
}
if(e.getSource()==nuevo)
{
grafo=new Grafo();
lienzo.getAristas().clear();
lienzo.getPuntos().clear();
lienzo.getNeo().clear();
aristas.clear();
lienzo.punto=false;
lienzo.repaint();
}
if(e.getSource()==recuperar)
{
for(int i=0;i<lienzo.getNeo().size();i++)
{
Arista
arista=(Arista)lienzo.getNeo().get(i);
arista.setColor(new Color(0,128,128));
}
lienzo.getNeo().clear();
lienzo.estado=false;
lienzo.repaint();
}
}
public void itemStateChanged(ItemEvent evento)
{
if (evento.getSource() == radioNodo)
comboOpcionesRecta.setEnabled(false);
else
comboOpcionesRecta.setEnabled(true);
if(evento.getSource()==radioNodo||radioNodo.isSelected())
lienzo.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
else
lienzo.setCursor(Cursor.getDefaultCursor());
if(evento.getSource()==ayudaCombo)
{
if(ayudaCombo.getSelectedIndex()==0)
area.setText(ayudaNod);
if(ayudaCombo.getSelectedIndex()==1)
area.setText(ayudaAri);
if(ayudaCombo.getSelectedIndex()==2)
area.setText(ayudaMod);
if(ayudaCombo.getSelectedIndex()==3)
area.setText(ayudaNue);
if(ayudaCombo.getSelectedIndex()==4)
area.setText(ayudaApl);
if(ayudaCombo.getSelectedIndex()==5)
area.setText(ayudaRes);
}
}
public void mousePressed(MouseEvent arg0)
{
contador=0;
if(radioArista.isSelected())
{
for (int i = 0; i < puntos.size(); i++)
{
if
(puntos.get(i).ecuacionDeCirculo(arg0.getPoint()))
{
puntos.get(i).setColorPunto(Color.RED);//pintarPunto(lienzo.getGraphics()
, Color.RED);
x=puntos.get(i).getUbicacion().x;
y=puntos.get(i).getUbicacion().y;
if(comboOpcionesRecta.getSelectedIndex()==1)
{
pun[contador] =
puntos.get(i);
contador++;
}
pun[contador] = puntos.get(i);
break;
}
}
}
if(radioMod.isSelected())
{
for (int i = 0; i < puntos.size(); i++)
{
if
(puntos.get(i).ecuacionDeCirculo(arg0.getPoint()))
{
puntos.get(i).setColorPunto(Color.RED);
pun[contador] = puntos.get(i);
break;
}
}
contador=0;
}
lienzo.repaint();
}
public void mouseReleased(MouseEvent arg0)
{
if(radioArista.isSelected())
{
if(pun[1]==null||pun[1].ecuacionDeCirculo(arg0.getPoint())==false||pun[0]
.getUbicacion().equals(pun[1].getUbicacion()))
contador=0;
if(contador==2||comboOpcionesRecta.getSelectedIndex()==1)
{
float peso=-1;
do
{
try
{
peso =
Float.parseFloat(JOptionPane.showInputDialog(null,"Ingrese el Peso de la
Arista"));
}
catch(NumberFormatException ex)
{
JOptionPane.showMessageDialog(null,"El peso de la Arista debe ser un
Nmero","Ingrese de nuevo el Peso",JOptionPane.ERROR_MESSAGE );
peso=-1;
}
catch(NullPointerException e)
{
pun[0].setColorPunto(Color.BLUE);
if(pun[1]!=null)
pun[1].setColorPunto(Color.BLUE);
lienzo.punto=false;
lienzo.repaint();
return;
}
}
while(peso==-1);
Arista arista=new Arista(pun[0], pun[1],
comboOpcionesRecta.getSelectedIndex(),peso);
aristas.add(arista);
lienzo.setAristas(aristas);
arista.pintarRecta(lienzo.getGraphics());
grafo.adicionarEnlace(pun[0].getNombre(),pun[1].getNombre(),peso);
contador = 0;
pun[0].setColorPunto(Color.BLUE);
pun[1].setColorPunto(Color.BLUE);
lienzo.punto=false;
lienzo.repaint();
}
}
if(pun[0]!=null)
pun[0].setColorPunto(Color.BLUE);
lienzo.repaint();
lienzo.punto=false;
contador=0;
pun[0]=null;
pun[1]=null;
}
public void mouseEntered(MouseEvent arg0)
{
}
public void mouseExited(MouseEvent arg0)
{
}
public void mouseDragged(MouseEvent e) {
if(radioArista.isSelected())
{
for (int i = 0; i < puntos.size(); i++)
{
if
(puntos.get(i).ecuacionDeCirculo(e.getPoint()))
{
pun[1] = puntos.get(i);
pun[1].setColorPunto( Color.RED);
break;
}
else
if(pun[1]!=null&&pun[1]!=pun[0])
pun[1].setColorPunto(Color.BLUE);
}
if(pun[0]!=null)
{
lienzo.setA(new Point(x,y));
lienzo.setB(e.getPoint());
lienzo.punto=true;
lienzo.repaint();
}
contador=2;
}
if(radioMod.isSelected()&&pun[0]!=null)
{
Point ubicacion=new Point(e.getX()-5,e.getY()-5);
pun[0].setUbicacion(ubicacion);
lienzo.repaint();
}
}
public void mouseMoved(MouseEvent e) {
if(radioMod.isSelected())
{
for (int i = 0; i < puntos.size(); i++)
{
if
(puntos.get(i).ecuacionDeCirculo(e.getPoint()))
puntos.get(i).pintarPunto(lienzo.getGraphics(), Color.RED);
else
puntos.get(i).pintarPunto(lienzo.getGraphics(), Color.BLUE);
}
}
}
public Grafo getGrafo()
{
return grafo;
}
}
Clase Aplicacin[editar]
// Esta clase es la principal y es la que permite ver corriendo el
programa.
public class Aplicacion {
public static void main(String args[])
{
Ventana mi=new Ventana();
mi.area.setEditable(false);
}
}
Pruebas[editar]
Tiempo empleado[editar]
Para una implementacin ptima del algoritmo haciendo uso de una interfaz grafica y una
estructura adicional se hicieron necesarias alrededor de 15 horas, incluyendo el tiempo que
se necesit para investigar y complementar los conceptos necesarios para lograr el resultado
obtenido y deseado.
Conclusiones[editar]