Хобрук: Ваш путь к мастерству в программировании

Случайное расположение вершин JUNG

Я создал java-программу, которая начинается с 1 вершины и оттуда добавляет одну вершину и 2 ребра за цикл. Он использует статический макет

Layout<Number, Number> staticLayout = new StaticLayout<Number, Number>(g, layout);
vv = new VisualizationViewer<Number, Number>(staticLayout, new Dimension(550, 550));

Это прозвучит очень нетехническим образом, но граф просто не выглядит достаточно случайным, в основном я имею в виду, что каждый раз, когда он запускается, они всегда сильно группируются по краям графа. график, в то время как очень немногие приближаются к центру. Моя программа обычно использует 100 сгенерированных вершин, и я получу полдюжины в центре, а остальные по краям.

Ниже приведен случайный пример, который я только что создал.

Возможно, если бы кто-то мог подтвердить, что это на самом деле случайно, или, если нет, если есть способ обойти эту проблему, или если я что-то неправильно настроил. Поскольку я хочу, чтобы узлы были как можно более случайными.

Любая помощь будет оценена по достоинству. Спасибо

Случайный пример

Ниже приведен соответствующий код апплета. включая его настройку.

public class AnimatingAddNodeDemo extends JApplet {

        //create a graph
        Graph<Number, Number> ig = Graphs.synchronizedUndirectedGraph(new UndirectedSparseMultigraph<Number, Number>());

        ObservableGraph<Number, Number> og = new ObservableGraph<Number, Number>(ig);
        og.addGraphEventListener(new GraphEventListener<Number, Number>() {

            public void handleGraphEvent(GraphEvent<Number, Number> evt) {
                //System.err.println("got " + evt);
            }
        });
        this.g = og;
        //create a graphdraw
        layout = new FRLayout<Number, Number>(g);
        layout.setSize(new Dimension(600, 600));
        setSize(700, 700);
        Relaxer relaxer = new VisRunner((IterativeContext) layout);
        relaxer.stop();
        relaxer.prerelax();

        Layout<Number, Number> staticLayout = new StaticLayout<Number, Number>(g, layout);
        vv = new VisualizationViewer<Number, Number>(staticLayout, new Dimension(550, 550));

        JRootPane rp = this.getRootPane();
        rp.putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE);

        getContentPane().setLayout(new BorderLayout());
    }

    Integer v_prev = null;

    public void process() {

        vv.getRenderContext().getPickedVertexState().clear();
        vv.getRenderContext().getPickedEdgeState().clear();
        try {
            if (g.getVertexCount() < 100) {
                //add a vertex

                Integer v1 = nodeCount;
                g.addVertex(v1);
                nodeCount++;
                System.out.println("adding vertex " + v1);
                vv.getRenderContext().getPickedVertexState().pick(v1, true);
                j.setText(myText);

                // wire it to some edges
                if (v_prev != null) {
                    Integer edge = edgeCount;
                    //vv.getRenderContext().getPickedEdgeState().pick(edge, true);

                    // let's connect to a random vertex, too!

                    int rand = (int) (Math.random() * (edgeCount-1)); // because there is a 0 node
                    while (v1.equals(rand)) {
                        System.out.println("avoided connecting to myself");
                        rand = (int) (Math.random() * (edgeCount-1)); // because there is a 0 node
                    }

                    edgeCount++;
                    g.addEdge(edge, rand, v1);  //add an edge called var1, between the nodes var2 and var3
                    vv.getRenderContext().getPickedEdgeState().pick(edge, true);
                    System.out.println("Adding edge " + edge + " between " + rand + " & " + v1 + "()");
                }

                v_prev = v1;
                layout.initialize();

                Relaxer relaxer = new VisRunner((IterativeContext) layout);
                relaxer.stop();
                relaxer.prerelax();
                vv.getRenderContext().getMultiLayerTransformer().setToIdentity();
                vv.repaint();

            } else {
                done = true;
            }

        } catch (Exception e) {
            System.out.println(e);
        }
    }


    public static void main(String[] args) {
        AnimatingAddNodeDemo and = new AnimatingAddNodeDemo();
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(and);

        and.init();
        and.start();
        frame.pack();
        //frame.setVisible(true);
    }
}
31.10.2013

  • Я делаю снимок в темноте, но кажется, что вы передаете свои StaticLayout и FRLayout (Фрухтерман-Рейнгольд). На вашем снимке экрана показано, как выглядит большинство FRLayout, когда их размер слишком мал. Узлы упираются в стены макета. Я предполагаю, что JUNG использует FRLayout в качестве преобразователя в классе StaticLayout. 31.10.2013

Ответы:


1

Причина, по которой ваш график не является случайным, вероятно, связана с тем, что вы передаете FRLayout конструктору.

layout = new FRLayout<Number, Number>(g);
// ...
Layout<Number, Number> staticLayout = new StaticLayout<Number, Number>(g, layout);

Вы можете создать свой собственный класс случайного макета, расширив AbstractLayout. Но, согласно JavaDoc, StaticLayout будет случайным образом размещать узлы, если вы исключите второй аргумент конструктора.

Layout<Number, Number> staticLayout = new StaticLayout(Number, Number>(g);
31.10.2013
  • В итоге я изменил макет на статический, т.е. layout = new StaticLayout‹Number, Number›(g) вместо удаления второго аргумента конструктора, но это очень помогло, спасибо. 03.11.2013
  • @AlexioHill Я рад, что это сработало. Похоже, вы удалили второй аргумент конструктора, просто выполнив new StaticLayout<Number, Number>(g) вместо new StaticLayout<Number, Number>(g, layout). 04.11.2013

  • 2

    Я не пришел к выводу, является ли это случайным. Поэтому вместо этого, когда я создаю каждую вершину, я решил установить конкретную координату вершины, используя layout.setLocation(v1, x, y) С созданием x и y, используя math.random() и умножив их на ширину и высоту моего апплета.

    Поэтому я теперь знаю, что это случайно.


    ИЗМЕНИТЬ

    На самом деле это сработало, но на самом деле это не так, мне пришлось удалить FRLayout. Оказывается, FRLayout не позволит вам установить свои собственные местоположения из-за того, что делает алгоритм.

    FRLayout — это силовой макет, который перемещает вершины в соответствии с топологией графа.

    Поэтому я изменил FRLayout на StaticLayout, удалил несколько вещей, которые работали только с FRLayout, и теперь он работает правильно.

    31.10.2013
    Новые материалы

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

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

    Настольный ПК как «одно кольцо, чтобы править всеми» домашних компьютеров
    Вид после 9 месяцев использования С настольных компьютеров все началось, но в какой-то момент они стали «серверами», и мы все перешли на ноутбуки. В прошлом году я столкнулся с идеей настольных..

    Расширенные методы безопасности для VueJS: реализация аутентификации без пароля
    Руководство, которое поможет вам создавать безопасные приложения в долгосрочной перспективе Безопасность приложений часто упускается из виду в процессе разработки, потому что основная..

    стройный-i18следующий
    Представляем стройную оболочку для i18next. Эта библиотека, основанная на i18next, заключает экземпляр i18next в хранилище svelte и отслеживает события i18next, такие как languageChanged,..

    Обзор 20 основных и современных методов работы с массивами в JavaScript
    Вы знаете их всех? В этом коротком посте я покажу сводку методов, доступных в JavaScript для работы с массивами. Я надеюсь, что вы найдете это полезным! В конце поста вы найдете ссылку на..

    Да, но я чувствую необходимость указать, что это или не единственные два.
    Да, но я чувствую необходимость указать, что это или не единственные два. Обучение с подкреплением (в качестве примера) также является важным.