Fractal to Fractal Tail

I am writing a detour to find the longest way on the road. The magic part of this code is the segment. Next refers to LINQ, to which specific logic is applied, for example, without revising nodes already visited. Therefore, do not indicate flaws in travsel, as this is beyond the scope.

What I'm trying to do is reduce the number of calls on the stack, because sometimes the path can be 5000 long. I know that I have to make a recursive recursive tail call recursive.

public static IEnumerable<Segment> FindLongestPath(Segment segment)
{
    var rv = new List<Segment> {segment};
    var longestPathLength = 0;
    var longestNextPaths = Enumerable.Empty<Segment>();

    foreach (var n in segment.Next)
    {
        var paths = FindLongestPath(n);
        var length = paths.Sum(p => p.LengthMeters);
        if (length > longestPathLength)
        {
            longestPathLength = length;
            longestNextPaths = paths;
        }
    }

    rv.AddRange(longestNextPaths);

    return rv;
}

How can I make this tail recursive call recursive? I know that I probably should support IEnumerable<Segment>when I travel, but I just don't wrap it around.

+4
2

spender - : .

spender, , , , . (CPS - , .)

, CPS- , (1) (2) ML, #. :

  • children node .
  • cost node.
  • , .

-, CPS ML:

let rec maximum_path_cost node =
  let rec aux nodes max =
    match nodes with
    | [] -> max
    | head :: tail -> 
       let c = maximum_path_cost head in
       let new_max = if c > max then c else max in
       aux tail new_max
  in
  (cost node) + (aux (children node) 0)

: , . : " ?" , ; , ( ), .

, aux , maximum_path_cost .

max_path_cost - - , int - , . aux .

CPS.

let rec maximum_path_cost node continuation =
  let rec aux nodes max aux_continuation =
    match nodes with
    | [] -> aux_continuation max
    | head :: tail ->
       let mpcc c = 
         let new_max = if c > max then c else max in
         aux tail new_max aux_continuation
       in
       maximum_path_cost head mpcc
  in
  let ac result =
    continuation ((cost node) + result) 
  in
    aux (children node) 0 ac

, , , . , , aux max, ; aux? , _path_cost. ? .

# # .:)

+4

, , . , .

, , . " ", . Queue<T>/Stack<T> ( , ), , , , , .

:

public static IEnumerable<Segment> FindLongestPath(Segment segment)
{
    var queue = new Queue<Segment>(); //or a Stack<Segment> with Push and Pop
    queue.Enqueue(segment);

    while(queue.Any())
    {
        var currentSegment = queue.Dequeue();
        foreach(var seg in currentSegment.Next)
        {
            queue.Enqueue(seg);
        }
        //process currentSegment
    }
}
+3

Source: https://habr.com/ru/post/1678881/


All Articles