Создание связного графа java

Я хочу написать функцию, которой задается набор вершин, а затем создается ребро между 2 вершинами и повторяется это до тех пор, пока граф не станет связным графом). Как я могу узнать, когда график стал связным?

Я не уверен, что понимаю эту проблему. Не могли бы вы опубликовать то, что пробовали до сих пор?

lakshayg 27.10.2018 06:51

Края должны быть направленными / ненаправленными? Ограничено ли количество добавляемых ребер определенным числом?

mettleap 27.10.2018 07:08

Нам нужна дополнительная информация ... Однако вы можете проверить, связан ли граф, используя алгоритм Дейкстры: если к его концу у вас все еще есть узел с расстоянием + inf, то он еще не подключен.

ihavenoidea 27.10.2018 07:27

В качестве структуры данных, которую вы можете разработать, вы можете использовать вектор списка смежности, для которого можно выразить отношения между узлом и другими, добавив массив соответствующих ребер узла.

Mihai8 27.10.2018 11:21

Вам следует изучить варианты структуры данных «непересекающееся множество», которая обычно используется в приложениях теории графов для отслеживания того, как графы делятся на связанные компоненты. Это может поддерживать более эффективные алгоритмы, чем альтернативы, в зависимости от поиска графа для проверки связности узлов.

John Bollinger 08.11.2018 01:35
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
1 484
1

Ответы 1

Это будет основная идея: каждый раз, когда вы добавляете новое ребро, вы запускаете BFS или DFS для проверки возможности подключения. Это решение может быть дополнительно оптимизировано.

import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Random;
import java.util.Set;

import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.SimpleGraph;

public class Main {

public static boolean isConnected(SimpleGraph<Integer, DefaultEdge> graph) {
    Set<Integer> vertexSet = graph.vertexSet();
    if (vertexSet.size()==0) {
        //graph is connected by definition
        return true;
    }

    if (vertexSet.size()-1>graph.edgeSet().size()) {
        //not enough edges, must be disconnected
        return false;
    }

    Set<Integer> traversed = new HashSet<>();
    Deque<DefaultEdge> toTraverse = new LinkedList<DefaultEdge>();

    //pick one random element to start search
    Integer startVertex = vertexSet.iterator().next();

    traversed.add(startVertex);
    graph.edgesOf(startVertex).forEach(x->toTraverse.addLast(x));
    while(traversed.size()!=vertexSet.size() && toTraverse.size()!=0) {
        DefaultEdge currentEdge = toTraverse.pollFirst();
        Integer src = graph.getEdgeSource(currentEdge);
        Integer dst = graph.getEdgeSource(currentEdge);

        //it can be at most one new vertex
        Integer targetVertex = traversed.contains(src)?dst:src;
        if (!traversed.contains(targetVertex)) {
            traversed.add(targetVertex);
            //BFS
            graph.edgesOf(targetVertex).forEach(x->toTraverse.addLast(x));

            //DFS
            //graph.edgesOf(targetVertex).forEach(x->toTraverse.addFirst(x));
        }
    }

    if (traversed.size()==vertexSet.size()) {
        return true;
    }else {
        return false;
    }
}

public static SimpleGraph<Integer, DefaultEdge> buildGraph(int numberOfVertices) {
    SimpleGraph<Integer, DefaultEdge> g =
            new SimpleGraph<Integer, DefaultEdge>(DefaultEdge.class);
    for(int i = 0; i < numberOfVertices; i++) {
        g.addVertex(i);
    }
    Random r = new Random();
    do {
        int a = r.nextInt(numberOfVertices);
        int b = r.nextInt(numberOfVertices);
        while(a == b) {
            b = r.nextInt(numberOfVertices);
        }
        g.addEdge(a, b);
    }while(!isConnected(g));
    return g;

}

public static void main(String[] args) {
    SimpleGraph<Integer, DefaultEdge> g = buildGraph(10);
    System.out.println("Number of edges");
    System.out.println(g.edgeSet().size());
    System.out.println("Edges:");
    for(DefaultEdge e: g.edgeSet()){
        String a = g.getEdgeSource(e).toString();
        String b = g.getEdgeTarget(e).toString();
        System.out.println(a+" "+b);
    }
}

}

Для произвольного графа проверка связности требует не менее O (V) (V - количество вершин, E - количество ребер). BFS и DFS работают в O (V + E). Это может быть хорошо, если вы хотите создавать относительно небольшие графики. Вот более разумная идея, как это сделать. Вначале вы создаете V отдельных графиков. Теперь вы хотите добавить границу между A и B, вы найдете граф, которому принадлежит A, а другой - B. Если это два разных графика, объедините их. Повторяйте этот процесс, пока не останется только один график.

Другие вопросы по теме