예제 #1
0
 public LGEdge(LCNode _info, LGVertex _s, LGVertex _d)
 {
     this.id          = 0;
     this.PLCInfo     = _info;
     this.Source      = _s;
     this.Destination = _d;
 }
예제 #2
0
        /// <summary>
        /// 将制定的点设为终点
        /// </summary>
        public void SetTerminate(int id)
        {
            if (id <= 0 || id > vertexs.Count)
            {
                throw new ArgumentOutOfRangeException();
            }
            LGVertex lgv = vertexs[id - 1];

            if (terminates.Contains(lgv))
            {
                return;
            }
            lgv.IsTerminate = true;
            terminates.Add(lgv);
        }
예제 #3
0
        /// <summary>
        /// 将制定的点设为起点
        /// </summary>
        public void SetStart(int id)
        {
            if (id <= 0 || id > vertexs.Count)
            {
                throw new ArgumentOutOfRangeException();
            }
            LGVertex lgv = vertexs[id - 1];

            if (starts.Contains(lgv))
            {
                return;
            }
            lgv.IsStart = true;
            starts.Add(lgv);
        }
예제 #4
0
        } /// <summary>

        /// 得到点标记中点标号的对应位
        /// </summary>
        /// <param name="lge">给定的边</param>
        /// <param name="id">给定的点标号</param>
        /// <returns>对应的位的值(0或1,1返回true)</returns>
        private bool _VertexGetFlag(LGVertex lgv, int id)
        {
            if (id <= 32)
            {
                return(((lgv[1] >> (id - 1)) & 1) != 0);
            }
            if (id <= 64)
            {
                return(((lgv[2] >> (id - 33)) & 1) != 0);
            }
            if (id <= 96)
            {
                return(((lgv[3] >> (id - 65)) & 1) != 0);
            }
            if (id <= 128)
            {
                return(((lgv[4] >> (id - 97)) & 1) != 0);
            }
            throw new IndexOutOfRangeException();
        }
예제 #5
0
 /// <summary>
 /// 从当前边开始前向查询,得到到达所有节点的通行情况,保存在标记中
 /// </summary>
 /// <param name="lgv">当前要查询的边</param>
 private void _EdgeSearch(LGVertex lgv)
 {
     foreach (LGEdge lge in lgv.Edges)
     {
         // 指向的点未被访问,标记为空
         if (_VertexEmptyFlag(lge.Destination))
         {
             _EdgeSearch(lge.Destination);
         }
         // 将边的标记设为指向点的标记
         lge[1] = lge.Destination[1];
         lge[2] = lge.Destination[2];
         lge[3] = lge.Destination[3];
         lge[4] = lge.Destination[4];
         // 能够指向该点,添加通行信息
         _EdgeSetFlag(lge, lge.Destination.Id);
         // 该点统计所有前向边
         lgv[1] |= lge[1];
         lgv[2] |= lge[2];
         lgv[3] |= lge[3];
         lgv[4] |= lge[4];
     }
 }
예제 #6
0
 /// <summary>
 /// 判断这个点的所有标记是否为空
 /// </summary>
 /// <param name="lgv">给定的点</param>
 /// <returns>是否为空,为空返回true</returns>
 private bool _VertexEmptyFlag(LGVertex lgv)
 {
     return(lgv[1] == 0 && lgv[2] == 0 && lgv[3] == 0 && lgv[4] == 0);
 }
예제 #7
0
        /// <summary>
        /// 检查是否短路,在逻辑图中体现为单向环
        /// </summary>
        public bool checkShortCircuit()
        {
            // 做一次拓扑排序来检查
            // 初始化每个节点的访问标记和后向计数
            foreach (LGVertex lgv in vertexs)
            {
                lgv[4] = 0;
            }
            foreach (LGEdge lge in edges)
            {
                lge.Destination[4]++;
            }
            // 开始拓扑排序,将计数为0的点加入队列中
            Queue <LGVertex> queue = new Queue <LGVertex>();

            foreach (LGVertex lgv in vertexs)
            {
                if (lgv[4] == 0)
                {
                    queue.Enqueue(lgv);
                }
            }
            // 记录已经进行拓扑排序的节点数量
            int solveCount = 0;

            while (queue.Count > 0)
            {
                solveCount++;
                LGVertex lgv = queue.Dequeue();
                foreach (LGEdge lge in lgv.Edges)
                {
                    if ((--lge.Destination[4]) == 0)
                    {
                        queue.Enqueue(lge.Destination);
                    }
                }
            }
            // 若存在节点未被排序,则在环中
            if (solveCount < vertexs.Count)
            {
                return(true);
            }
            // 还存在一种短路情况,分支后面出现线路指令(INV,MEP,MEF)时

            /*
             * foreach (LGVertex lgv in vertexs)
             * {
             *  if (lgv.Edges.Count() > 1)
             *  {
             *      foreach (LGEdge lge in lgv.Edges)
             *      {
             *          switch (lge.PLCInfo.Type)
             *          {
             *              case "INV": case "MEP": case "MEF":
             *                  return true;
             *          }
             *      }
             *  }
             * }
             */
            return(false);
        }
예제 #8
0
        /// <summary>
        /// 生成该节点对应的表达式
        /// </summary>
        public void GenExpr()
        {
            if (!this.Expr.Equals("null"))
            {
                return;
            }
            // 若为起点则表达式为1
            if (this.IsStart)
            {
                this.Expr = "1"; return;
            }
            // 生成所有子项表达式
            List <String> subexprs = new List <String>();

            foreach (LGEdge lge in BackEdges)
            {
                LGVertex pv = lge.Source;
                // 若前向边指向的节点未访问(表达式为"null"),则生成表达式
                if (pv.Expr.Equals("null"))
                {
                    pv.GenExpr();
                }
                string uexpr = lge.PLCInfo.Expr;
                // 若与运算两边的表达式其中为“1”,则忽略这个“1”
                if (uexpr.Equals("1"))
                {
                    lge.Expr = pv.Expr;
                }
                else if (pv.Expr.Equals("1"))
                {
                    lge.Expr = uexpr;
                }
                else
                {
                    lge.Expr = String.Format("{0:s}&&{1:s}", pv.Expr, uexpr);
                }
            }
            // 如果有多个表达式需要或运算
            if (BackEdges.Count > 1)
            {
                // 按照ASCII码来排序,为后续合并工作做准备
                Comparison <LGEdge> sortByExpr = delegate(LGEdge v1, LGEdge v2)
                {
                    return(v1.Expr.CompareTo(v2.Expr));
                };
                BackEdges.Sort(sortByExpr);
                foreach (LGEdge lge in BackEdges)
                {
                    subexprs.Add(lge.Expr);
                }
                // 表达式合并
                bool hasor = false;
                Expr = ExprHelper.Merge(subexprs, 0, subexprs.Count - 1, ref hasor);
                if (hasor)
                {
                    Expr = "(" + Expr + ")";
                }
            }
            // 如果存在前向边
            else if (BackEdges.Count > 0)
            {
                this.Expr = BackEdges[0].Expr;
            }
            else
            {
                this.Expr = "1";
            }
        }