Ejercicios Resueltos de Algoritmos con Grafos en Java

Informática y Telecomunicaciones6,39 KB

Ejercicios Resueltos de Grafos en Java

A continuación, se presenta una colección de ejercicios prácticos implementados en Java para la manipulación y resolución de problemas sobre la teoría de grafos, utilizando estructuras como Iterator, Vector, Vertice y Arco.

Ejercicio 1: Búsqueda de Predecesores

Métodos para obtener los vértices predecesores de un vértice dado en un grafo, ya sea recorriendo los arcos o explorando los vértices adyacentes.

public static Iterator<Vertice> predecesores (Grafo g, Vertice v ){
    Vector<Vertice> pred = new Vector<>();
    Iterator<Arco> itAr = g.arcos();
    while(itAr.hasNext()){
        Arco a = itAr.next();
        if (a.getDestino().equals(v)) pred.add(a.getOrigen()); 
    }
    return pred.iterator(); 
}

public static Iterator<Vertice> predecesores2 (Grafo g, Vertice v ){
    Vector<Vertice> pred = new Vector<>();
    Iterator<Vertice> itVer = g.vertices();
    while (itVer.hasNext()){
        Vertice w = itVer.next();
        Iterator<Vertice> itAdy = g.adyacentes(w);
        while (itAdy.hasNext()) 
            if (itAdy.next().equals(v)) pred.add(w);
    }
    return pred.iterator(); 
}

Ejercicio 2: Verificación de Sumidero

Algoritmo para determinar si un vértice específico actúa como un sumidero dentro del grafo.

public static boolean sumidero (Grafo g, Vertice v){
    // Número de vértices
    Iterator<Vertice> itVer = g.vertices(); 
    int numVertices = 0;
    while (itVer.hasNext()){
        itVer.next(); 
        numVertices++; 
    }
    // Grado de entrada
    itVer = predecesores(g, v); 
    int numPred = 0;
    while (itVer.hasNext()){
        itVer.next(); 
        numPred++; 
    }
    // Grado de salida
    itVer = g.adyacentes(v); 
    int numAdy = 0;
    while (itVer.hasNext()){
        itVer.next();
        numAdy++;
    }
    return numAdy == 0 && numPred == numVertices - 1;
}

Ejercicio 3: Comprobación de Grafo Regular

Función que comprueba si todos los vértices del grafo poseen el mismo grado de adyacencia.

public static boolean regular (Grafo g){
    if (g.esVacio()) return true;
    Iterator<Vertice> itVer = g.vertices();
    Vertice v = itVer.next();
    Iterator<Vertice> itAdy = g.adyacentes(v);
    int numAdy = 0;
    while (itAdy.hasNext()){
        numAdy++;
        itAdy.next();
    }
    while (itVer.hasNext()){
        v = itVer.next();
        itAdy = g.adyacentes(v);
        int contador = 0;
        while (itAdy.hasNext()){
            contador++;
            itAdy.next();
        }
        if (contador != numAdy)
            return false;
    }
    return true;
}

Ejercicio 4: Existencia de Camino entre Dos Vértices

Métodos basados en búsqueda para comprobar si existe un camino conectando dos vértices determinados.

public static boolean hayCaminoEntreDos (Grafo g, Vertice v1, Vertice v2){
    Vector<Vertice> visitados = new Vector<>();
    return caminoEntreDos(g, v1, v2, visitados);
}

private static boolean caminoEntreDos (Grafo g, Vertice v1, Vertice v2, Vector<Vertice> visitados){
    boolean encontrado = false; 
    visitados.add(v1);
    if (v1.equals(v2)) return true;
    else { 
        Iterator<Vertice> adys = g.adyacentes(v1);
        while (adys.hasNext() && !encontrado){
            Vertice w = adys.next();
            if (!visitados.contains(w))
                encontrado = caminoEntreDos(g, w, v2, visitados); 
        }
        return encontrado; 
    } 
}

Ejercicio 5: Recorridos, Arborescencia y Ciclos

Conjunto de funciones avanzadas que incluyen el cálculo del tamaño de un iterador, recorridos en profundidad (DFS), detección de arborescencia, nodos no alcanzables y detección de ciclos.

private static int size(Iterator<Vertice> i){
    int cont = 0;
    while(i.hasNext()){
        cont++;
        i.next();
    }
    return cont;
}

// Recorrido en profundidad
public static void profundidad (Grafo g, Vertice v) {
    Vector<Vertice> visitados = new Vector<>();
    profundidad(g, v, visitados);
}

private static void profundidad(Grafo g, Vertice v, Vector<Vertice> visitados)
{
    visitados.add(v);
    Iterator<Vertice> adys = g.adyacentes(v);
    while (adys.hasNext()){
        Vertice w = adys.next();
        if (!visitados.contains(w))
            profundidad(g, w, visitados);
    }
}

public static Vertice esArborescencia (Grafo g){
    Iterator<Vertice> ver = g.vertices();
    while(ver.hasNext()){
        Vector<Vertice> visitados = new Vector<>();
        Vertice v = ver.next();
        profundidad(g, v, visitados);
        // Comparar el conjunto de visitados con el conjunto de vértices del grafo
        if (size(visitados.iterator()) == size(g.vertices())) return v;
    }
    return null;
}

public static Iterator<Vertice> noAlcanzables (Grafo g, Vertice v){
    Vector<Vertice> porVisitar = new Vector<>();
    Iterator<Vertice> itVer = g.vertices();
    while (itVer.hasNext()){
        porVisitar.add(itVer.next());
    }
    return noAlcanzables(g, v, porVisitar);
}

private static Iterator<Vertice> noAlcanzables (Grafo g, Vertice v, Vector<Vertice> porVisitar){
    porVisitar.remove(v);
    Iterator<Vertice> itAdy = g.adyacentes(v);
    while(itAdy.hasNext()){
        Vertice ady = itAdy.next();
        if(porVisitar.contains(ady))
            return noAlcanzables(g, ady, porVisitar);
    }
    return porVisitar.iterator();
}

// Determinar si hay un ciclo que tenga como origen el vértice v
public static boolean hayCiclo(Grafo g, Vertice v){
    Vector<Vertice> visitados = new Vector<>();
    return hayCiclo(g, v, v, visitados);
}

private static boolean hayCiclo(Grafo g, Vertice vOrigen, Vertice v, Vector<Vertice> visitados){
    boolean encontrado = false;
    visitados.add(v);
    Iterator<Vertice> adys = g.adyacentes(v);
    while (adys.hasNext() && !encontrado){
        Vertice w = adys.next();
        if (vOrigen.equals(w))
            encontrado = true;
        else if (!visitados.contains(w))
            encontrado = hayCiclo(g, vOrigen, w, visitados);
    }
    return encontrado;
}

Descargar

PDF Word HTML