Reputation: 5929
I am looking for an algorithm which finds a path in a tree along the maximum node values at each level. The following graphic illustrates the problem:
If all nodes on a level would have unique values, this problem would be quite trivial. However, if there are duplicate values on a level, then I (assume that I) need some sort of look ahead. As shown in the example, if there is a draw, the path is chosen which allows for a higher value in the next level. Taken to an "extreme", the path
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 0
would be chosen over the path
1 -> 2 -> 3 -> 4 -> 5 -> 5 -> 99
As soon as there is only one possible path, the algorithm may exit.
Until now, my naive solution has been to find all the possible paths and them compare them level by level, which works for the (small) trees I am dealing with, but I'd like to find a "proper" solution.
I am quite sure that this algorithm has already been implemented, however, I find it hard to find the right search terms for it. Is anyone aware of a solution to this problem?
Upvotes: 2
Views: 71
Reputation: 1718
Here is a possible implementation (not tested)
Assume a tree structure based on Nodes as follow:
internal class Node
{
int Value ;
List<Node> Children ;
}
Main program
// Initialize the best path and call the Seek procedure
List<Node> BestPath = SeekBestSubPath(TheRootNode)
Recursive function
private List<Node> SeekBestSubPath(Node CurrentNode)
{
// identify one or more children with max value
List<Node> BestChildrenNodes = null ;
int Max = int.MinValue ;
for (int i=0;i<CurrentNode.Children.Count;i++)
if (CurrentNode.Children[i].Value > Max)
BestChildrenNodes=new List<Node>() { CurrentNode.Children[i] } ;
else if (CurrentNode.Children[i].Value == Max)
BestChildrenNodes.Add(CurrentNode.Children[i]) ;
// Process BestChildrenNodes
List<Nodes> result = new List<Node>() ;
for (int i=0;i<BestChildrenNodes.Count;i++)
{ // search the best sub path for each child and keep the best one among all
List<Node> ChildBestSubPath = SeekBestSubPath(BestChildrenNodes[i]) ;
if (PathComparator(ChildBestSubPath,MaxPath)>1) result=ChildBestSubPath ;
}
result.Insert(0,CurrentNode) ;
return result ;
}
Compare 2 subpaths
private PathComparator(List<Node> Path1,List<Node> Path2)
{ returns 0:equality, 1:Path1>Path2, -1:Path1<Path2
int result = 0
for (int i=0;i<Math.Min(Path1.Length,Path2.length) && result=0;i++)
result=Math.Sign((Path1[i].Value).CompareTo(Path2[i].Value));
if (result==0) result=Math.Sign(((Path1[i].Count).CompareTo(Path2[i].Count));
return result ;
}
Upvotes: 1
Reputation: 18546
You can start from the root and maintain the list of candidates. Initially the root is the only element in the list. At each iteration you can look at all children of the current candidates and put those that have the maximum value into a new candidates list (that is, each iteration goes one level lower).
Each node is visited at most once, so this solution has a linear time complexity.
Upvotes: 1