Оптимизация раскладки графа в С#
У меня есть список объектов, которые мне нужно организовать как эстетический граф. Мой текущий подход включает IronPython и генетический алгоритм, но это занимает слишком много времени.
Я читал на Graphviz, QuickGraph и Graph #, но мне не нужна часть визуализации - у меня уже есть приложение, которое будет отображать узлы с учетом координат x/y. Мне сказали, что алгоритм Sugiyama и силовое семейство алгоритмов имеют тенденцию выводить приятные графики, но я не могу найти библиотеку .NET, которая будет выводить координаты вместо изображения без какого-либо довольно серьезного исходного кода хакерство.
Кто-нибудь может рекомендовать библиотеки, алгоритмы и т.п.?
Ответы
Ответ 1
Существует множество опций с различными плюсами и минусами - вы можете пропустить через этот, который является списком программного обеспечения, которое делает, более или менее, то, что вы ищете.
В принципе, похоже, нет свободной, чистой реализации С#, которая предназначена для использования в качестве библиотеки движка макета. Ближайшая вещь выглядит MSAGL, которая доступна для скачивания, re на MSDN, но в остальном это довольно дорого.
Различие между Graph # и QuickGraph заключается в том, что последний предоставляет примитивы обхода трассировки и манипуляции, но не предоставляет никаких алгоритмов компоновки. График # имеет весь источник, доступный, и из того, что я (кратко) смотрел, имеет аккуратное разделение между механизмом компоновки и реализацией чертежа.
Graphviz написан на чистом C/С++ и довольно монолитен, принимая в качестве входного текстового файла, описывающего график, и производя различные типы выходного, как векторного, так и растрового. Это не очень удобно, как механизм компоновки плагинов, но может быть использован путем обхода и предоставления требуемого входного файла и анализа вывода. Не очень чистое решение.
Там также что-то называется OGDF. Хотя он полностью написан на С++, он был разработан для использования в качестве библиотеки компоновки макетов и имеет хорошо структурированный интерфейс для этого. Он поддерживает различные алгоритмы компоновки, включая оптимизированную Sugiyama, если это вас интересует.
Если вы заинтересованы в реализации оптимизированного варианта Sugiyama, вы всегда можете свернуть свое собственное, используя опрятное описание алгоритма:)
В конечном счете, вы, вероятно, должны решить, какой тип макета вам нужен, прежде чем принимать решение о библиотеке.
Ответ 2
Microsoft Research имеет механизм автоматического компоновки графиков, который может помочь вам в этом.
Подробнее об этом вы можете прочитать здесь:
http://research.microsoft.com/en-us/downloads/f1303e46-965f-401a-87c3-34e1331d32c5/
Ответ 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);
}
}
}