Оптимизация компоновки графика в C#

У меня есть список объектов, которые мне нужно организовать как эстетическая график. Мой текущий подход включает в себя IronPython и генетический алгоритм, но это занимает слишком много времени.

Я читал на Graphviz, QuickGraph и Graph#, но мне не нужна часть визуализации - у меня уже есть приложение, которое будет отображать узлы с учетом координат x/Y. Мне сказали, что алгоритм Sugiyama и семейство алгоритмов на основе силы имеют тенденцию выводить приятные графики, но Кажется, я не могу найти библиотеку .NET, которая будет выводить координаты вместо изображения без довольно серьезного взлома исходного кода.

может ли кто-нибудь рекомендовать библиотеки, алгоритмы или тому подобное?

6 ответов


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

раньше было так, что найти решение с открытым исходным кодом было сложно, но когда-то коммерчески лицензированное MSAGL теперь кажется, с открытым исходным кодом.

различие между графика# и QuickGraph это последний предоставляет примитивы обхода графа и манипуляции, но не предоставляет никаких алгоритмов компоновки. Graph# имеет весь доступный источник и из того, что я (кратко) рассмотрел, имеет четкое разделение между механизмом компоновки и реализацией чертежа.

Graphviz написан на чистом C / C++ и довольно монолитен, принимая в качестве входного текстовый файл, описывающий график и производящий различные типы вывода, Как векторные, так и растровые. Это не очень подходит как плагин макет двигателя, но может быть использован путем обстрела и предоставления необходимого входного файла и разбора вывода. Не очень чистое решение, хотя.

есть еще кое-что под названием OGDF. Хотя он полностью написан на C++, он был разработан для использования в качестве библиотеки движка компоновки и имеет хорошо структурированный интерфейс для этого. Он поддерживает различные алгоритмы компоновки, включая оптимизированную Sugiyama, если это то, что вас интересует.

Если вы заинтересованы в реализации оптимизированного варианта Sugiyama, вы всегда можете свернуть свой собственный, используя аккуратное описание алгоритма :)

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


Microsoft Research имеет автоматизированный механизм компоновки графика,который может помочь вам в этом.

вы можете прочитать больше об этом здесь:

http://research.microsoft.com/en-us/downloads/f1303e46-965f-401a-87c3-34e1331d32c5/


yFiles имеет очень сложные реализации как направленных на силу (называемых "органическими"), так и основанных на Сугияме ("называемых иерархическими") алгоритмов компоновки. Они предлагают реализации без просмотра для Java, .net, Silverlight, Flex и Javascript. API для получения координат доступен онлайн здесь.

алгоритмы и их качество могут быть протестированы в свободном yEd Graph Editor application, библиотеки только хотя в продаже есть.


на всякий случай, если кто-то столкнется с подобной проблемой. Существует проект с открытым исходным кодом GraphX для .NET, который включает в себя множество алгоритмов компоновки, отделенных от механизма визуализации. Таким образом, вы можете просто взять библиотеку логики, выполнить вычисления и получить пакет координат для использования в вашем собственном инструменте vis.

https://github.com/panthernet/GraphX


в Java есть реализация макета Sugiyama как часть системы modsl, Лицензия Apache. источник здесь.

Я смог достаточно легко преобразовать его в смешанный реализация Objective-C/Objective-C++ на основе орграфа.


Я получил координаты узлов таким образом

namespace GleeTest
{
    class GleeTest
    {

        static void Main() {
            Microsoft.Glee.GleeGraph oGleeGraph = new Microsoft.Glee.GleeGraph();

            Microsoft.Glee.Splines.ICurve oCurve =
               Microsoft.Glee.Splines.CurveFactory.CreateEllipse(
                   1, 1,
                   new Microsoft.Glee.Splines.Point(0, 0)
                   );
            Microsoft.Glee.Node strNode1 = new Microsoft.Glee.Node("Circle", oCurve);

            Microsoft.Glee.Node strNode3 = new Microsoft.Glee.Node("Diamond", oCurve);
            Microsoft.Glee.Node strNode4 = new Microsoft.Glee.Node("Standard", oCurve);
            Microsoft.Glee.Node strNode2 = new Microsoft.Glee.Node("Home", oCurve);

            oGleeGraph.AddNode(strNode1);
            oGleeGraph.AddNode(strNode2);
            oGleeGraph.AddNode(strNode3);
            oGleeGraph.AddNode(strNode4);

            Microsoft.Glee.Edge oGleeEdge1 =
               new Microsoft.Glee.Edge(strNode1, strNode2);
            Microsoft.Glee.Edge oGleeEdge2 =
            new Microsoft.Glee.Edge(strNode2, strNode1);
            Microsoft.Glee.Edge oGleeEdge3 =
            new Microsoft.Glee.Edge(strNode2, strNode2);
            Microsoft.Glee.Edge oGleeEdge4 =
            new Microsoft.Glee.Edge(strNode1, strNode3);
            Microsoft.Glee.Edge oGleeEdge5 =
            new Microsoft.Glee.Edge(strNode1, strNode4);
            Microsoft.Glee.Edge oGleeEdge6 =
          new Microsoft.Glee.Edge(strNode4, strNode1);


            oGleeGraph.AddEdge(oGleeEdge1);
            oGleeGraph.AddEdge(oGleeEdge2);
            oGleeGraph.AddEdge(oGleeEdge3);
            oGleeGraph.AddEdge(oGleeEdge4);
            oGleeGraph.AddEdge(oGleeEdge5);
            oGleeGraph.AddEdge(oGleeEdge6);

            oGleeGraph.CalculateLayout();


            System.Console.WriteLine("Circle position  " + oGleeGraph.FindNode("Circle").Center.X + "," + oGleeGraph.FindNode("Circle").Center.Y);
            System.Console.WriteLine("Home position = " + oGleeGraph.FindNode("Home").Center.X + "," + oGleeGraph.FindNode("Home").Center.Y);
            System.Console.WriteLine("Diamond position = " + oGleeGraph.FindNode("Diamond").Center.X + "," + oGleeGraph.FindNode("Diamond").Center.Y);
            System.Console.WriteLine("Standard position = " + oGleeGraph.FindNode("Standard").Center.X + "," + oGleeGraph.FindNode("Standard").Center.Y);




        }

    }
}