简体   繁体   English

低内存最短路径算法

[英]Low Memory Shortest Path Algorithm

I have a global unique path table which can be thought of as a directed un-weighted graph. 我有一个全局唯一路径表,可以将其视为有向非加权图。 Each node represents either a piece of physical hardware which is being controlled, or a unique location in the system. 每个节点代表被控制的物理硬件,或者代表系统中的唯一位置。 The table contains the following for each node: 该表包含每个节点的以下内容:

  1. A unique path ID (int) 唯一路径ID(int)
  2. Type of component (char - 'A' or 'L') 组件类型(字符-'A'或'L')
  3. String which contains a comma separated list of path ID's which that node is connected to (char[]) 字符串,其中包含该节点连接到的路径ID的逗号分隔列表(char [])

I need to create a function which given a starting and ending node, finds the shortest path between the two nodes. 我需要创建一个给定起点和终点的函数,找到两个节点之间的最短路径。 Normally this is a pretty simple problem, but here is the issue I am having. 通常这是一个非常简单的问题,但这是我遇到的问题。 I have a very limited amount of memory/resources, so I cannot use any dynamic memory allocation (ie a queue/linked list). 我的内存/资源数量非常有限,因此无法使用任何动态内存分配(即队列/链接列表)。 It would also be nice if it wasn't recursive (but it wouldn't be too big of an issue if it was as the table/graph itself if really small. Currently it has 26 nodes, 8 of which will never be hit. At worst case there would be about 40 nodes total). 如果它不是递归的,那也很好(但是,如果表/图形本身很小,那么它就不会有太大的问题。目前它有26个节点,其中8个永远不会被命中。在最坏的情况下,总共大约有40个节点。

I started putting something together, but it doesn't always find the shortest path. 我开始将一些东西放在一起,但它并不总能找到最短的路径。 The pseudo code is below: 伪代码如下:

bool shortestPath(int start, int end)
  if start == end
    if pathTable[start].nodeType == 'A'
      Turn on part
    end if 
    return true
  else
    mark the current node
    bool val
    for each node in connectedNodes
      if node is not marked
        val = shortestPath(node.PathID, end)
      end if 
    end for

    if val == true
      if pathTable[start].nodeType == 'A'
        turn on part
      end if 
      return true 
    end if
  end if 

  return false

end function

Anyone have any ideas how to either fix this code, or know something else that I could use to make it work? 任何人都有任何想法如何解决此代码,或者知道我可以用来使其正常工作的其他知识吗?

----------------- EDIT ----------------- -----------------编辑-----------------

Taking Aasmund's advice, I looked into implementing a Breadth First Search. 根据Aasmund的建议,我研究了实施广度优先搜索。 Below I have some c# code which I quickly threw together using some pseudo code I found online. 下面有一些C#代码,我使用网上找到的一些伪代码将它们快速汇总在一起。

pseudo code found online: 在线找到伪代码:

Input: A graph G and a root v of G 输入:图G和G的根v

procedure BFS(G,v):
       create a queue Q
       enqueue v onto Q
       mark v
       while Q is not empty:
           t ← Q.dequeue()
           if t is what we are looking for:
               return t
           for all edges e in G.adjacentEdges(t) do
              u ← G.adjacentVertex(t,e)
              if u is not marked:
                   mark u
                   enqueue u onto Q
      return none

C# code which I wrote using this code: 我使用以下代码编写的C#代码:

        public static bool newCheckPath(int source, int dest)
        {
            Queue<PathRecord> Q = new Queue<PathRecord>();
            Q.Enqueue(pathTable[source]);
            pathTable[source].markVisited();

            while (Q.Count != 0)
            {
                PathRecord t = Q.Dequeue();
                if (t.pathID == pathTable[dest].pathID)
                {
                    return true;
                }
                else
                {
                    string connectedPaths = pathTable[t.pathID].connectedPathID;
                    for (int x = 0; x < connectedPaths.Length && connectedPaths != "00"; x = x + 3)
                    {
                        int nextNode = Convert.ToInt32(connectedPaths.Substring(x, 2));

                        PathRecord u = pathTable[nextNode];
                        if (!u.wasVisited())
                        {
                            u.markVisited();
                            Q.Enqueue(u);
                        }

                    }
                }
            }

            return false;
        }

This code runs just fine, however, it only tells me if a path exists. 这段代码运行得很好,但是,它只会告诉我是否存在路径。 That doesn't really work for me. 那对我真的不起作用。 Ideally what I would like to do is in the block "if (t.pathID == pathTable[dest].pathID)" I would like to have either a list or a way to see what nodes I had to pass through to get from the source and destination, such that I can process those nodes there, rather than returning a list to process elsewhere. 理想情况下,我想在块“ if(t.pathID == pathTable [dest] .pathID)”中,我想要一个列表或一种方法来查看必须经过哪些节点才能从中获得源和目标,以便我可以在那里处理那些节点,而不是返回列表以在其他地方处理。 Any ideas on how i could make that change? 关于如何进行更改的任何想法?

The most effective solution, if you're willing to use static memory allocation (or automatic , as I seem to recall that the C++ term is), is to declare a fixed-size int array (of size 41, if you're absolutely certain that the number of nodes will never exceed 40). 如果您愿意使用静态内存分配(或自动的 ,我似乎还记得C ++术语是这样的话),那么最有效的解决方案是声明一个固定大小的int数组(大小为41,如果绝对要这样做)。确定节点数永远不会超过40)。 By using two indices to indicate the start and end of the queue, you can use this array as a ring buffer, which can act as the queue in a breadth-first search. 通过使用两个索引来指示队列的开始和结束,可以将此数组用作环形缓冲区,该缓冲区可以在广度优先搜索中用作队列。

Alternatively: Since the number of nodes is so small, Bellman-Ford may be fast enough. 或者:由于节点数很少,因此Bellman-Ford可能足够快。 The algorithm is simple to implement, does not use recursion, and the required extra memory is only a distance ( int , or even byte in your case) and a predecessor id ( int ) per node. 该算法易于实现,不使用递归,所需的额外内存仅为每个节点一个距离(在您的情况下为int ,甚至是byte )和每个节点的前身id( int )。 The running time is O(VE) , alternatively O(V^3) , where V is the number of nodes and E is the number of edges. 运行时间是O(VE) ,或者是O(V^3) ,其中V是节点数, E是边数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM