Exemplo n.º 1
0
        public void GenShortestPath(int startNo, int endNo)
        {
            GenNodes();
            GenEdgeTable(startNo);

            if (EdgeNode.SearchEdgeNodeNo(edgeNodes, endNo) < 0)
            {
                Console.WriteLine(0);
                return;
            }

            Dijkstra(startNo, endNo);
            PrintShortestPath(startNo, endNo);
        }
Exemplo n.º 2
0
        private void PrintShortestPath(int startNo, int endNo)
        {
            int endEdgeNodeNo = EdgeNode.SearchEdgeNodeNo(edgeNodes, endNo);

            // 未寻到路
            if (preNodeNos[endEdgeNodeNo] == NULL_NODE)
            {
                Console.WriteLine(0);
                return;
            }

            int distance = distances[endEdgeNodeNo];
            // 逆序寻找前趋节点
            var path = new List <int>();

            while (endEdgeNodeNo != INIT_NODE)
            {
                path.Insert(0, endEdgeNodeNo);
                endEdgeNodeNo = preNodeNos[endEdgeNodeNo];
            }

            // 修改矩阵
            foreach (var j in path)
            {
                int x = edgeNodes[j].node.x;
                int y = edgeNodes[j].node.y;
                martrix[y][x] = 2;
            }

            // 打印
            Console.WriteLine(distance);
            for (int i = 0; i < size; i++)
            {
                Console.WriteLine(string.Join(" ", martrix[i]));
            }
        }
Exemplo n.º 3
0
        // 从起点开始用广度优先遍历方式建立相邻节点表,可覆盖从起点开始所有可达的节点,组成一张连接拓扑图
        private void GenEdgeTable(int startNo)
        {
            edgeNodes = new List <EdgeNode>();
            var totalNos = new List <int>();
            var newNos   = new List <int>();

            newNos.Add(startNo);
            while (newNos.Count > 0)
            {
                var newNos2 = new List <int>();
                foreach (var no in newNos)
                {
                    var node = nodes[no];
                    if (node.value == 1)
                    {
                        continue;
                    }
                    if (totalNos.Contains(node.no))
                    {
                        continue;
                    }

                    totalNos.Add(no);
                    var edgeNode = new EdgeNode(node, nodes);
                    edgeNodes.Add(edgeNode);
                    foreach (var newNo in edgeNode.neighborNos)
                    {
                        if (!totalNos.Contains(newNo) && !newNos.Contains(newNo) && !newNos2.Contains(newNo))
                        {
                            newNos2.Add(newNo);
                        }
                    }
                }
                newNos = newNos2;
            }
        }
Exemplo n.º 4
0
        // Dijkstra最短路径算法
        private void Dijkstra(int startNo, int endNo)
        {
            var s = new List <int>();   //已找到最短路径的端点

            //var u = new List<int>();   //未找到最短路径的端点

            for (int i = 0; i < MAX_SIZE * MAX_SIZE; i++)
            {
                distances[i]  = MAX_DISTANCE; // 初始化为最长距离
                preNodeNos[i] = NULL_NODE;    // 初始化为无前趋节点
            }

            //初始化将第一个节点加入s,其余加入待定集合u
            int selectEdgeNodeNo = EdgeNode.SearchEdgeNodeNo(edgeNodes, startNo);

            s.Add(selectEdgeNodeNo);
            distances[selectEdgeNodeNo]  = 0;         //修改距离
            preNodeNos[selectEdgeNodeNo] = INIT_NODE; // 修改前趋节点

            if (edgeNodes.Count <= 1)
            {
                return;
            }

            // 当待定集合U里节点不为空时
            while (s.Count < edgeNodes.Count)
            {
                // 根据选定的新加入节点更新待定集合u中节点的距离和前趋节点
                foreach (var nodeNo in edgeNodes[selectEdgeNodeNo].neighborNos)
                {
                    int edgeNodeNo = EdgeNode.SearchEdgeNodeNo(edgeNodes, nodeNo);
                    if (s.Contains(edgeNodeNo))
                    {
                        continue;
                    }

                    // 如果经过新加入节点的新路比老路距离短
                    if (distances[edgeNodeNo] > distances[selectEdgeNodeNo] + 1)
                    {
                        distances[edgeNodeNo]  = distances[selectEdgeNodeNo] + 1; //修改距离
                        preNodeNos[edgeNodeNo] = selectEdgeNodeNo;                //修改前趋节点
                    }
                }

                // 选定新的S节点,挑选U里路径最短的
                int min   = MAX_DISTANCE;
                int newNo = NULL_NODE;
                for (int i = 0; i < edgeNodes.Count; i++)
                {
                    if (s.Contains(i))
                    {
                        continue;
                    }
                    if (distances[i] < min)
                    {
                        min   = distances[i];
                        newNo = i;
                    }
                }
                selectEdgeNodeNo = newNo;
                s.Add(selectEdgeNodeNo);

                // 如果选定节点是结束点,则提前结束算法
                if (edgeNodes[selectEdgeNodeNo].node.no == endNo)
                {
                    return;
                }
            }
        }