10/11/2014
Implementaci ón del Al gor itm o de Kr uskal en Java - W i ki l i br os
Implementación del Algoritmo de Kruskal en Java De Wikilibros, la colección de libros de texto de contenido libre. El algoritmo de Kruskal es Kruskal es un algoritmo de la teoría de grafos que busca encontrar un árbol recubridor mínimo mínimo de un grafo dado. dado. Aquí Aquí encontrar emos emos una im plementación plementación en Java incluyendo una interfaz gráfica.
Contenido Contenido 1 Descripción Descripción del Problema Problema 2 Limitaciones Limitaciones 3 Solución Solución 3.1 Estructura Estructura Grafo 3.1.1 Clase Clase Enlace 3.1.2 Clase Nodo 3.1.3 Clase Arco A rco 3.1.4 Clase Gr afo afo 3.2 Interfaz Interfaz Gráfica 3.2.1 Clase Lienzo Clase Lienzo 3.2.2 Clase Punto Punto 3.2.3 Clase Ar ista ista 3.3 Paquete Paquete Principal 3.3.1 Clase AlgoritmoKruskal 3.4 VENTANA VENTANA 3.4.1 Clase A plicación 4 Modo de compilación y ejecución 5 Pruebas 6 Tiempo empleado 7 Tiempo de Ejecución T(n) 8 Conclusiones 9 Véase también 10 Enlaces externos externos
escripción del Problema El algoritmo de kruskal, es un algoritmo voraz utilizado en la teoría de grafos, con el fin de encontrar un árbol recubridor mínimo de un grafo conexo y ponderado. El algoritmo de kruskal consiste en: Paso 0: Iniciar el árbol T con n nodos y sin arcos T=({1, 2, …n},ø) http://es.w iki books.or g/wiki /Im pl em entaci%C3%B3n_del_Algor i tmo_de_Kr uskal_en_Java
1/22
10/11/2014
Implementaci ón del Al gor itm o de Kr uskal en Java - W i ki l i br os
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. Paso 3. Si L es no vacío, volver al paso 2, de lo contrario PARAR.
Limitaciones Las únicas limitaciones que se presentan con el problema de la implementación del algoritmo de Kruskal es la creación 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( HayCiclo(Grafo g,Arco aVerificar,Nodo terminal,String terminal,String N N) )
{
ArrayList< ArrayList
Enlace> aux= aux=terminal.getEnlaces terminal.getEnlaces() (); ; if(aux.size aux.size() ()== ==0 0) return false; if(terminal.existeEnlace terminal.existeEnlace( (aVerificar.getInicial aVerificar.getInicial()) ())!=!=-1 1) return true; for(int i= i=0;i
{ Enlace nodo= nodo=aux.get aux.get( (i); if(nodo.getDestino nodo.getDestino() (). .equals equals( (N)==false) if( HayCiclo( HayCiclo(g,aVerificar,g.getNodo g,aVerificar,g.getNodo( (nodo.getDestino nodo.getDestino()) ()),terminal. ,terminal.getNombre getNombre())) ())) return true;
} return false;
}
Solución En la implementación del algoritmo de Kruskal en Java, se hizo uso de una estructura de datos adicional llamada grafo y adicionalmente se implementó una interfaz gráfica.
Estructura Grafo Clase Enlace // creamos un clase llamada enlace La clase enlace se utiliza para hacer refencia al nodo terminal y al peso de un arco. http://es.w iki books.or g/wiki /Im pl em entaci%C3%B3n_del_Algor i tmo_de_Kr uskal_en_Java
2/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
public class Enlace
{ private String destino; private double peso; public Enlace(String desti, double peso1)
{
destino = desti; peso = peso1; } public Enlace(String desti)
{
destino = desti; peso = -1; } public void modificar(double peso1)
{
peso = peso1; } public String getDestino()
{ return destino;
} public double getPeso()
{ return peso;
} }
Clase Nodo 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 enlaces; private int enlacesExistentes; public ArrayList getEnlaces()
{ return enlaces;
} public Nodo(String newName)
{
nombre = newName; enlacesExistentes = -1; enlaces = new ArrayList(); } public int getEnlacesExistentes()
{ return enlacesExistentes;
} public String getNombre()
{ http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
3/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
return nombre;
} public void agregarEnlace(String enlazar,double peso)
{ if (enlacesExistentes == -1)
{
enlaces.add(new Enlace(enlazar,peso)); enlacesExistentes++; } else
{ int posicion; posicion = existeEnlace(enlazar); if (posicion == -1) { enlaces.add(new Enlace(enlazar,peso)); enlacesExistentes++; }
} }
public int existeEnlace(String enlazar)
{ for (int i = 0; i < enlaces.size(); i++)
{ Enlace miEnlace; miEnlace = enlaces.get(i); if (miEnlace.getDestino().equals(enlazar)) return i;
}
return -1;
} public double enlacePosicion(int posi)
{ Enlace miEnlace; 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 Guarda la referencia del nodo inicial, nodo terminal y peso de un determinado arco del grafo.
public class Arco
{ http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
4/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
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 Representa la estructura grafo, compuesta por nodos y arcos.
import java.util.Hashtable; import java.util.ArrayList; public class Grafo
{ ArrayList nombres; ArrayList aristas; Hashtable nodos; public Grafo()
{
nombres=new ArrayList(); nodos=new Hashtable (); aristas=new ArrayList (); } public void ingresarNodo(String nombre)
http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
5/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
{
nombres.add(nombre); nodos.put(nombre,new Nodo(nombre)); } public void adicionarEnlace(String nodoInicial,String nodoTerminal,float peso)
{ Arco nuevo=new Arco(nodoInicial,nodoTerminal,peso); int i=buscarIndice(nuevo.getPeso()); 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
{ Arco otro=aristas.get(i); if(arco.getInicial().equals(otro.getInicial())&&arco.getTerminal().equals(otro.getTerminal())& { aristas.remove(otro); return true; }
}
return false;
} public int buscarIndice(float peso)
{ for(int i=0;i
{ if(peso
} return -1;
} public Hashtable getNodos()
{ return nodos;
} public void setNodos(Hashtable muchos)
{
nodos=muchos; } public ArrayList getNombres()
{ return nombres;
} public Nodo getNodo(String nombre)
{ return (Nodo)nodos.get(nombre);
} public ArrayList getAristas() { return aristas;
} public void setAristas(ArrayList aristas) { this.aristas = aristas;
} public void setNombres(ArrayList nombres) { this.nombres = nombres;
} }
Interfaz Gráfica http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
6/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
Clase Lienzo Es el lienzo sobre el cual se dibujará el grafo.
import java.awt.*; import java.util.ArrayList; import javax.swing.JComponent; public class Lienzo extends JComponent
{ private ArrayList puntos; private ArrayList aristas; private ArrayList neo; private Point a, b; public boolean estado = false; public boolean punto = false; public Lienzo()
{
aristas = new ArrayList(); puntos = new ArrayList(); neo = new ArrayList(); } public void paintComponent(Graphics g)
{ if (punto)
{ g.setColor(Color.BLUE); g.drawLine((int) a.getX() + 5, (int) a.getY() + 5, (int) b.getX() + 5, (int) b.getY() + 5); } for (int i = 0; i < aristas.size(); i++)
{ final Arista arista = (Arista) aristas.get(i); arista.pintarRecta(g);
}
if (estado) for (int i = 0; i < neo.size(); i++)
{ final Arista arista = (Arista) neo.get(i); arista.setColor(Color.RED); arista.pintarRecta(g);
}
for (int i = 0; i < puntos.size(); i++)
{ final Punto punto = (Punto) puntos.get(i); punto.pintarPunto(g);
} }
public void cambiarGrafo(Grafo nuevo)
{ Arco aux; for (int i = 0; i < aristas.size(); i++)
{
aux = aristas.get(i).getArista(); if (nuevo.busarArista(aux) == true)
neo.add(aristas.get(i)); } for (int i = 0; i < aristas.size(); i++)
{ final Arco n = aristas.get(i).getArista(); nuevo.getAristas().add(n);
}
estado = true; http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
7/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
repaint(); } public ArrayList getPuntos()
{ return puntos;
} public void setPuntos(final ArrayList puntos)
{ this.puntos = puntos;
} public ArrayList getAristas()
{ return aristas;
} public void setAristas(final ArrayList aristas)
{ this.aristas = aristas;
} public ArrayList getNeo()
{ return neo;
} public void setNeo(final ArrayList neo)
{ this.neo = neo;
} public void setA(Point a)
{ this.a = a;
} public void setB(Point b)
{ this.b = b;
} }
Clase Punto Permite dibujar un punto sobre el lienzo. Hace referencia a la posición del punto sobre el lienzo.
import java.awt.Color; import java.awt.Graphics; import java.awt.Point; public class Punto
{ private private private private
Point ubicacion; String nombre; Color colorPunto = Color.BLUE; 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); http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
8/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
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 - ubic
} public Point getUbicacion()
{ return ubicacion;
} public String getNombre()
{ return nombre;
} public void setUbicacion(Point ubicacion)
{ this.ubicacion = ubicacion;
} public Color getColorPunto()
{ return colorPunto;
} public void setColorPunto(Color colorPunto)
{ this.colorPunto = colorPunto;
} }
Clase Arista 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;
public class Arista
{ private Arco arista; private Punto a, b; private Point inicial; private Point terminal, ubicacionExt; private Color color = new Color(0, 128, 128), aux = Color.RED; private int tipo; private float peso; public Arista(Punto puntoA, Punto puntoB, int tipo, float peso)
{ http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
9/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
arista = new Arco(puntoA.getNombre(), puntoB.getNombre(), peso); a = puntoA; b = puntoB; this.tipo = tipo; 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 control if (grado <= 90 control }
&& grado >= 0) = new Point((inicial.x + terminal.x) / 2 - 10, (inicial.y + te && grado > 45) = new Point((inicial.x + terminal.x) / 2 + 50, (inicial.y + te
else
{ if (grado >= -45 && grado <= 0) control = new Point((inicial.x + terminal.x) / 2 - 30, (inicial.y + te if (grado >= -90 && grado < -45) control = new Point((inicial.x + terminal.x) / 2 - 50, (inicial.y + te
}
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()
{ http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
10/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
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 Clase AlgoritmoKruskal
//Implementación del Algoritmo voraz de Kruskal.
import java.util.ArrayList; public class AlgoritmoKruskal
{
@SuppressWarnings("unchecked") public Grafo aplicarKruskal(Grafo grafo)
{
Grafo árbol=new Grafo(); ArrayList nodos=grafo.getNombres(); for(int j=0;j
{
árbol.ingresarNodo(nodos.get(j)); } ArrayList L=(ArrayList)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());
http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
11/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
L.remove(pro); } return árbol;
} public boolean HayCiclo(Grafo g,Arco aVerificar,Nodo terminal,String N)
{
ArrayList aux=terminal.getEnlaces(); if(aux.size()==0) return false; if(terminal.existeEnlace(aVerificar.getInicial())!=-1) return true; for(int i=0;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 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;
public class Ventana implements MouseListener, ItemListener, ActionListener, MouseMotionListener { int cantidad = 0; ArrayList puntos; ArrayList aristas; static JFrame frame; JButton aplicar,nuevo,recuperar; Container contenedor; JRadioButton radioNodo, radioArista, radioMod; http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
12/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
JLabel ayuda, titulo; ButtonGroup grupo; JComboBox comboOpcionesRecta,ayudaCombo; JScrollPane panel; public JTextArea area; String ayudaNod,ayudaAri,ayudaMod,ayudaRes,ayudaNue,ayudaApl; Punto pun[]; public Lienzo lienzo; Grafo grafo; int j,i; int x,y; private int contador = 0;
public Ventana() { frame = new JFrame(); contenedor=frame.getContentPane(); Font font=new Font("Verdana",Font.BOLD,11); Font font1=new Font("Verdana",Font.PLAIN,12); grafo=new Grafo();
lienzo = new Lienzo(); lienzo.setBounds(0, 0, 600, 600); lienzo.setBorder(BorderFactory.createBevelBorder(1)); lienzo.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); pun = new Punto[2]; pun[0]=null; pun[1]=null; puntos = new ArrayList(); aristas = new ArrayList();
area=new JTextArea(); area.setFont(font1); panel=new JScrollPane(area); panel.setBounds(660, 270, 280, 250); titulo=new JLabel("Dibuje su grafo:"); titulo.setFont(font); titulo.setBounds(610, 20, 130, 20); ayuda=new JLabel("Ayuda:"); ayuda.setBounds(610, 200, 100, 20); ayuda.setFont(font);
comboOpcionesRecta = new JComboBox(); comboOpcionesRecta.addItem("Arista"); comboOpcionesRecta.addItem("Arista Bucle"); comboOpcionesRecta.addItem("Arista Curva"); comboOpcionesRecta.setFont(font);
ayudaCombo=new JComboBox(); ayudaCombo.addItem(">Como hacer un Nodo"); ayudaCombo.addItem(">Como hacer una Arista"); ayudaCombo.addItem(">Como modificar un Grafo"); ayudaCombo.addItem(">Boton 'Nuevo'"); ayudaCombo.addItem(">Boton 'Aplicar'"); ayudaCombo.addItem(">Boton'Reset'"); ayudaCombo.setFont(font); ayudaCombo.setSelectedIndex(-1);
radioNodo = new JRadioButton("Crear Nodo"); radioArista = new JRadioButton("Crear Arista"); radioMod = new JRadioButton("Modificar");
radioArista.setFont(font); radioMod.setFont(font);
http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
13/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
radioNodo.setFont(font);
grupo = new ButtonGroup(); grupo.add(radioNodo); grupo.add(radioArista); grupo.add(radioMod); radioNodo.setSelected(true); radioNodo.setBounds(680, 60, 120, 20); radioArista.setBounds(680, 110, 130, 20); radioMod.setBounds(820, 60, 100, 20);
aplicar=new JButton("Aplicar"); aplicar.setBounds(670,160, 80, 20); aplicar.setFont(font); nuevo=new JButton("Nuevo"); nuevo.setBounds(760,160, 80, 20); nuevo.setFont(font); recuperar=new JButton("Reset"); recuperar.setBounds(850,160, 80, 20); recuperar.setFont(font);
comboOpcionesRecta.setBounds(815, 110, 100, 20); ayudaCombo.setBounds(710,240,175,20);
ayudaNod ayudaAri ayudaMod ayudaRes ayudaApl ayudaNue
= = = = = =
"\n¡¡¡COMO CREAR UN NODO!!!\n\n" + "1. Seleccione el RadioButton \"Crear Nodo\".\n" + "2. Ha "\n¡¡¡COMO CREAR UNA ARISTA!!!\n\n" + "1. Seleccione el RadioButton \"Crear Arista\".\n" + " "\n¡¡¡COMO MODIFICAR EL GRAFO!!!\n\n" + "1. Seleccione el RadioButton \"Modificar\".\n" + "2 "\n¡¡¡BOTON RESET!!!\n\n" + " Este botón permite recuperar el estado \n" + " del Grafo antes "\n¡¡¡BOTON APLICAR!!!\n\n" + " Este botón permite Aplicar el Algoritmo de\n" + " Kruskal al "\n¡¡¡BOTON NUEVO!!!\n\n" + " Limpia el area de Dibujo para crear un\n" + " nuevo Grafo y po
contenedor.setLayout(null);
contenedor.add(comboOpcionesRecta); contenedor.add(radioMod); contenedor.add(radioArista); contenedor.add(radioNodo); contenedor.add(ayudaCombo); contenedor.add(lienzo); contenedor.add(aplicar); contenedor.add(panel); contenedor.add(nuevo); contenedor.add(recuperar); contenedor.add(ayuda); contenedor.add(titulo);
frame.setFont(font); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(null); frame.setSize(1000, 600); frame.setLocation(10, 20); frame.setTitle("GrafoMatic Displayer"); frame.setVisible(true);
lienzo.addMouseListener(this); lienzo.addMouseMotionListener(this); aplicar.addActionListener(this); nuevo.addActionListener(this); recuperar.addActionListener(this); radioNodo.addItemListener(this); radioArista.addItemListener(this); radioMod.addItemListener(this); ayudaCombo.addItemListener(this); } public void mouseClicked(MouseEvent evento) {
http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
14/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
if (evento.getClickCount() == 2&&radioNodo.isSelected()==true) { String nombre = "hay"; do { try { 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 nombre="hay"; }
} while(nombre=="hay");
Punto punto = new Punto((int) evento.getPoint().getX() - 5, (int) evento.getPoint().getY() - 5, 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
}
public void itemStateChanged(ItemEvent evento) { if (evento.getSource() == radioNodo) comboOpcionesRecta.setEnabled(false);
http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
15/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
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(), Colo 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()) {
http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
16/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
if(pun[1]==null||pun[1].ecuacionDeCirculo(arg0.getPoint())==false||pun[0].getUbicacion().equals contador=0;
if(contador==2||comboOpcionesRecta.getSelectedIndex()==1) { float peso=-1; do { try { peso = Float.parseFloat(JOptionPane.showInputDialog(null,"Ingrese el Pe } catch(NumberFormatException ex) { JOptionPane.showMessageDialog(null,"El peso de la Arista debe ser un Nú 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())
http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
17/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
{ 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 Aplicación
// Esta clase es la principal y es la que permite ver corriendo el programa.
public class Aplicacion { public static void main(String args[])
{ http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
18/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
Ventana mi=new Ventana(); mi.area.setEditable(false); } }
Modo de compilación y ejecución Para poder compilar y ejecutar el programa debe tener instalado en su computador el jdk de java 1.5 (http://java.sun.com/javase/downloads/index_jdk5.jsp) o mejores actualizaciones y además debe tener el path de Windows configurado con el jdk . Más sobre configuración del path (http://web.archive.org/20020205113417/www.geocities.com/chungara/configurar.html) Antes de comenzar tiene que copiar cada una de las clases en un bloc de notas separado y guardarlo con el mismo nombre de la clase y con extensión .java. Por ejemplo: al copiar la clase AlgoritmoKruskal en un bloc de notas la guarda como AlgoritmoKruskal.java. Para compilar abra la consola, o para Windows XP la herramienta símbolo del sistema, estando allí diríjase al directorio donde tiene todas las clases guardadas (Todas las clases deben estar en el mismo directorio para que el programa corra correctamente) y enseguida copie el siguiente comando javac Aplicacion.java , esto le dice a java que compile el main del programa que se encuentra en Aplicacion.java . Si hace esto correctamente deben haberse creado en el directorio de las clases varios archivos .class, uno para cada clase con el mismo nombre de la clase. Para ejecutar tiene que haber compilado primero. Nuevamente abra la consola, o símbolo del sistema, y diríjase al directorio donde se encuentran todas las clases y digite el siguiente comando java Aplicacion , esto le dice a java que ejecute el main del programa. Si lo hace correctamente el programa debe estar corriendo.
Pruebas
En este primer grafo podemos ver que el algoritmo ha seleccionado las aristas con menor peso que son las de 9 y 10. El algoritmo hace una selección de la menor arista del grafo y la añade a un árbol de manera que al añadirla al árbol no forme un ciclo. http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
19/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
En este ejemplo el árbol que es creado por el algoritmo es el representado por las líneas rojas en la figura b).
En este segundo ejemplo podemos observar que decisión toma el algoritmo en caso que haya varias aristas con el mismo peso. El algoritmo sigue el mismo criterio, hace una selección de la menor arista del grafo y la añade a un árbol de manera que al añadirla al árbol no forme un ciclo. En este ejemplo podemos ver claramente el criterio del que se habla. El algoritmo añadiría al árbol la arista con peso 4, luego la arista con peso 5, luego la que tiene peso 7 y al momento de añadir la arista de peso 8 se da cuenta que si añade la arista e-d forma un ciclo y la desecharía y tomaría luego a a-c, como esta no forma ciclo entonces la añade al árbol. Para la implementación de este algoritmo también influye el orden en el cual el usuario dibujo las aristas por que el algoritmo pudo haber seleccionado la arista a-c primero, esto lo veremos más claro en el siguiente ejemplo.
El algoritmo sigue el mismo criterio, hace una selección de la menor arista del grafo y la añade a un árbol de manera que al añadirla al árbol no forme un ciclo. El algoritmo toma en orden ascendente las aristas pero también tiene en cuenta el orden en el cual, el usuario, dibujo las aristas. Para este caso el usuario dibujo primero
http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
20/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
la arista b-d y luego la c-d, debido a esto el árbol que da como resultado no me toma la arista c-d por que formaría un ciclo en el árbol.
Tiempo empleado Para una implementación ó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 complementar los conceptos necesarios para lograr el resultado obtenido y deseado.
Tiempo de Ejecución T(n) Sea T(n) el número de nodos que posee el grafo. Dado que se trata de un grafo denso podemos afirmar que la longitud del camino máximo será n. Igualmente cada llamada recursiva supondrá una disminución del problema en exactamente la unidad. De forma similar, puede afirmarse que el número de llamad as recursivas irá disminuyendo en uno puesto que en cada nivel hay un nodo adyacente más que ya ha sido visitado. Por último puede observarse que dentro del ciclo se realizan al menos n comparaciones. Con los hechos nombrados con anterioridad es posible establecer la siguiente relación de recurrencia: T(n) = (n-1) T(n-1) + n Siendo esta recurrencia no homogénea, es decir, en este caso la combinación lineal no es igual a cero, tal como puede verse en la siguiente expresión: A 0tn +a1tn-1 +…..+ ak tn-k = bn p(n) Se procede ahora a definir el valor de b=2 y p(n)=n Obteniendo que el polinomio característico es: (x-(n-1)) (x-1)² con raíces (n-1) (de multiplicidad 1) y 1 (de multiplicidad 2). Por lo tanto todas las soluciones son de la forma t n= c1(n-1)n +c21n+c3n1n Siempre y cuando t0 >=0 para todo n, se concluye inmediatamente que t pertenece a O (n-1) n
Conclusiones El algoritmo de kruskal es sencillo de implementar con las herramientas adecuadas. El algoritmo de kruskal, al momento de implementarlo en algún lenguaje de programación, no es tan óptimo con respecto a otros algoritmos que cumplen el mismo objetivo, como el de Prim, debido que al momento de implementarlo se tiene la limitante de diseñar un algoritmo adicional que encuentre ciclos que en este caso no es el más óptimo. Al momento de implementar el algoritmo es más óptimo ordenar a medida que el usuario ingresa aristas que ordenar después de terminado el grafo. También sería bueno añadir las aristas en una cola de prioridad, ya que se evita igualmente la búsqueda de la arista menor.
Véase también Algoritmo de Prim http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
21/22
10/11/2014
Implementación del Algoritmo de Kruskal en Java - Wikilibros
Algoritmo de Kruskal Teoría de grafos Algoritmo voraz
Enlaces externos Animación del algoritmo de Kruskal (http://students.ceid.upatras.gr/~papagel/project/kruskal.htm) Creación y solución de laberintos por los algoritmos de Kruskal y Prim (http://www.cut-theknot.org/Curriculum/Games/Mazes.shtml) Otra Animación (incluye código en JAVA) (http://www-b2.is.tokushimau.ac.jp/~ikeda/suuri/kruskal/Kruskal.shtml) Obtenido de «http://es.wikibooks.org/w/index.php? title=Implementación_del_Algoritmo_de_Kruskal_en_Java&oldid=216846» Categorías: Wikilibros:Fusionar Wikilibros:Libros para dividir en subpáginas
Esta página fue modificada por última vez el 10 ene 2014 a las 22:56. El texto está disponible bajo la Licencia Creative Commons Atribución-CompartirIgual 3.0; pueden aplicarse términos adicionales. Véase Términos de uso para más detalles.
http://es.wikibooks.org/wiki/Implementaci%C3%B3n_del_Algoritmo_de_Kruskal_en_Java
22/22