精华内容
下载资源
问答
  • 优先矩阵图也被认为是矩阵数据分析法,与矩阵图法类似,只是矩阵图上各元素间的关系用数据进行量化,使整理和分析结果更加精确。它是新的质量管理七种工具之一,是一种定量分析问题的方法。优先矩阵是针对通过头脑...
    4687b49437b20916678dba7f8480d1aa.png

    优先矩阵图也被认为是矩阵数据分析法,与矩阵图法类似,只是矩阵图上各元素间的关系用数据进行量化,使整理和分析结果更加精确。它是新的质量管理七种工具之一,是一种定量分析问题的方法。

    优先矩阵是针对通过头脑风暴得到的众多面临问题或解决问题的措施,确定优先解决的问题或优先采取的措施的方法。在QC新七种工具中,它是唯一种利用数据分析问题的方法,但其结果仍要以图形表示。

    它区别于矩阵图法的是:不是在矩阵图上填符号,而是填数据,形成一个分析数据的矩阵。目前,在日本尚未广泛应用,只是作为一种“储备工具”提出来的。应用这种方法,往往需求借助电子计算机来求解。

    它的主要方法为主成分分析法,利用此法可从原始数据获得许多有益的情报。主成分分析法是一种将多个变量化为少数综合变量的一种多元统计方法。

    864e714b4426f656e6df75ef0acf3d66.png

    优先矩阵具备3个优点:

    ·它是确定主要薄弱环节的一种有效手段,这些环节的运营可能已经严重阻碍或妨碍了主要改进目标的实现。

    ·它提供了确立优先顺序的可能,以便把资源分配到改进过程上来。

    ·它有助于团结一支管理队伍来支持各方一致同意的优先环节。

    优先矩阵的目的是帮助人们在矩阵图或树图的分析中,根据权重系数和决定准则测量/评价关联性,以决定要优先实施的方案。一旦我们通过诸如关系矩阵图、关联图、树图或其他方法构建/识别了关联和选项/可选方案后,一般就要进入决定阶段。优先矩阵可以让我们进行相关比较,并以一种有组织的方式表达信息,这样我们可以根据一致、客观和量化的评价支持我们做出的决定。

    在日常工作中,当我们进行顾客调查、产品设计或者其他各种方案选择,做决策的时候,往往需要确定对几种因素加以考虑,然后,针对这些因素要权衡其重要性,加以排队,得出加权系数。

    e5be37aad2073cead907f2067d502f38.png

    在日常使用中,我们经常和其他工具结合使用:

    1.可以利用亲和图把这些要求归纳成几个主要的方面。然后,利用这里介绍进行成对对比,再汇总统计,定量给每个方面进行重要性排队。

    2.过程决策图执行时确定哪个决策合适时可以采用。

    3.质量功能展开。优先矩阵是各个因素之间的相互对比,确定重要程度;而质量功能展开可以利用这个方法的结果。用来确定具体产品或者某个特性的重要程度。

    当然,还有其他各种方法可以采用,但是,优先矩阵的好处之一是可以利用电子表格软件来进行。

    bd929dda30e24a5c5a5da29a3ef5ca0d.png

    我们平常该如何使用矩阵数据分析法呢? 下面通过例子来简单介绍。

    1、确定需要分析的各个方面。我们通过亲和图得到以下几个方面,需要确定它们相对的重要程度:易于控制、易于使用、网络性能、和其他软件可以兼容、便于维护。

    2、组成数据矩阵。用Excel或者手工做。把这些因素分别输入表格的行和列,如表所示。

    3、确定对比分数。自己和自己对比的地方都打0分。以 “行”为基础,逐个和“列”对比,确定分数。“行”比“列”重要,给正分。分数范围从9到1分。打1分表示两个重要性相当。譬如,第2行“易于控制”分别和C列“易于使用”比较,重要一些,打4分。和D列“网络性能”比较,相当,打1分。…………如果“行”没有“列””重要,给反过来重要分数的倒数。譬如,第3行的“易于使用”和B列的“易于控制”前面已经对比过了。前面是4分,现在取倒数,1/4=0.25。有D列“网络性能”比,没有“网络性能”重要,反过来,“网络性能”比“易于使用”重要,打5分。现在取倒数,就是0.20。实际上,做的时候可以围绕以0组成的对角线对称填写对比的结果就可以了。

    表1:矩阵数据分析法

    c55613400a357bde1abf82a0187041e1.png

    4、加总分。按照“行”把分数加起来。在G列内得到各行的“总分”。

    5、算权重分。把各行的“总分”加起来,得到“总分之和”。再把每行“总分”除以“总分之和”得到H列每个“行”的权重分数。权重分数愈大,说明这个方面最重要,“网络性能”34.9分。其次是“易于控制”26.2分。

    展开全文
  • 数组与矩阵数组是由一组相同类型的数据元素构成的有限序列,访问数据元素的方式是使用元素各自的序号进行访问,也就是下标。数组它本身是线性表的推广,一维数组就是一个向量形式的线性表,二维数组就是由一维数组...

    前言

    一入编程深似海,从此砖头是爱人,日日搬,夜夜搬,搬到天荒地老,精尽人亡,直教人失去了自我,忘记了时间,忽然之间发现九月份快没了,赶紧写篇博客打个卡,证明一下我还活着。。。

    数组与矩阵

    数组是由一组相同类型的数据元素构成的有限序列,访问数据元素的方式是使用元素各自的序号进行访问,也就是下标。数组它本身是线性表的推广,一维数组就是一个向量形式的线性表,二维数组就是由一维数组组成的线性表。

    在许多科学计算和工程应用中,经常要用到矩阵的概念,我们用的最多的其实就是Mysql的表,表数据都是行列存储,这就是矩阵。

    由于矩阵具有元素数目固定以及元素按下标关系有序排列等特点,所以在使用高级语言编程时,一般都是用二维数组来存储矩阵。

    数组的顺序存储

    为什么是顺序存储?

    我想问这个问题就太低级了。因为它是数组,数据的存储方式分为顺序存储和链式存储两种,数组一旦被定义,他的维数和维界就已固定,除结构的初始化和销毁外,数组只会有存取元素和修改元素的操作,不存在插入和删除操作,所以数组适合用顺序存储。

    数组存放在内存中的映射关系

    数组可以是多维的,但是内存空间却是一维的,所以我们就要把多维数组通过一定的映射顺序把它变成一维的,然后存储到内存空间之中。

    在大多数高级编程语言中,多维数组在内存中通常有两种不同的顺序存储方式, 按行优先顺序存储 按列优先顺序存储

    举个例子,以下3行4列的一个二维数组矩阵:

    a1,a2,a3,a4

    b1,b2,b3,b4

    c1,c2,c3,c4

    按行优先顺序存储:

    43cbf7ecba4b96991623c0a20a0662ea.png

    按列优先顺序存储:

    bc4bdd8979af3d71c7242413c1d65810.png

    地址计算

    地址计算的意思就是给定数组下标,求在一维内存空间的地址,从而取出数据。

    我们先来看一维数组的地址计算

    一维数组内的元素只有一个下标,存储方法和普通的线性表一样。

    如一维数组 A = [a1,a2,a3,......ai,.........,an],每个元素占用size个存储单元(就是内存大小),那么元素ai的存储地址为 A[0]的位置 + (i-1)*size

    再来看二维数组的地址计算

    以二维数组Amn为例,首元素为A[0][0],数组中任意元素A[i][j]的地址为:A[0][0]的位置 + (n * (i-1) + (j-1))* size;

    比如:一个5行4列的二维数组A,按行存储,其中每个元素占2个存储单元,首元素地址是1000,求第3行第2列的元素在内存中的地址。

    我们把参数套进公式中,答案 = 1000 + (4 * (3-1) + (2-1)) * 2 = 1018;

    如果把矩阵画在纸上观察就一目了然:

    5bd0250698ee58449d6f4948a176159b.png

    公式的内容就是求出格子数,乘以每个格子所占用的存储单元,再加上首地址。

    矩阵转置

    设计一个算法,实现矩阵A(m*n) 转置为矩阵B(n*m),简单的说,就是行列互换。

    $arr = [ ['张三','男','北京'], ['李四','女','上海'], ['王五','男','广州'],];function transpose($a){ $b = []; for ($i = 0;$i < count($a); $i ++){ for($j = 0;$j < count($a[$i]); $j ++){ $b[$j][$i] = $a[$i][$j]; } } return $b;}$result = transpose($arr);

    结果为:

    $result = [

    ['张三','李四','王五'],

    ['男','女','男'],

    ['北京','上海','广州'],

    ];

    特殊矩阵

    特殊矩阵的压缩存储

    特殊矩阵指的是具有许多相同元素或者零元素,并且这些元素的分布有一定规律性的矩阵。

    这种矩阵如果还使用前面的方式来存储,就会产生大量的空间浪费,为了节省存储空间,可以对这类矩阵采用压缩存储,压缩存储的方式是把那些呈现规律性分布的相同元素只分配一个存储空间,对零元素不分配存储空间。

    三角矩阵

    三角矩阵我们以下三角来做例子,如图所示:

    e4300bbcdb2c0c8b862c86c34485f082.png

    所有空格之中装的数据都是null或者都是同一常量,也就是空格中全都是相同的数据。

    按行方式存储的情况下,一维存储内存空间的大小是:1+2+3+4+5+6+7 = n(n+1)/2 = 7 * (7+1) / 2 = 28,当然,在最后还要加一个存储空间,用来存储上三角中相同的数据。

    那么对于任意元素aij,在一维存储内存空间中的地址仍然是要靠计算格子来得到,先算出占满行的总格子数,再加上当前行的格子数:a[0][0]的位置 + (i * (i+1) / 2 + j) * size;

    我们使用公式来验证一下,a42的所在格子数 = (i * (i+1) / 2 + j) = 4 * 5 / 2 + 2 = 12

    带状矩阵

    带状矩阵也叫做对角矩阵,如图所示:

    2e54324b8d44aafed8ba1846ad761881.png

    带状矩阵的特征是:所有非0元素都集中在以主对角线为中心的3条对角线区域,其他区域的元素都为0。

    除了第一行和最后一行仅2个非零元素,其余行都是3个非零元素,换句话说就是每行都是3个非零元素,但是第一行少了1个,最后一行少了1个,所以所需的一维空间大小为:3n - 2;

    那么对于任意一个元素 aij,怎么计算它在内存空间的地址呢?

    经过观察可以得知i和j都在对角线附近,相减后的结果与分布情况分别如下

    j - i = 1;对角线上面

    j - i = 0; 对角线

    j - i = -1;对角线下面

    不管是在对角线的哪个位置,我们都可以使用通用的办法来计算地址,也就是先计算出上面行所占的格子,再加上当前行的格子。

    上面的行数:i,由于行列都是0开头计数,所以上面的行数就是i这个值。

    上面的格子数: 3 * i - 1,减1是因为第一行少一个格子。

    当前行格子数: j - i + 1;根据i和j的关系,我们把相减后的值加1,得到当前行的格子数。

    那么最后aij的内存地址 = a00首地址 + ((3 * i -1) + ( j-i+1)) * size; size为每个数据所占用的存储单元大小。

    比如首地址为1000,每个数据占用2个存储单元,那么a45在内存中的地址 = 1000 + 13 * 2 = 1026;

    稀疏矩阵的压缩存储

    由于特殊矩阵中非零元素的分布是有规律的,所以总是可以找到矩阵元素与一维数组下标的对应关系,但还有一种矩阵,矩阵中大多数元素都为0,一般情况下非零元素个数只占矩阵元素总数的30%以下,并且元素的分布是没有任何规律的,这样的矩阵我们称为稀疏矩阵。

    如果采用常规方法存储稀疏矩阵,就会相当浪费存储空间,因此我们需要只存储非零元素。由于稀疏矩阵中非零元素的分布是没有规律的,所以除了存储非零元素的值之外,我们还需要同时存储非零元素的行、列位置,也就是三元组(i,j,aij)。

    如图:

    6fcc7f87145f5e3b97672cbbeb2f7d03.png

    所谓三元组,也就是一个矩阵,一个二维数组,每一行都三个列,分别为行号、列号、元素值。

    由于三元组在稀疏矩阵与内存地址间扮演了一个中间人的角色,所以稀疏矩阵进行压缩存储后,便失去了随机存取的特性。

    展开全文
  • 还得了解“邻接矩阵”的用法。示例:在下图(graph)中,找到从A点到H点的最短距离。广度优先算法的搜索方式:通过逐层遍历所有相邻节点,从而暴力的找出最短路径。如下图:代码演示:using System; using ...

    ba6fee1370423a1f736848ca9445513e.png

    概念:

    "广度优先搜索"是一种通过逐层遍历所有访问对象,从而找到通过最短节点数到达目标的算法。

    学习准备:

    学习前,需要先掌握图(Graph)、队列(queue)、栈(stack)的概念。还得了解“邻接矩阵”的用法。

    示例:

    在下图(graph)中,找到从A点到H点的最短距离。

    a27e1b9466df72826ef7f05c8ad5e014.png

    广度优先算法的搜索方式:通过逐层遍历所有相邻节点,从而暴力的找出最短路径。如下图:

    d2580f0db848282f9f6bdd5df732023d.png

    代码演示:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections;//调用queue的时候需要该名称空间
    
    
    namespace 广度优先搜索
    {
    
        class nodeClass
        {
            public string nodeName;
            public bool isVisited;
            public nodeClass(string name)//类的构造器
            {
                nodeName = name;
            }
        }
    
        class Gragh
        {
            const int nodeNumMax = 10;
            nodeClass[] nodes = new nodeClass[nodeNumMax];//节点数组
            int[,] adjmatrix = new int[nodeNumMax, nodeNumMax];
    
            int nodeNumNow = 0;//统计当前有几个节点数
    
            public Gragh()//利用类构造器的优先机制,首先初始化图的关系矩阵
            {
                for (int i = 0; i < nodeNumMax; i++)
                {
                    for (int j = 0; j < nodeNumMax; j++)
                    {
                        adjmatrix[i, j] = 0;
                    }
                }
            }
    
            public void addNode(string newNodeName)
            {
                nodes[nodeNumNow] = new nodeClass(newNodeName);
                nodeNumNow++;
            }
    
            public void addEdge(int nodeNum1, int nodeNum2)
            {
                adjmatrix[nodeNum1, nodeNum2] = 1;
            }
    
            public void displayNode(int nodePosition)
            {
                Console.WriteLine(nodes[nodePosition].nodeName);
            }
    
            public int visiteNode(int oneNode)//检查某节点是否还有未访问过的相邻节点。
            {
                for (int j = 0; j < nodeNumMax; j++)
                {
                    if (adjmatrix[oneNode, j] == 1 && nodes[j].isVisited == false)
                        return j;
                }
                return -1;
            }
    
            public void 广度优先搜索()
            {
                //创建队列,以方便实现自动搜索。
                Queue nodeQueue = new Queue();
                //访问第一个节点
                nodes[0].isVisited = true;
                displayNode(0);
                nodeQueue.Enqueue(0);
    
                //访问之后的节点
                int node1;
                int node2;
    
                while (nodeQueue.Count > 0 && nodes[nodeNumNow - 1].isVisited != true)//除了判断节点以外,新加了一个判断,当最后一个节点被访问了以后,整个循环就停止
                {
                    node1 = (int)nodeQueue.Dequeue();//将队列中的第一个节点弹出,并记录。
                    node2 = visiteNode(node1);//寻找节点1指向的节点。
    
                    while (node2 != -1 && nodes[nodeNumNow - 1].isVisited != true)
                    {
                        Console.WriteLine(nodes[node1].nodeName + "=>" + nodes[node2].nodeName);//显示哪个节点指向哪个节点。
                        //广度优先搜索,首先就是把与第一个点相邻的点全部找出来,储存在queue里面。
                        nodeQueue.Enqueue(node2);
                        nodes[node2].isVisited = true;
                        displayNode(node2);
                        node2 = visiteNode(node1);
                    }
                }
            }
    
            //重置所有被访问过的节点
            public void resetNode()
            {
                for (int i = 0; i < nodeNumMax; i++)
                {
                    nodes[i].isVisited = false;
                }
            }
        }
    
    
    
        class Program
        {
            static void Main(string[] args)
            {
                Gragh graphInstance = new Gragh();
    
                //添加节点
                graphInstance.addNode("A");//编号0
                graphInstance.addNode("B");//编号1
                graphInstance.addNode("C");//编号2
                graphInstance.addNode("E");//编号3
                graphInstance.addNode("D");//编号4
                graphInstance.addNode("F");//编号5
                graphInstance.addNode("G");//编号6
                graphInstance.addNode("H");//编号7
    
                //添加边
                graphInstance.addEdge(0, 1);//A=>B
                graphInstance.addEdge(0, 2);//A=>C
                graphInstance.addEdge(1, 4);//B=>D
                graphInstance.addEdge(4, 2);//D=>C
                graphInstance.addEdge(2, 3);//C=>E
                graphInstance.addEdge(4, 5);//D=>F
                graphInstance.addEdge(3, 5);//E=>F
                graphInstance.addEdge(5, 6);//F=>G
                graphInstance.addEdge(0, 0);//G=>H
                graphInstance.addEdge(2, 7);//C=>H
    
                graphInstance.广度优先搜索();
    
            }
        }
    }
    
    展开全文
  • 通用矩阵乘(General Matrix Multiplication,简称gemm)是深度学习框架的核心计算单元之一,广泛用于Convolution、Full connection、Matmul等算子实现。GEMM示意图上图中,LHS(left hand side)代表左矩阵,RHS代表...

    通用矩阵乘(General Matrix Multiplication,简称gemm)是深度学习框架的核心计算单元之一,广泛用于Convolution、Full connection、Matmul等算子实现。

    4d4761aac89e027309a331f854180a9a.png
    GEMM示意图

    上图中,LHS(left hand side)代表左矩阵,RHS代表右矩阵,[M, K]*[K, N],输出矩阵维度为[M, N]。卷积算子的计算方式通常使用im2col的方法转换成GEMM的形式。这种情况下,M、K和N有具体含义,M代表input tensor的height*weight, K代表input的channels,N代表ouput的channels。

    切分

    4a1fbc7947104203c85637ca3890a358.png
    切分方式一

    7eec917b6e656e7bf52f505702118f8c.png
    切分方式二

    切分方式一采用了类似传统矩阵乘“点积”的计算方式,切分方式二采用了“千层糕”的计算方式。二者的计算量相同,区别是输入和输出数据的内存访问顺序不同。方式一对并行计算的支持要好于方式二,因为方式一对于输出地址只写一次,我们可以将输出划成多块,然后在CPU上交给不同的线程去处理,线程间无依赖关系。方式二对输出地址需要多次读写,会产生线程间依赖,需要进行线程同步。本文选择切分方式一。

    数据PACK

    为了减少cache miss,我们需要提前将数据按照计算方式进行重排,以便计算时能按连续内存读取。

    209d1e28c70baddc8304237fa636ec81.png
    重排方式一

    重排方式一对左矩阵的分块按列优先(Column-major)进行重排,对右矩阵的分块按行优先(Row-major)进行重排。

    c28490e4d048937143ccd53a65c21f4d.png
    重排方式二

    重排方式二对左矩阵的分块按行优先进行重排,对右矩阵的分块按列优先进行重排。注意这里的行优先的行、列优先的列都是局部的,不是完整的行或者列,因此从外层循环来看,还是属于重排方式一的形式。重排方式二是重排方式一的一种特殊形式。

    核心计算

    3931ffc40f4490d447faa7fd08128c03.png
    核心kernel计算

    0ffdba380dc4a48b4b523a05b1100624.png
    ARM v8指令集Float32数据类型Neon寄存器排布

    0752a16c5880a98ae18285b53cd67ef6.png
    ARM v7指令集Float32数据类型Neon寄存器排布

    170403122b690cea088a4a08600fb179.png
    ARM v8指令集Int8数据类型Neon寄存器排布

    4f0668cd06c499cb74245c58c8d0e08c.png
    ARM v7指令集Int8数据类型Neon寄存器排布

    以上给出了ARM架构几种不同指令集和数据类型下的相对较优的排布方式。块切分的原则是Neon寄存器利用最大化。另外,FLOAT32使用了重排方式一。INT8使用了重排方式二,原因是v7和v8的向量乘指令不支持int8的vector和scalar的运算,另外arm v8.2有更高效的int8 sdot运算指令,更适合点积运算。

    循环策略

    71f447c66fa85371c419f0a059105908.png
    Row-Col循环

    ef621017707a65156cb890d255a49133.png
    Col-Row循环

    row是指M,col是指N。 以Convolution 1x1算子为例,row对应的是input的height*width,col对应的是output channels,一般来说row会远大于col,如果按照Col-Row循环,LHS太大导致无法整个塞入L1 cache,每列遍历的时候都会发生LHS的cache miss,影响效率。而如果按照Row-Col循环,每行遍历的时候,RHS都会在L1 cache中,执行效率更高。

    多线程划分策略

    和循环策略类似,遵循减少cache miss的原则,如果M>N,按M来划分。如果N>M,按N来划分。

    468255955add7ca6362a295fbdf2ef36.png
    两线程按M切分

    其他优化点

    减少计算量:pack的过程会将行列向上对齐,比如按行按12切分的话,如果实际只有20行,会额外补4行,而最终的计算结果并不需要这4行,这会造成额外的计算成本。所以对于这些额外的行列,需要单独适配计算方案,比如如果kernel block是12x8,那么对于不足部分,可以以12x4/8x8/8x4/4x4等进行计算。

    边pack边计算:可以提前对整个完整矩阵进行pack,然后进行分块计算,但这样做通常效率比较低,特别是对于arm v7设备来说,影响更明显。对分块先pack,再计算,然后再pack下一个分块,效率会更高。当然,对于权重来说,可以在模型初始化的时候进行pack,不存在这个问题。

    参考

    https://www.cs.utexas.edu/~flame/pubs/GotoTOMS_revision.pdfwww.cs.utexas.edu白牛:OpenBLAS gemm从零入门zhuanlan.zhihu.com
    db9743e5642d9355c983786c6525429d.png
    旷视科技:工程之道 | CPU推理性能提高数十倍,MegEngine计算图、MatMul优化解析zhuanlan.zhihu.com
    2b1210dbfebbbb5d20c502f07089e049.png
    MindSpore官网www.mindspore.cnhttps://github.com/google/ruygithub.com
    展开全文
  • 广度优先搜索 广度优先搜索算法(英语:Breadth-First Search,缩写BFS),又译作宽度优先搜索,或横向优先搜索,是一种图形搜索方法。简单的说,BFS是从根节点开始,沿着树德宽度遍历树德节点。如果所有节点均被...
  • 其实机器学习场景中还有一类非常常见的,就是推荐,特别是在线购物、文娱产品为了提升用户体验,一个比较好的主意就是让用户优先看到他需要的物品、内容,甚至提供用户意料之外又情理之中的产商品。推荐算法正好能够...
  • 若已知运算符之间的优先关系,可按如下步骤构造优先函数: 1、对每个运算符a(包括#在内)令f(a)=g(a)=1 2、如果a⋗b且f(a)<=g(b)令f(a)=g(b)+1 3、如果a⋖b且f(a)>=g(b)令g(b)= f(a)+1 4、如果a≐b而f(a)...
  • 什么是矩阵的秩?如何研究矩阵?要诀:变换 -- 等价关系 -- 分类 -- 代表元 -- 不变量.分类别是将复杂的事物说清楚的重要方法秩, 秩序. 有统一的标准才有秩序, 有了标准就可以进行分类. 标准其实就是某种等价关系. 比如...
  • 等价关系在网络分析、图论、模式识别和数据库技术等方面都有许多应用,而任意等价关系矩阵都置换合同于块1-对角矩阵标准形,从置换运算的角度分析置换合同的几条性质,提出基于图的深度优先搜索策略的置换矩阵构造...
  • 什么是行优先和列优先? 故名思意,当我们表示一个矩阵的时候把行放在前面就是行优先,把列放在前面就是列优先。 ... ,用一个列优先的平移矩阵表示为,两个矩阵关系也不难看出其实是互为转...
  • 与达到目的最优先考虑的选择或二者挑一的抉择有关系的数据,用一个简略的双轴的相关关系图表示出来,相关关系的程度可以用符号或数值来代表。它区别于矩阵图法的是:不是在矩阵图上填符号,而是填数据,形成一个数据...
  • 会文化的需求如人际关系,是以某些原则为基础的,其中最重要的就是人与人之间的互相信赖。这种互相信赖,源自于宽容,或者负责、体贴、归属感等等,甚至可以说是无私的爱。在心理需求方面,很多人追求一种临时抱佛脚...
  • 在邻接矩阵中,可以如下表示顶点和边连接关系: 说明: 将顶点对应为下标,根据横纵坐标将矩阵中的某一位置值设为1,表示两个顶点向联接。 图示表示的是无向图的邻接矩阵,从中我们可以发现它们的分布关于斜对角线...
  •  在邻接矩阵中,可以如下表示顶点和边连接关系:   说明:  将顶点对应为下标,根据横纵坐标将矩阵中的某一位置值设为1,表示两个顶点向联接。  图示表示的是无向图的邻接矩阵,从中我们可以发现它们的...
  • 如果看完本篇博客任有不明白的...常用的图的存储结构主要有以下二种:邻接矩阵邻接表邻接矩阵我们知道,要表示结点,我们可以用一个一维数组来表示,然而对于结点和结点之间的关系,则无法简单地用一维数组来表示了...
  • 因此图可以有一个二阶矩阵来记录各个节点的联通关系,由一个数组来记录各个节点的内容。图的广度优先遍历和深度优先遍历。 输出如下: 深度优先遍历: 1 2 4 8 5 6 3 7 广度优先遍历: 1 2 3 4 ...
  • 内含代码片段。原理包括算符优先的三种优先关系定义与判断方法,FIRSTVT集和LASTVT集的构造步骤;判断算符关系,构造算符优先关系矩阵的说明;根据矩阵分析句子合法性的步骤说明;实验结果包含输入与输出
  • 1.写在前面  图的存储结构有两种:一种是基于二维数组的... 在邻接矩阵中,可以如下表示顶点和边连接关系:   说明:  将顶点对应为下标,根据横纵坐标将矩阵中的某一位置值设为1,表示两个顶点向联接。...
  • 我们要对他进行深度优先搜索(基于邻接矩阵) 邻接矩阵的意思就是用矩阵的形式来表示图中顶点直接的邻接关系 如图所示我们可以得到矩阵如下 假设矩阵名字为matrix matrix[3][4]的值表示的就是从顶点3到顶点4...
  • 给出图的顶点数和顶点与顶点之间的连接关系,请输出用邻接矩阵存储的图的广度优先搜索顶点序列。 Input 输入的第一行是一个整数T表示测试示例的数目,每组示例的第一行有两个数m(2 Output 每组输出k行,...
  • 图的深度优先搜索(邻接矩阵)

    千次阅读 2014-03-20 17:13:47
    给出图的顶点数和顶点与顶点之间的连接关系,请输出用邻接矩阵存储的图的深度优先搜索顶点序列。 Input 输入的第一行是一个整数T表示测试示例的数目,每组示例的第一行有两个数m(2 Output 每组输出k行,每行为从...
  • 编译原理之算符优先分析

    千次阅读 2019-06-20 11:57:29
    2. 构造优先关系矩阵的算法?举例加以讲解;四. 算符优先分析法最左规约串的确定1. 最左素短语的定义是什么?2. 最左素短语的特征?如何根据其特征确定当前句型的最左可归约串?3. 什么是“单非产生式”,算符优...
  • 图主要有两种存储结构,邻接矩阵表示法,邻接链表表示法。以有9个顶点的图为例。如图所示邻接矩阵表示法typedef struct ...建立9个元素的数组用于表示元素并建立对应关系矩阵用于表示顶点之间的关系邻接链表表示法ty...
  • 邻接矩阵是一种采用大小为V*V的矩阵Adj来表示点和边的关系的。其中矩阵的值为布尔值,如果两个点i,j之间存在一条边,则Adj[i][j] = 1。  深度优先搜索,类似于树的前序遍历,本质上也是用堆栈来实现。应用包括了...
  • 02 图的存储2、图的存储结构邻接矩阵邻接表图a、邻接矩阵存储方法邻接矩阵:顶点之间相邻关系矩阵。图G(V,E)含 n(n>0)个顶点,则G的邻接矩阵A是 n 阶方阵;其中顶点编号为0 ~(n-1)。共有四种类型不带权无向图不...
  • 邻接矩阵介绍直接说,邻接矩阵是图的一种存储结构。那么图是什么呢?图是一种逻辑结构,和线性结构、树形结构、集合结构一样 是一种逻辑结构用来描述数据对象中的数据元素之间的关系。来看下图的定义:图(Graph)是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 386
精华内容 154
关键字:

优先关系矩阵