Exemple #1
0
 /// <summary>
 /// 添加一条相邻的边,有可能是前向或者后向
 /// </summary>
 public void InsertEdge(LGEdge e)
 {
     if (e.Source.Id == this.Id)
     {
         nedges.Add(e);
     }
     if (e.Destination.Id == this.Id)
     {
         pedges.Add(e);
     }
 }
Exemple #2
0
        /// <summary>
        /// 添加边
        /// </summary>
        public void InsertEdge(LCNode lcnode, int sid, int did)
        {
            if (sid <= 0 || sid > vertexs.Count)
            {
                throw new ArgumentOutOfRangeException();
            }
            if (did <= 0 || did > vertexs.Count)
            {
                throw new ArgumentOutOfRangeException();
            }
            //Console.Write("edge {0:d} {1:d}\n", sid, did);
            LGEdge e = new LGEdge(lcnode, vertexs[sid - 1], vertexs[did - 1]);

            vertexs[sid - 1].InsertEdge(e);
            vertexs[did - 1].InsertEdge(e);
            edges.Add(e);
        }
Exemple #3
0
 /// <summary>
 /// 设置边标记中点标号的对应位(设置为1)
 /// </summary>
 /// <param name="lge">给定的边</param>
 /// <param name="id">给定的点标号</param>
 /// <returns>对应的标记</returns>
 private int _EdgeSetFlag(LGEdge lge, int id)
 {
     if (id <= 32)
     {
         return(lge[1] |= (1 << (id - 1)));
     }
     if (id <= 64)
     {
         return(lge[2] |= (1 << (id - 33)));
     }
     if (id <= 96)
     {
         return(lge[3] |= (1 << (id - 65)));
     }
     if (id <= 128)
     {
         return(lge[4] |= (1 << (id - 97)));
     }
     throw new IndexOutOfRangeException();
 }
Exemple #4
0
 /// <summary>
 /// 得到边标记中点标号的对应位
 /// </summary>
 /// <param name="lge">给定的边</param>
 /// <param name="id">给定的点标号</param>
 /// <returns>对应的位的值(0或1,1返回true)</returns>
 private bool _EdgeGetFlag(LGEdge lge, int id)
 {
     if (id <= 32)
     {
         return(((lge[1] >> (id - 1)) & 1) != 0);
     }
     if (id <= 64)
     {
         return(((lge[2] >> (id - 33)) & 1) != 0);
     }
     if (id <= 96)
     {
         return(((lge[3] >> (id - 65)) & 1) != 0);
     }
     if (id <= 128)
     {
         return(((lge[4] >> (id - 97)) & 1) != 0);
     }
     throw new IndexOutOfRangeException();
 }
Exemple #5
0
 /// <summary>
 /// 判断这个边的所有标记是否为空
 /// </summary>
 /// <param name="lge">给定的边</param>
 /// <returns>是否为空,为空返回true</returns>
 private bool _EdgeEmptyFlag(LGEdge lge)
 {
     return(lge[1] == 0 && lge[2] == 0 && lge[3] == 0 && lge[4] == 0);
 } /// <summary>
Exemple #6
0
        /// <summary>
        /// 检查是否混联错误
        /// </summary>
        /// <returns>是否存在混联错误</returns>
        /// <detail>
        /// 当存在入度不等于出度的环时,说明这个环存在分支,即符合混联错误的条件
        /// 入度大于出度时存在向内的分支,入度小于出度时存在向外的分支
        /// 所以可以检查所有的联通分量,判断是否都合法
        /// 合法的条件为in(T)-out(S)+sum(in(a)-out(a)) == 0, a为环内不包含原终点的点
        /// in(T)是相对于终点T的出度,即所有能到达T的边的总数
        /// out(S)是相对于起点S的出度,即所有能从S到达该点的边的总数
        /// </detail>
        public bool CheckFusionCircuit()
        {
            btflag = new int[vertexs.Count(), 4];
            // 枚举每个点作为环的原点
            foreach (LGVertex lgv1 in vertexs)
            {
                // 出度为1的点不可能是环的原点
                if (lgv1.Edges.Count <= 1)
                {
                    continue;
                }

                /*
                 * in(T)和out(S)是无法直接获得的,需要从起点出发访问所有的边
                 * 并且点和边上的四个标记以位的方式存储这条边是否到达某个节点
                 * 标记1存储编号1-32,标记2存33-64,以此类推
                 * 对于每个相对于S的in(T),找到标记过的后向边的数量
                 * 对于每个相对于T的out(S),找出在对应位标记的前向边的数量
                 */
                foreach (LGVertex lgv2 in vertexs)
                {
                    lgv2[1] = lgv2[2] = lgv2[3] = lgv2[4] = 0;
                }
                foreach (LGEdge lge in edges)
                {
                    lge[1] = lge[2] = lge[3] = lge[4] = 0;
                }
                _EdgeSearch(lgv1);
                LGEdge flagedge = new LGEdge(null, null, null);
                foreach (LGVertex lgv2 in vertexs)
                {
                    // 该点应不为起点
                    if (lgv2.Id == lgv1.Id)
                    {
                        continue;
                    }
                    int sum = 0, sumin = 0, sumout = 0;
                    flagedge[1] = flagedge[2] = flagedge[3] = flagedge[4] = ~0;
                    // 检查终点的所有后向边,统计in(T)
                    foreach (LGEdge lge in lgv2.BackEdges)
                    {
                        if (!_EdgeEmptyFlag(lge))
                        {
                            sumin++;
                        }
                    }
                    // 检查起点的所有前向边,统计out(S)
                    foreach (LGEdge lge in lgv1.Edges)
                    {
                        if (_EdgeGetFlag(lge, lgv2.Id))
                        {
                            sumout++;
                            for (int i = 1; i <= 4; i++)
                            {
                                flagedge[i] &= lge[i];
                            }
                        }
                    }
                    // 检查终点的所有前向边,剔除掉后面的桥点
                    foreach (LGEdge lge in lgv2.Edges)
                    {
                        for (int i = 1; i <= 4; i++)
                        {
                            flagedge[i] &= ~lge[i];
                        }
                    }
                    // 若不能构成两条以上的路径则忽略
                    if (sumin < 2 || sumout < 2)
                    {
                        continue;
                    }
                    // 计算in(T)-out(S)
                    sum = sumin - sumout;
                    // 检查所有能够到达终点的点,统计sum(in(a)-out(a))
                    bool hasbridge = false;
                    foreach (LGVertex lgv3 in vertexs)
                    {
                        if (lgv3.Id == lgv1.Id)
                        {
                            continue;
                        }
                        if (lgv3.Id == lgv2.Id)
                        {
                            continue;
                        }
                        // 该点是连通分量的桥点
                        if (_EdgeGetFlag(flagedge, lgv3.Id))
                        {
                            hasbridge = true;
                            break;
                        }
                        if (_VertexGetFlag(lgv3, lgv2.Id))
                        {
                            sum += lgv3.BackEdges.Count() - lgv3.Edges.Count();
                        }
                    }
                    // 如果不存在桥点,并且不满足等式则混连错误
                    if (!hasbridge && sum != 0)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }