package matrizAdyacencia;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

public class Grafo
{
    int _vertices;
    boolean _matrizAdyacencias[][];
   
    // ctor
    public Grafo( int nroVertices )
    {
        this._vertices = nroVertices;
        this._matrizAdyacencias = new boolean[ nroVertices ][ nroVertices ];
       
        for( int i = 0; i < getVertices(); i++ )
            for( int j = 0; j < getVertices(); j++ )
                this._matrizAdyacencias[ i ][ j ] = false;
    }
   
    // agrega una arista entre dos vertices
    public void setArista( int i, int j )
    {
        this._matrizAdyacencias[ i ][ j ] = true;
        this._matrizAdyacencias[ j ][ i ] = true;
    }
   
    // elimina una arista entre dos vertices
    public void eliminarArista( int i, int j )
    {
        this._matrizAdyacencias[ i ][ j ] = false;
        this._matrizAdyacencias[ j ][ i ] = false;
    }
   
    // determina si hay un camino entre dos vertices
    public boolean isArista( int i, int j )
    {
        return ( this._matrizAdyacencias[ i ][ j ] == true && this._matrizAdyacencias[ j ][ i ] == true );
    }
   
    // devuelve la cantidad de vertices del grafo
    public int getVertices()
    {
        return this._vertices;
    }

    // verifica si un vertice es aislado
    public boolean esVerticeAislado( int vertice )
    {       
        boolean retValue = false;
       
        for( int i = 0; i < getVertices(); i++ ) 
            retValue = retValue || isArista( vertice, i );
       
        return retValue;
    }
   
    // devuelve el grado de un vertice
    public int getGrado( int vertice )
    {
        int ret = 0;
       
        for( int i = 0; i < getVertices(); i++ ) if( isArista( vertice, i ) )
            ret++;
       
        return ret;
    }
   
    // devuelve una lista de vecinos de un vertice
    public int[] listaVecinos( int vertice )
    {
        int ret[] = new int[ this.getGrado( vertice ) ];
        int indice = 0;
       
        for( int i = 0; i < this.getVertices(); i++ )
            if( this.isArista( vertice, i ) )
            {
                ret[ indice ] = i;
                indice++;
            }
       
        return ret;
    }

    // devuelve la cantidad de vecios en comun entre dos vertices
    public int vecinosEnComun( int verticeUno, int verticeDos )
    {
        int ret = 0;
        int vecinosDeUno[] = this.listaVecinos( verticeUno );
        int vecinosDeDos[] = this.listaVecinos( verticeDos );
       
        for( int i = 0; i < vecinosDeUno.length; i++ )
            for( int j = 0; j < vecinosDeDos.length; j++ )
                if( vecinosDeUno[i] == vecinosDeDos[j] )
                    ret++;
       
        return ret;
    }

    // devuelve una lista de vecinos en comun entre dos vertices
    public int[] listaVecinosEnComun( int verticeUno, int verticeDos )
    {
        int vecinosVerticeUno[] = this.listaVecinos( verticeUno );
        int vecinosVerticeDos[] = this.listaVecinos( verticeDos );
       
        int ret[] = new int[ vecinosEnComun( verticeUno, verticeDos ) ];
        int indice = 0;
   
        for( int i = 0; i < vecinosVerticeUno.length; i++ )
            for( int j = 0; j < vecinosVerticeDos.length; j++ )
                if( vecinosVerticeUno[ i ] == vecinosVerticeDos[ j ] )
                {
                    ret[ indice ] = vecinosVerticeUno[ i ];
                    ++indice;
                }
       
        return ret;
    }

    // confirma si dos vertices son vecinos
    public boolean sonVecinos( int verticeUno, int verticeDos )
    {
        return isArista( verticeUno, verticeDos );
    }

    // confirma si un vertice es universal
    public boolean esVerticeUniversal( int vertice )
    {
        return this.listaVecinos( vertice ).length == this.getVertices() - 1;
    }

    // agrega un vertice al grafo
    public void agregarVertice()
    {
        this._vertices++;
       
        boolean aux[][] = new boolean[ _vertices ][ _vertices ];
       
        for( int i = 0; i < _vertices - 1; i++ )
            for( int j = 0; j < _vertices - 1; j++ )
                aux[ i ][ j ] = this._matrizAdyacencias[ i ][ j ];
       
        this._matrizAdyacencias = aux;
    }

    // elimina un vertice
    public void eliminarVertice( int vertice )
    {
        //desconecto el vertice del grafo
        for( int i = 0; i < getVertices(); i++ ) if( isArista( vertice, i ) )
            eliminarArista( vertice, i );
               
        // una nueva matriz
        boolean aux [][] = new boolean[ _vertices - 1 ][ _vertices - 1 ];
       
        //copio todo lo que interesa
        for( int i = 0; i < getVertices() - 1; i++ )
            for( int j = 0; j < getVertices() - 1; j++ ) if( i != vertice && j != vertice)
                    aux[ i ][ j ] = this._matrizAdyacencias[ i ][ j ];
       
        // piso la vieja mariz
        this._matrizAdyacencias = aux;
        this._vertices--;
    }

    // devuelve los vertices a distancia dos
    // este metodo no deberia estar en esta clase
    public ArrayList<Integer> verticesDistanciaDos( int vertice )
    {
        int vecinosDelVertice[] = listaVecinos( vertice );
        ArrayList< Integer > conjuntoVecinos = new ArrayList< Integer >();
       
        for( int i = 0; i < vecinosDelVertice.length; i++ )
        {
            int aux[] = listaVecinos( vecinosDelVertice[ i ] );
            for( int j = 0; j < aux.length; j++ ) if( !conjuntoVecinos.contains( aux[ j ] ) && !isArista( vertice, aux[ j ] ) && aux[ j ] != vertice )
                    conjuntoVecinos.add( aux[ j ] );
        }
   
        return conjuntoVecinos;
    }
   
    // si es necesario recorre todo el grafo para determinar si es conexo
    public boolean bfs()
    {       
        boolean retValue = true;
        boolean verticesVisitados[] = new boolean [ getVertices() ];
        Queue< Integer > cola = new LinkedList< Integer >();       
       
        cola.add( 0 );
       
        // mientras falten vertices por procesar
        while( !cola.isEmpty() )
        {
            int verticeActual = cola.remove();
            verticesVisitados[ verticeActual ] = true;
           
            int vecinosDelVerticeActual[] = listaVecinos( verticeActual );
           
            // entonces debo procesar tambien todos sus vecinos
            for( int indice = 0; indice < vecinosDelVerticeActual.length; ++indice )
                if( !verticesVisitados[ vecinosDelVerticeActual[ indice ] ] )
                {
                    cola.add( vecinosDelVerticeActual[ indice ] );
                    verticesVisitados[ vecinosDelVerticeActual[ indice ] ] = true;
                }
        }
               
        // si todos los vertices estan visitados entonces es conexo
        for( int indice = 0; indice < verticesVisitados.length; ++indice )
            retValue = retValue && verticesVisitados[ indice ];
       
        return retValue;
    }
}

Comentarios

Entradas populares de este blog

El juego del ahorcado, escrito en assembler i8086

Una posible implementacion en modo texto de una sopa de letras con python ( 2013 )

ayuda memoria sobre conversion dinamica descendente y polimorfismo