0

I've been trying with limited success to find a more efficient way of discovering all paths along a tree - from multiple roots to multiple leaves. I had it working somewhat using mutable strings and snipping the heads and tails (like a blockchain) but it's buggy and my gut says there has to be a more efficient route (no pun intended).

All relationships between nodes are first defined as parent-child and are held in a dictionary like so:

Parent1 = [child1, child2, child3] Parent2 = [child1, child2, child4]

Combined with a list of all nodes, the following sets can be calculated:

  • Elders (nodes without parents but with children)
  • Younglings (nodes with parents but without children)
  • Everyone else (children / parents, any generation)
  • Free floaters (nodes with neither parents nor children)

My thinking is that the elders should be the starting point (root) and all possible paths to the younglings (leaves) could be calculated using BFS Breath-First-Search, but was under the impression that it only allowed for a single root-node / elder. I need an algorithm that can accept multiple elders and multiple younglings. My code so far:

    NSMutableArray * ma = [NSMutableArray new];
    NSArray * from = [NSArray arrayWithArray:[eldersSet allObjects]];
    NSArray * to = [NSArray arrayWithArray:[youngSet allObjects]];
    for (int n = 0; n < (int)from.count; n++){
        NSString * fromString = from[n];
        for (int k = 0; k < (int)to.count; k++){
            NSString * toString = to[k];
            NSString * toFrom = [NSString stringWithFormat:@"%@ -> %@", fromString, toString];
            NSArray * array = [self searchTreeFrom:fromString childID:toString runArray:[NSArray new]];
            if (array.count == 0){
                continue;
            }
            [ma addObject:@{@"path":toFrom, @"array":array}];
        }
    }

    NSLog(@"ma is %@", ma);


 -(NSArray *)searchTreeFrom:(NSString *)parentID childID:(NSString *)childID runArray:(NSArray *)runArray{
     
     if ([parentID isEqualToString:childID]){
         NSMutableArray * ma = [NSMutableArray array];
         [ma addObjectsFromArray:runArray];
         [ma addObject:childID];
         return (NSArray *)ma;
     }
     
     NSMutableArray * result = [NSMutableArray new];
     if ([localR valueForKey:parentID]){
         NSArray * localArray = localR[parentID];
         for (int n = 0; n < (int)localArray.count; n++){
             result = [NSMutableArray arrayWithArray:[self searchTreeFrom:localArray[n] childID:childID runArray:result]];
             if (result.count > 0){
                 [result insertObject:parentID atIndex:0];
                 return result;
             }
         }
     }
     return result;
 }

It's mostly working, even where routes overlap in an (X) shape, with two elders, one shared child node in the middle and two younglings - it still calculates all the paths correctly. However a (<>) diamond shape leads to the issue that the returned path only goes along the top route (the first child node).

A (<>) diamond has two paths, but the issue is that only one path is requested, from single elder to single youngling, whereas in the former (X) four are requested (two elders, two younglings). I'm wondering if I'm going about this all wrong, as the total number of paths in a (<>) diamond style shape cannot be known in advance, and instead to focus on the recursive function, not returning a value where n == 0, but forcing it through the entire list of children.

Has anyone had any experience with multiple-root -> multiple-leaf path generation? Am I doing something stupid? The goal isn't to find the most efficient path or anything, only to discover all paths. I should mention that the localR variable listed above is the parent=[child,child] dictionary. I'll include output and visual below:

enter image description here

Johnny Rockex
  • 4,136
  • 3
  • 35
  • 55
  • 1
    Related: [Where should I post questions about algorithms: Stack Overflow or Software Engineering?](https://meta.stackexchange.com/questions/165519/where-should-i-post-questions-about-algorithms-stack-overflow-or-software-engin). – Willeke Dec 01 '21 at 10:50
  • 1
    I did not follow the code, however I wonder why you need the complex classification of Elders, Youngsters and such ? A simple Graph representation (say a list of nodes, each with its list of neighbors) should do. Apply on in simple BFS. If you need multiple root-target searches run multiple BFS. – c0der Dec 02 '21 at 09:53
  • @c0der yep, now I feel stupid. Let me try and come back, if it works please post as answer and I'll tick. – Johnny Rockex Dec 06 '21 at 07:01
  • That's what we are here for, to exchange ideas and share opinions and experience (0: Feedback is always welocme – c0der Dec 07 '21 at 08:31

0 Answers0