精华内容
下载资源
问答
  • Layout algorithms for visualizing directed acylic graphs
  • 在这些情况下, d3-hierarchy可能无法满足您的需求,这就是为什么存在d3-dag (有向无环图)的原因。 该模块实现了用于处理DAG的数据结构。 旧版本旨在尽可能地模仿d3-hierarchy的api,新版本则选择使用现代...
  • 有向无环图(DAG)布局 有向无环图及其布局算法 有向无环图(directed acyclic graph,以下简称 DAG)是一种常见的图形,其具体定义为一种由有限个顶点和有限条带方向的边组成的,并且其中任意一个顶点都不能...

    有向无环图(DAG)布局

    有向无环图及其布局算法

    有向无环图(directed acyclic graph,以下简称 DAG)是一种常见的图形,其具体定义为一种由有限个顶点和有限条带有方向的边组成的图,并且其中任意一个顶点都不能沿着边再次指向自己。

    DAG 可以用于模型化许多不同种类的信息,因此将一个 DAG 数据结构可视化的需求也变得非常普遍。并且由于大部分图的数据都非常复杂甚至动态变化,所以自动、可配置的 DAG 可视化布局算法显然比人为排版更为高效且可靠。

    为满足笔者所在项目一个可视化功能(其逻辑可视为一个 DAG)的开发,我们需要一个可在浏览器端进行布局计算的 js 库,并且基于计算结果进行渲染。经过调研,社区的一个项目 dagre 基本可以满足我们的需求,但需要彻底掌握其计算逻辑我们还需要理解一些基本概念和对应配置项之间的关系。

    基本概念

    dagre 主要基于《A Technique for Drawing Directed Graphs》 的理论进行实现,因此也有以下几类单位:

    • graph,即图整体,我们可以对图配置一些全局参数。
    • node,即顶点,dagre 在计算时并不关心 node 实际的形状、样式,只要求提供维度信息。
    • edge,即边,edge 需要声明其两端的 node 以及本身方向。例如A -> B表示一条由 A 指向 B 的 edge。
    • rank,即层级,rank 是 DAG 布局中的核心逻辑单位,edge 两端的 node 一定属于不同的 rank,而同一 rank 中的 node 则会拥有同样的深度坐标(例如在纵向布局的 graph 中 y 坐标相同)。下文中我们会用示例 graph 进一步解释 rank 的作用。
    • label,即标签,label 不是 DAG 中的必要元素,但 dagre 为了适用更多的场景增加了对 edge label 的布局计算。

    深入 rank

    接下来的示例中我们会用一种易懂的描述语言表达一个 DAG 的 node 与 edge:A -> B代表 A 和 B 两个 node 以及一条由 A 指向 B 的 edge。

    示例 1

    A->B;
    B->C;
    
        +---+       +---+        +---+  
        | A |------>| B |------->| C |  
        +---+       +---+        +---+

    在这个示例中,node A, B, C 分别属于 3 个 rank。

    示例 2

    A->B;
    A->C;
    
                    +---+
                --> | B |
        +---+--/    +---+
        | A |
        +---+--\    +---+
                --> | C |
                    +---+

    在这个示例中,A 在 rank1 中,而 B 和 C 都比 A 低一个层级,属于 rank2,因此 B 和 C 拥有同样的 x 坐标(示例图为横行延伸,因此深度方向为 x 方向)。

    示例 3

    A->B;
    B->C;
    A->C;
    
                    +---+
                 -->| B |---\
        +---+---/   +---+    --->+---+  
        | A |                    | C |  
        +---+------------------->+---+

    在这个示例中,我们发现 edge 两端的 node 可以相差超过一个 rank。由于 edge 两端的 node 不可属于同样的 rank,所以我们不能让 B 和 C 属于同一个 rank,进而最优的绘制结果为 A 和 C 之间相隔两个 rank。

    在这三个例子中,我们已经对 rank 的含义和规则有了更好的理解,接下来可以看看 dagre 允许我们对各类布局元素做怎样的配置。

    展开全文
  • 有向无环图的自动布局算法

    千次阅读 2015-01-23 11:49:00
    最近业余在做一个基于结点的编辑工具玩, 遇到一个问题, 就是结点和连线多了, 经常会出现重叠...要是这个样子, 还不如不用清楚呢, 所心就需要找一个方法来进行自动布局, 理想情况是这样的(手动整理结果): 当然

    原文地址:http://blog.csdn.net/xoyojank/article/details/8249719

    最近业余在做一个基于结点的编辑工具玩, 遇到一个问题, 就是结点和连线多了, 经常会出现重叠交叉的问题, 导致图看不清楚:


    要是这个样子, 还不如不用图清楚呢, 所心就需要找一个方法来进行自动布局, 理想情况是这样的(手动整理结果):


    当然, 手动整理的话, 每个人弄出来的结果都不一样. 自动的算法肯定没有100%完美的, 但是总是能方便不少的

    在google了一会儿后, 发现这种结点-线组成的图是一有个学名的: directed acyclic graph, 例如这样:


    无非我这个图结点上的连接点是有限制的, 但这个对于布局算法来说, 影响不大. 因为布局只需要大体考虑每个结点的位置

    那么, 这个算法需要满足几个条件: 

    1. 结点之间不能有重叠
    2. 连线之间尽量减少交差
    3. 结点之间是有基本的层次关系对齐的
    基于这些限制条件, google到一个比较有名的算法 Sugiyama's layout algorithm
    初步看了一上, 这个算法比较复杂, 是多种算法的集合
    自己不是很熟悉这方面的理论知识, 所以还是决定采用第三的算法库
    C++可以使用的图绘制算法库, 比较常见的有Graphviz, OGDF, Boost Graph
    根据这个问题(http://stackoverflow.com/questions/2751826/which-c-graph-library-should-i-use)的推荐, 尝试了OGDF, 效果还不错(可惜是GPL协议)
    [cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
    1. //------------------------------------------------------------------------------  
    2. void  
    3. QNodesEditor::autoLayout()  
    4. {  
    5.     using namespace ogdf;  
    6.     Graph graph;  
    7.     // setup graph  
    8.     QMap<NodeElement*, QNEBlock*> nodeMap;  
    9.     foreach(QGraphicsItem * item, scene->items())  
    10.     {  
    11.         if (item->type() == QNEBlock::Type)  
    12.         {  
    13.             NodeElement* node = graph.newNode();  
    14.             item->setData(QNEBlock::Type, qVariantFromValue((void*)node));  
    15.             nodeMap[node] = (QNEBlock*)item;  
    16.         }  
    17.     }  
    18.     foreach(QGraphicsItem * item, scene->items())  
    19.     {  
    20.         if (item->type() == QNEConnection::Type)  
    21.         {  
    22.             QNEConnection* connection = (QNEConnection*)item;  
    23.             NodeElement* node1 = (NodeElement*)connection->port1()->block()->data(QNEBlock::Type).value<void*>();  
    24.             NodeElement* node2 = (NodeElement*)connection->port2()->block()->data(QNEBlock::Type).value<void*>();  
    25.             graph.newEdge(node1, node2);  
    26.         }  
    27.     }  
    28.     // node size  
    29.     GraphAttributes graphAttr(graph,  
    30.                               GraphAttributes::nodeGraphics | GraphAttributes::edgeGraphics |  
    31.                               GraphAttributes::nodeLabel | GraphAttributes::nodeColor |  
    32.                               GraphAttributes::edgeColor | GraphAttributes::edgeStyle |  
    33.                               GraphAttributes::nodeStyle | GraphAttributes::nodeTemplate);  
    34.     NodeElement* node;  
    35.     forall_nodes(node, graph)  
    36.     {  
    37.         QNEBlock* item = nodeMap[node];  
    38.         graphAttr.width(node) = item->getHeight();  
    39.         graphAttr.height(node) = item->getWidth();  
    40.     }  
    41.   
    42.     // compute layout  
    43.     SugiyamaLayout layout;  
    44.   
    45.     FastHierarchyLayout* ohl = new FastHierarchyLayout;  
    46.     ohl->layerDistance(30);  
    47.     ohl->nodeDistance(25);  
    48.     layout.setLayout(ohl);  
    49.   
    50.     layout.call(graphAttr);  
    51.   
    52.     // update node position  
    53.     forall_nodes(node, graph)  
    54.     {  
    55.         double x = graphAttr.x(node);  
    56.         double y = graphAttr.y(node);  
    57.         QNEBlock* item = nodeMap[node];  
    58.         item->setPos(y, x);  
    59.     }  
    60. }  
    最终效果:

    展开全文
  • 对一个有向无环图(Directed Acycqc Graph,DAG)G进行拓扑排序,是将G中所有顶点排成线性序列,使得中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前 一种可能的拓扑排序结果2-&amp;amp;...

    拓扑排序 示例:

    对一个有向无环图(Directed Acyclic Graph,DAG)G进行拓扑排序,是将G中所有顶点排成线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前
    一种可能的拓扑排序结果2->8->0->3->7->1->5->6->9->4->11->10->12
    拓扑排序

    算法分析

    拓扑排序的方法
    从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它;
    从网中删去该顶点,并且删去从该顶点发出的全部有向边;
    重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止。

    Python代码如下:

    解法1:用邻接矩阵表示图的拓扑排序

    import numpy as np
    
    
    def topological_sort(g):
        n = len(g)
        # 获取所有入度为0的结点
        q = []
        for j in range(n):
            flag = True
            for i in range(n):
                if g[i][j] == 1:
                    flag = False
                    break
            if flag:
                q.insert(0, j)
    
        li = []  # 记录结果
        while len(q) > 0:
            # p出队,把从p出度的数据置为0
            p = q.pop()
            li.append(p)
            for i in range(n):
                if g[p][i] == 1:
                    g[p][i] = 0  # 去掉连通
                    # 如果结点i的入度为0则入队结点i
                    in_degree_count = 0
                    for u in g:
                        if u[i] == 1:
                            in_degree_count += 1
                    if in_degree_count == 0:
                        q.insert(0, i)
    
        return li
    
    
    if __name__ == '__main__':
        # 用邻接矩阵表示图
        # 初始化图的数据,连通的标记为1
        g = np.zeros(shape=(13, 13), dtype='int')
        # g[i][j] = 1 表示 i -> j
        g[0][1] = g[0][5] = g[0][6] = 1
        g[2][0] = g[2][3] = 1
        g[3][5] = 1
        g[5][4] = 1
        g[6][4] = g[6][9] = 1
        g[7][6] = 1
        g[8][7] = 1
        g[9][10] = g[9][11] = g[9][12] = 1
        g[11][12] = 1
    
        result = topological_sort(g)
        print(result)

    输出结果:[2, 8, 0, 3, 7, 1, 5, 6, 4, 9, 10, 11, 12]

    解法2:用邻接表表示图的拓扑排序

    def topological_sort2(g):
        n = len(g)
        # 计算所有结点的入度
        in_degree = [0] * n
        for i in range(n):
            for k in g[i]:
                in_degree[k] += 1
        # 入度为0的结点
        in_degree_0 = []
        for i in range(n):
            if in_degree[i] == 0:
                in_degree_0.insert(0, i)
    
        li = []  # 记录结果
        while len(in_degree_0) > 0:
            # p出队
            p = in_degree_0.pop()
            li.append(p)
            for k in g[p]:
                # 对应结点的入度减1
                in_degree[k] -= 1
                if in_degree[k] == 0:
                    in_degree_0.insert(0, k)
    
        return li
    
    
    if __name__ == '__main__':
        # 用邻接表表示图
        g2 = [[]] * 13
        g2[0] = [1, 5, 6]
        g2[2] = [3]
        g2[3] = [5]
        g2[5] = [4]
        g2[6] = [4, 9]
        g2[7] = [6]
        g2[8] = [7]
        g2[9] = [10, 11, 12]
        g2[11] = [12]
        result2 = topological_sort2(g2)
        print(result2)

    输出结果:[0, 2, 8, 1, 3, 7, 5, 6, 4, 9, 10, 11, 12]

    展开全文
  • 图文并貌的DAG(有向无环图)拓扑排序:Kahn算法 正在从小白成长的我想写一个小白看得懂的DAG拓扑排序!不要嫌我啰嗦噢! 目录 1.什么是DAG 2.什么是拓扑排序 3.Kahn算法思想 4.Kahn算法代码实现 5.运行结果
  • JGraph,有向图自动布局,内置多种布局策略,支持层状、装等多种布局方式。
  • 文字环绕图片布局

    千次阅读 2018-12-20 16:31:30
    实现文字环绕图片布局。  &lt;div style="width:400px;"&gt; &lt;div style="float:left; clear: both;" align="center"&gt; &lt;img src="/images/w...
  • 有向有环图的层次布局算法(一)

    千次阅读 2013-01-04 17:45:36
    [本文介绍的有向有环图的层次布局算法是Sugiyama和Gansner的算法。] 目标 有向有环图(Directed Cycline Graph DCG)的定义就不解释了,这里首先列出DCG布局的期望效果: 显示中的分层结构,连线均沿同...
  • 图文环绕布局css

    千次阅读 2018-09-07 15:05:45
    <style> .box{ width: 500px; border: 1px solid #000; } .box img{ float: left; } </style> <body> <div class="box"> <img src="img/1.jpg" alt="">...这是内...
  • HTML/CSS实现文字环绕图片布局

    千次阅读 2019-07-13 09:51:50
    在一个图文并茂的网页上,文字环绕图片可以使布局美观紧凑,如何实现呢?两种办法: 1.利用图片属性实现 代码如下: <p sty...
  • 解决文字环绕图片布局问题

    千次阅读 2018-06-01 20:52:03
    通过设置img属性hspace和vspace解决:&lt;p style="width:500px;"&gt; &lt;img src="images/tu.jpg"... 文字围绕布局,hspace设置图片与文字左右距离,vspace设置图片与
  • 有向无环图中, 两点间的简单路径数

    千次阅读 2013-05-23 17:19:20
    已知有向无环图 G = (V, E) 和两点 s, t. 给出一个线性时间的算法, 返回在 G 中 s 到 t 的简单路径数. 例如下 (算法导论 Figure 22.8),  该有向无环图存在4条简单路径从点 p 到 点 v : po, pory, posry 和 psry. ...
  • 行业资料-建筑装置-带传感器单元的锭纺纱布局.zip
  • Flex实现环绕布局

    千次阅读 2016-05-08 12:09:36
    html,body{ width: 100%; height: 100%; } html,body,ul,li,a{ padding: 0; margin: 0; list-style-type: none; text-decoration: none; } .sup{
  • 之前做布局大多是按照方格排成几排,围成一个圈的貌似原生的组件里没有。所以需要自己实现一个,好在不算太难。具体思路很简单:就是设定半径、开始角度、间隔角度以及各个子对象的大小,然后用代码让他们像上那样...
  • 这篇文章主要介绍了Android实现文字和图片混排的方法,实例分析了文字环绕图片效果的具体功能显示及页面布局实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下 本文实例讲述了Android实现文字和图片混排(文字...
  • G6 提供了 9 种一般布局和 4 种树布局: 一般: Random Layout:随机布局; Force Layout:经典力导向布局;(布局网络中粒子之间具有引力和斥力,从随机无序的布局不断演变为趋于平衡稳定的布局。适用...
  • 不带权有向图无向图效果展示分段代码全部源代码:传送门 当我们处理完几百几千乃至上万的图论数据后总是不可避免地要对数据进行数据可视化等的分析 ,甚至要在画好图的基础上进行一些上层修改,增加连线,高亮...
  •  前边的几篇博客,我们了解了UICollectionView的基本用法以及一些扩展,在不定高的瀑布流布局中,我们发现,可以通过设置具体的布局属性类UICollectionViewLayoutAttributes来设置设置每个item的具体位置,我们可以...
  • 原理:在图片所在的div前面增加一个宽度为1px的空div,使空div和图片所在的div都左/右浮动,再清除图片所在的div受左/右浮动的影响。这样,空div 会把图片挤下去。修改空div的高度,可以调整图片的位
  • 行业文档-设计装置-充气网柜气箱的布局结构.zip
  • android自定义圆形布局CircleLayout

    千次下载 热门讨论 2014-12-13 13:11:14
    自己写的简单的圆形布局layout,布局内部可以放各种控件,如Textview,ImageView,Edittext,Button 等等,希望对大家有用!
  • 印刷电路板布局是整个PCB设计中最重要的一,对于模拟电路和高频电路尤为关键。  Protel提供两种布局方式:手工布局和自动布局。布线的关键是布局,多数设计者采用手工布局的形式。手工布局的方法是:用鼠标选中...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 41,074
精华内容 16,429
关键字:

有向无环图布局