Оптимизация раскладки графа в С#

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

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

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

Ответы

Ответ 1

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

В принципе, похоже, нет свободной, чистой реализации С#, которая предназначена для использования в качестве библиотеки движка макета. Ближайшая вещь выглядит MSAGL, которая доступна для скачивания, re на MSDN, но в остальном это довольно дорого.

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

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

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

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

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

Ответ 3

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

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

Ответ 4

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

i удалось легко преобразовать его в смешанную Objective-C/Objective-С++ реализацию на основе орграфа.

Ответ 5

У меня были координаты узлов таким образом

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);




        }

    }
}