Improved Algorithm (print all graph paths) and programlua
In Program in Lua version 2, section 11.7 describes how to use lua to write the "Graph" data structure,
However, the graph algorithm provided in the book can only print the correct path found in the first article, so I figured it out by myself.
How can I use lua to write a graph algorithm to print all possible paths? I think it alone.
For a long time, I did not refer to any materials. I completely solved it by "mental violence" and finally thought about it,
I don't know what algorithm this is. It's amazing to use what I think is called the concept of "degradation ".
So I will share this algorithm.
(I always think I have seen the word "degradation" in which book, but I don't know what is actually "degradation ",
However, in my mind, "degradation" is just a concept. Here, I think this concept seems to have
A proper taste, I will call it "degradation. In addition, this algorithm may also be implemented.
But I don't actually know what this algorithm is. I only know the idea of this algorithm-what I call
"Degradation" (because I have learned very little, at least I have not studied graph theory, so do not spray it ).
You have met the "design" algorithm, or you can tell me what it is (at least I don't think I can come up with it ).
Something else will not think of, I should have not reached that realm = _ = ))
Body:
The first is a. lua file that saves the data in the figure. Its name is graph. lua,
The relative path is./lua/graph. lua.
The content is as follows:
a b b cb f c dc fd ef gg hf ii jj cj ki lc k k l
As follows:
(This algorithm is only applicable to unidirectional graphs)
Then there is the "Graph" data structure and my "design" algorithm:
The relative path is./lua/11.7.lua.
(The comments are detailed and are written in the Code. If you don't understand them, ask me)
Graph ={} -- generate the function Graph of the Graph node. newNode (graph, name) if not graph [name] thengraph [name] = {name = name, adj ={}}-- Create a New graph node endreturn Graph [name] end -- generate graph function. gen (s) local graph ={} for line in io. lines (s) do -- match start point, leading to node local namefrom, nameto = string. match (line, "(% S +) % s (% S +)") local from = Graph. newNode (graph, namefrom) -- generate the starting node local to = Graph. newNode (graph, nameto) -- generate the path to the node local path = from. adj -- Obtain the path table path [# path + 1] = to -- connect to the Graph Node path endreturn graphendfunction Graph. findpath (curr, to, path, visited) -- parameter: current node, destination node, set of storage paths, set of accessed nodes (degraded) -- about degradation: here, the concept of degradation is self-proposed, which means to cancel the record of a node on a path-forward backtracking, so that another recursive search branch can find this path. At the same time, -- stores records for nodes recorded by the pressed stack function and nodes in the inaccessible path so that recursive functions -- directly return path = path or {} -- path as a table to record all stored paths visited = visited or {} -- visited is the table that stores the record node if visited [curr] then -- return nil end visited [curr] = true directly to the record Node path ["name"] = curr ["name"] -- Record path if curr = to then -- locate the end, construct a path and return visited [curr] = nil -- degradation (cancel the end record) return path end local pfor I, from in ipairs (curr. adj) do path [I] = {father = path} -- save a field that can locate the parent node -- recursive search path local rightPath = Graph. findpath (from, to, path [I], visited) if not rightPath then path [I] = nil end -- not found, cancel a sub-tablep = rightPath or p -- Record the return of the last path when a path exists, otherwise, nilendif p then visited [curr] = nil -- degrades the return p ["father"] node of the path -- returns the father of the path, that is, the current node end path = nil -- not found, delete the node end -- print all Graph paths function Graph. printPath (path, visited) -- path node set, accessed Node Set (degraded) path = path or {} visited = visited or {} if path then visited [# visited + 1] = path -- saves the accessed path io in array form. write (path. name, "") -- print the current node name and the space character endlocal maxn = table. maxn (path) -- Take the largest number in the feasible branch if maxn = 0 then -- visited [# visited] = nil -- degraded when the branch (that is, the end) does not exist, cancels recording of the node io. write ("\ n") -- this path has been completely output, line feed return end -- end, return local count = 0 -- count the number of branches for I = 1, maxn do if path [I] then -- the branch of this number exists count = count + 1 -- increasing the number of branches if count> 1 then -- except the first branch, for I, v in ipairs (visited) do -- print io on the recorded root node. write (v. name, "") endendGraph. printPath (path [I], visited) -- then Recursively search the next branch endendendvisited [# visited] = nil -- The Branch has been searched, and this branch is no longer searched. The degraded endlocal graph = Graph. gen (". /lua/graph. lua ") -- generate Graph local path = Graph. findpath (graph ["a"], graph ["l"]) -- find the Graph path. printPath (path) -- output graph path
The output result is as follows: