Algoritmo en Java
Algoritmo en Java
Limitaciones
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
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
Clase Enlace // creamos un clase llamada enlace La clase enlace se utiliza para hacer refencia al nodo terminal y al peso de un arco. 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; } }
Implementacin del Algoritmo de Kruskal en Java 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<Enlace> enlaces; private int enlacesExistentes; public ArrayList<Enlace> getEnlaces() { return enlaces; } public Nodo(String newName) { nombre = newName; enlacesExistentes = -1; enlaces = new ArrayList<Enlace>(); } public int getEnlacesExistentes() { return enlacesExistentes; } public String getNombre() { 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));
Implementacin del Algoritmo de Kruskal en Java 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; } }
Implementacin del Algoritmo de Kruskal en Java Clase Arco 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() {
Implementacin del Algoritmo de Kruskal en Java 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 <String>nombres; ArrayList <Arco>aristas; Hashtable <String,Nodo> nodos;
public Grafo() { nombres=new ArrayList<String>(); nodos=new Hashtable <String,Nodo>(); aristas=new ArrayList <Arco>(); }
public void ingresarNodo(String nombre) { 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());
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);
Interfaz Grfica
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<Punto> puntos; private ArrayList<Arista> aristas; private ArrayList<Arista> neo; private Point a, b; public boolean estado = false; public boolean punto = false; public Lienzo() { aristas = new ArrayList<Arista>(); puntos = new ArrayList<Punto>(); neo = new ArrayList<Arista>(); } 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++) {
Implementacin del Algoritmo de Kruskal en Java 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; repaint(); } public ArrayList<Punto> getPuntos() { return puntos; } public void setPuntos(final ArrayList<Punto> puntos) { this.puntos = puntos; } public ArrayList<Arista> getAristas() { return aristas; } public void setAristas(final ArrayList<Arista> aristas) { this.aristas = aristas; }
10
public ArrayList<Arista> getNeo() { return neo; } public void setNeo(final ArrayList<Arista> 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 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);
Implementacin del Algoritmo de Kruskal en Java } 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)); } 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; } }
11
Implementacin del Algoritmo de Kruskal en Java 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;
12
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) { 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);
Implementacin del Algoritmo de Kruskal en Java 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 10, (inicial.y + terminal.y) / 2 + 50); if (grado <= 90 && grado > 45) control = new Point((inicial.x 50, (inicial.y + terminal.y) / 2 + 10); } else { if (grado >= -45 && grado <= 0) control = new Point((inicial.x 30, (inicial.y + terminal.y) / 2 - 10); if (grado >= -90 && grado < -45) control = new Point((inicial.x 50, (inicial.y + terminal.y) / 2 - 10); }
13
terminal.x) / 2 -
terminal.x) / 2 +
terminal.x) / 2 -
terminal.x) / 2 -
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);
Implementacin del Algoritmo de Kruskal en Java 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; } }
14
15
Paquete Principal
Clase AlgoritmoKruskal //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();
16
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
import java.awt.Color; import import import import import import import import import import 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; 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;
Implementacin del Algoritmo de Kruskal en Java public class Ventana implements MouseListener, ItemListener, ActionListener, MouseMotionListener { int cantidad = 0; ArrayList<Punto> puntos; ArrayList<Arista> aristas; static JFrame frame; JButton aplicar,nuevo,recuperar; Container contenedor; JRadioButton radioNodo, radioArista, radioMod; 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<Punto>(); aristas = new ArrayList<Arista>();
17
18
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); 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);
Implementacin del Algoritmo de Kruskal en Java 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 = "\nCOMO CREAR UN NODO!!!\n\n" + "1. Seleccione el RadioButton \"Crear Nodo\".\n" + "2. Haga doble click sobre el area de Dibujo.\n" + "3. Inserte el nombre del Nodo.\n" + "4. Haga click en Aceptar."; ayudaAri = "\nCOMO CREAR UNA ARISTA!!!\n\n" + "1. Seleccione el RadioButton \"Crear Arista\".\n" + "2. Seleccione el Tipo de arista que desee\n \"Arista\", \"Arista Curva\", o \"Arista Bucle\".\n" + "3. Haga click sobre el nodo que desea sea el\n nodo inicial.\n" + "4. Mantega presionado el boton del mouse\n y arrastrelo hasta el nodo terminal.\n" + "5. Suelte el boton del mouse e ingrese\n el peso de la Arista.\n" + "6. Haga click en Aceptar."; ayudaMod = "\nCOMO MODIFICAR EL GRAFO!!!\n\n" + "1. Seleccione el RadioButton \"Modificar\".\n" + "2. Haga click sobre un Nodo\n" + "3. Mantega presionado el botn del mouse \n y arrastrelo para darle una nueva\n posicin al nodo.\n" + "4. Suelte el botn del mouse."; ayudaRes = "\nBOTON RESET!!!\n\n" + " Este botn permite recuperar el estado \n" + " del Grafo antes de aplicar el Algoritmo de \n" + " Kruskal.\n"; ayudaApl = "\nBOTON APLICAR!!!\n\n" + " Este botn permite Aplicar el Algoritmo de\n" + " Kruskal al Grafo dibujado por el Usuario."; ayudaNue = "\nBOTON NUEVO!!!\n\n" + " Limpia el area de Dibujo para crear un\n" + " nuevo Grafo y poder aplicar nuevamente\n" + " el Algoritmo de Kruskal.\n"; contenedor.setLayout(null); contenedor.add(comboOpcionesRecta); contenedor.add(radioMod); contenedor.add(radioArista); contenedor.add(radioNodo); contenedor.add(ayudaCombo); contenedor.add(lienzo);
19
Implementacin del Algoritmo de Kruskal en Java 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) { 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; }
20
Implementacin del Algoritmo de Kruskal en Java 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);
21
Implementacin del Algoritmo de Kruskal en Java 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())) {
22
23
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().
24
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);
Implementacin del Algoritmo de Kruskal en Java 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);
25
Implementacin del Algoritmo de Kruskal en Java } 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; } }
26
Implementacin del Algoritmo de Kruskal en Java Clase Aplicacin // 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); } }
27
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 seleccin de la menor arista del grafo y la aade a un rbol de manera que al aadirla al rbol no forme un ciclo. En este ejemplo el rbol que es creado por el algoritmo es el representado por las lneas rojas en la figura b).
28
En este segundo ejemplo podemos observar que decisin toma el algoritmo en caso que haya varias aristas con el mismo peso. El algoritmo sigue el mismo criterio, hace una seleccin de la menor arista del grafo y la aade a un rbol de manera que al aadirla al rbol no forme un ciclo. En este ejemplo podemos ver claramente el criterio del que se habla. El algoritmo aadira al rbol la arista con peso 4, luego la arista con peso 5, luego la que tiene peso 7 y al momento de aadir la arista de peso 8 se da cuenta que si aade la arista e-d forma un ciclo y la desechara y tomara luego a a-c, como esta no forma ciclo entonces la aade al rbol. Para la implementacin de este algoritmo tambin 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 ms claro en el siguiente ejemplo. El algoritmo sigue el mismo criterio, hace una seleccin de la menor arista del grafo y la aade a un rbol de manera que al aadirla al rbol no forme un ciclo. El algoritmo toma en orden ascendente las aristas pero tambin tiene en cuenta el orden en el cual, el usuario, dibujo las aristas. Para este caso el usuario dibujo primero 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 formara un ciclo en el rbol.
Tiempo empleado
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
El algoritmo de kruskal es sencillo de implementar con las herramientas adecuadas. El algoritmo de kruskal, al momento de implementarlo en algn lenguaje de programacin, 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 disear un algoritmo adicional que encuentre ciclos que en este caso no es el ms ptimo. Al momento de implementar el algoritmo es ms ptimo ordenar a medida que el usuario ingresa aristas que ordenar despus de terminado el grafo. Tambin sera bueno aadir las aristas en una cola de prioridad, ya que se evita igualmente la bsqueda de la arista menor.
29
Enlaces externos
Animacin del algoritmo de Kruskal [3] Creacin y solucin de laberintos por los algoritmos de Kruskal y Prim [4] Otra Animacin (incluye cdigo en JAVA) [5]
Referencias
[1] [2] [3] [4] [5] http:/ / java. sun. com/ javase/ downloads/ index_jdk5. jsp http:/ / www. geocities. com/ chungara/ configurar. html http:/ / students. ceid. upatras. gr/ ~papagel/ project/ kruskal. htm http:/ / www. cut-the-knot. org/ Curriculum/ Games/ Mazes. shtml http:/ / www-b2. is. tokushima-u. ac. jp/ ~ikeda/ suuri/ kruskal/ Kruskal. shtml
30
Licencia
Creative Commons Attribution-Share Alike 3.0 Unported //creativecommons.org/licenses/by-sa/3.0/