Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Concurrent segment detection #135

Closed
yakra opened this issue Nov 21, 2018 · 17 comments · Fixed by #136
Closed

Concurrent segment detection #135

yakra opened this issue Nov 21, 2018 · 17 comments · Fixed by #136

Comments

@yakra
Copy link
Contributor

yakra commented Nov 21, 2018

Some background info: Re: PA: US 19 Truck (Pittsburgh)
http://forum.travelmapping.net/index.php?topic=316.msg12112#msg12112

TL;DR:

Search for Wait. Did we mean to do that?, in the 9th response below.

if s.concurrent is None:
    s.concurrent = []
    other.concurrent = s.concurrent
    s.concurrent.append(s)
    s.concurrent.append(other)
    concurrencyfile.write("New concurrency [" + str(s) + "][" + str(other) + "] (" + str(len(s.concurrent)) + ")\n")
else:
    other.concurrent = s.concurrent # ADD THIS HERE!
    if other not in s.concurrent:
        s.concurrent.append(other)
    # ...

may be what we need. It should link up segments beyond just the 2nd one with the 1st segment's concurrency list, and prevent erasing the 1st segment's list followed by needlessly re-detecting its concurrencies.

@yakra
Copy link
Contributor Author

yakra commented Nov 21, 2018

for h in highway_systems:
# h = usai
    for r in h.route_list:
    # r = pa.i376
        for s in r.segment_list:
        # s = [69A to 69B via pa.i376]
            if s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:
            # True
                for w1 in s.waypoint1.colocated:
                # w1 = pa.us019@I-376(69A)
                    if w1.route is not r:
                    # w1.route = pa.us019; True
                    .-> for w2 in s.waypoint2.colocated:
                    |   # w2 = pa.us019@I-376(69B)
                    |       if w1.route is w2.route:
                    |       # True
                    |           other = w1.route.find_segment_by_waypoints(w1,w2)
                    |           if other is not None:
                    |           # other = [I-376(69A) to I-376(69B) via pa.us019]
                    |               if s.concurrent is None:
                    |               # First pass; True
                    |                   s.concurrent = []
                    |                   # empty list
                    |                   other.concurrent = s.concurrent
                    |                   # 2 empty lists, quantum entangled
                    |                   s.concurrent.append(s)
                    |                   # I-376 & US19 get I-376
                    |                   s.concurrent.append(other)
                    |                   # I-376 & US19 get US19
                    |__________________ concurrencyfile.write("New concurrency [" + str(s) + "][" + str(other) + "] (" + str(len(s.concurrent)) + ")\n")
                                    else:
                                        if other not in s.concurrent:
                                        #
                                            s.concurrent.append(other)
                                            #
                                            #concurrencyfile.write("Added concurrency [" + str(s) + "]-[" + str(other) + "] ("+ str(len(s.concurrent)) + ")\n")
                                            concurrencyfile.write("Extended concurrency ")
                                            for x in s.concurrent:
                                                concurrencyfile.write("[" + str(x) + "]")
                                            concurrencyfile.write(" (" + str(len(s.concurrent)) + ")\n")
I-376 US19 US22 US30 TrkS TrkN
I-376 I-376 None None None None
US19 US19

@yakra
Copy link
Contributor Author

yakra commented Nov 21, 2018

for h in highway_systems:
# h = usai
    for r in h.route_list:
    # r = pa.i376
        for s in r.segment_list:
        # s = [69A to 69B via pa.i376]
            if s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:
            # True
            .-> for w1 in s.waypoint1.colocated:
            |   # w1 = pa.us019@I-376(69A)
            |       if w1.route is not r:
            |       # w1.route = pa.us019; True
            |           for w2 in s.waypoint2.colocated:
            |           # w2 = pa.us022@I-376(69B), pa.us030@I-376(69B), pa.us019trkpit@I-376(69B)_S, pa.us019trkpit@I-376(69B)_N
            |               if w1.route is w2.route:
            |______________ # False for all remaining
                                other = w1.route.find_segment_by_waypoints(w1,w2)
                                if other is not None:
                                #
                                    if s.concurrent is None:
                                    #
                                        s.concurrent = []
                                        #
                                        other.concurrent = s.concurrent
                                        #
                                        s.concurrent.append(s)
                                        #
                                        s.concurrent.append(other)
                                        #
                                        concurrencyfile.write("New concurrency [" + str(s) + "][" + str(other) + "] (" + str(len(s.concurrent)) + ")\n")
                                    else:
                                        if other not in s.concurrent:
                                        #
                                            s.concurrent.append(other)
                                            #
                                            #concurrencyfile.write("Added concurrency [" + str(s) + "]-[" + str(other) + "] ("+ str(len(s.concurrent)) + ")\n")
                                            concurrencyfile.write("Extended concurrency ")
                                            for x in s.concurrent:
                                                concurrencyfile.write("[" + str(x) + "]")
                                            concurrencyfile.write(" (" + str(len(s.concurrent)) + ")\n")
I-376 US19 US22 US30 TrkS TrkN
I-376 I-376 None None None None
US19 US19

@yakra
Copy link
Contributor Author

yakra commented Nov 21, 2018

for h in highway_systems:
# h = usai
    for r in h.route_list:
    # r = pa.i376
        for s in r.segment_list:
        # s = [69A to 69B via pa.i376]
            if s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:
            # True
            .-> for w1 in s.waypoint1.colocated:
            |   # w1 = pa.us022@I-376(69A)
            |       if w1.route is not r:
            |       # w1.route = pa.us022; True
            |       .-> for w2 in s.waypoint2.colocated:
            |       |   # w2 = pa.us022@I-376(69B)
            |       |       if w1.route is w2.route:
            |_______*       # True for US22; false for all remaining
                    |           other = w1.route.find_segment_by_waypoints(w1,w2)
                    |           if other is not None:
                    |           # other = [I-376(69A) to I-376(69B) via pa.us022]
                    |               if s.concurrent is None:
                    |               # False; received items in earlier pass
                    |                   s.concurrent = []
                    |                   #
                    |                   other.concurrent = s.concurrent
                    |                   #
                    |                   s.concurrent.append(s)
                    |                   #
                    |                   s.concurrent.append(other)
                    |                   #
                    |                   concurrencyfile.write("New concurrency [" + str(s) + "][" + str(other) + "] (" + str(len(s.concurrent)) + ")\n")
                    |               else:
                    |                   if other not in s.concurrent:
                    |                   # True
                    |                       s.concurrent.append(other)
                    |                       # I-376 & US19 get US22
                    |                       #concurrencyfile.write("Added concurrency [" + str(s) + "]-[" + str(other) + "] ("+ str(len(s.concurrent)) + ")\n")
                    |                       concurrencyfile.write("Extended concurrency ")
                    |                       for x in s.concurrent:
                    |                           concurrencyfile.write("[" + str(x) + "]")
                    |______________________ concurrencyfile.write(" (" + str(len(s.concurrent)) + ")\n")
I-376 US19 US22 US30 TrkS TrkN
I-376 I-376 None None None None
US19 US19
US22 US22

@yakra
Copy link
Contributor Author

yakra commented Nov 21, 2018

for h in highway_systems:
# h = usai
    for r in h.route_list:
    # r = pa.i376
        for s in r.segment_list:
        # s = [69A to 69B via pa.i376]
            if s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:
            # True
            .-> for w1 in s.waypoint1.colocated:
            |   # w1 = pa.us030@I-376(69A)
            |       if w1.route is not r:
            |       # w1.route = pa.us030; True
            |       .-> for w2 in s.waypoint2.colocated:
            |       |   # w2 = pa.us030@I-376(69B)
            |       |       if w1.route is w2.route:
            |_______*       # True for US30; false for all remaining
                    |           other = w1.route.find_segment_by_waypoints(w1,w2)
                    |           if other is not None:
                    |           # other = [I-376(69A) to I-376(69B) via pa.us030]
                    |               if s.concurrent is None:
                    |               # False; received items in earlier pass
                    |                   s.concurrent = []
                    |                   #
                    |                   other.concurrent = s.concurrent
                    |                   #
                    |                   s.concurrent.append(s)
                    |                   #
                    |                   s.concurrent.append(other)
                    |                   #
                    |                   concurrencyfile.write("New concurrency [" + str(s) + "][" + str(other) + "] (" + str(len(s.concurrent)) + ")\n")
                    |               else:
                    |                   if other not in s.concurrent:
                    |                   # True
                    |                       s.concurrent.append(other)
                    |                       # I-376 & US19 get US30
                    |                       #concurrencyfile.write("Added concurrency [" + str(s) + "]-[" + str(other) + "] ("+ str(len(s.concurrent)) + ")\n")
                    |                       concurrencyfile.write("Extended concurrency ")
                    |                       for x in s.concurrent:
                    |                           concurrencyfile.write("[" + str(x) + "]")
                    |______________________ concurrencyfile.write(" (" + str(len(s.concurrent)) + ")\n")
I-376 US19 US22 US30 TrkS TrkN
I-376 I-376 None None None None
US19 US19
US22 US22
US30 US30

@yakra
Copy link
Contributor Author

yakra commented Nov 21, 2018

for h in highway_systems:
# h = usai
    for r in h.route_list:
    # r = pa.i376
        for s in r.segment_list:
        # s = [69A to 69B via pa.i376]
            if s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:
            # True
                for w1 in s.waypoint1.colocated:
                # w1 = pa.us019trk@I-376(69A), and that's the last colocated point
                    if w1.route is not r:
                    # w1.route = pa.us019trk; True
                    .-> for w2 in s.waypoint2.colocated:
                    |   # w2 = yadda, yadda, pa.us019trk@I-376(69B)_S ...
                    |       if w1.route is w2.route:
                    |       # True
                    |           other = w1.route.find_segment_by_waypoints(w1,w2)
                    |           if other is not None:
                    |           # other = [I-376(69B)_S to I-376(69A) via pa.us019trkpit]
                    |               if s.concurrent is None:
                    |               # False; received items in earlier pass
                    |                   s.concurrent = []
                    |                   #
                    |                   other.concurrent = s.concurrent
                    |                   #
                    |                   s.concurrent.append(s)
                    |                   #
                    |                   s.concurrent.append(other)
                    |                   #
                    |                   concurrencyfile.write("New concurrency [" + str(s) + "][" + str(other) + "] (" + str(len(s.concurrent)) + ")\n")
                    |               else:
                    |                   if other not in s.concurrent:
                    |                   # True
                    |                       s.concurrent.append(other)
                    |                       # I-376 & US19 get [I-376(69B)_S to I-376(69A) via pa.us019trkpit]
                    |                       #concurrencyfile.write("Added concurrency [" + str(s) + "]-[" + str(other) + "] ("+ str(len(s.concurrent)) + ")\n")
                    |                       concurrencyfile.write("Extended concurrency ")
                    |                       for x in s.concurrent:
                    |                           concurrencyfile.write("[" + str(x) + "]")
                    |______________________ concurrencyfile.write(" (" + str(len(s.concurrent)) + ")\n")
I-376 US19 US22 US30 TrkS TrkN
I-376 I-376 None None None None
US19 US19
US22 US22
US30 US30
TrkS TrkS

@yakra
Copy link
Contributor Author

yakra commented Nov 21, 2018

for h in highway_systems:
# h = usai
^   for r in h.route_list:
|   # r = pa.i376, last Interstate we care about at this segment
|   .-> for s in r.segment_list:
|___*   # s = [69A to 69B via pa.i376], and then other I-376 segments we're not concerned with
    |       if s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:
    |       # True
    |           for w1 in s.waypoint1.colocated:
    |           # w1 = pa.us019trk@I-376(69A), and that's the last colocated point
    |               if w1.route is not r:
    |               # w1.route = pa.us019trk; True
    |                   for w2 in s.waypoint2.colocated:
    |                   # w2 = pa.us019trk@I-376(69B)_N, and that's the last colocated point
    |                       if w1.route is w2.route:
    |                       # True
    |                           other = w1.route.find_segment_by_waypoints(w1,w2)
    |                           if other is not None:
    |                           # other = [I-376(69A) to I-376(69B)_N via pa.us019trkpit]
    |                               if s.concurrent is None:
    |                               # False; received items in earlier pass
    |                                   s.concurrent = []
    |                                   #
    |                                   other.concurrent = s.concurrent
    |                                   #
    |                                   s.concurrent.append(s)
    |                                   #
    |                                   s.concurrent.append(other)
    |                                   #
    |                                   concurrencyfile.write("New concurrency [" + str(s) + "][" + str(other) + "] (" + str(len(s.concurrent)) + ")\n")
    |                               else:
    |                                   if other not in s.concurrent:
    |                                   # True
    |                                       s.concurrent.append(other)
    |                                       # I-376 & US19 get [I-376(69A) to I-376(69B)_N via pa.us019trkpit]
    |                                       #concurrencyfile.write("Added concurrency [" + str(s) + "]-[" + str(other) + "] ("+ str(len(s.concurrent)) + ")\n")
    |                                       concurrencyfile.write("Extended concurrency ")
    |                                       for x in s.concurrent:
    |                                           concurrencyfile.write("[" + str(x) + "]")
    |______________________________________ concurrencyfile.write(" (" + str(len(s.concurrent)) + ")\n")
I-376 US19 US22 US30 TrkS TrkN
I-376 I-376 None None None None
US19 US19
US22 US22
US30 US30
TrkS TrkS
TrkN TrkN

@yakra
Copy link
Contributor Author

yakra commented Nov 21, 2018

for h in highway_systems:
# h = usaus
.-> for r in h.route_list:
|   # r = pa.us019
|   .-> for s in r.segment_list:
|___*   # s = [I-376(69A) to I-376(69B) via pa.us019] etc.
    |       if s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:
    |       # True
    |           for w1 in s.waypoint1.colocated:
    |           # w1 = pa.i376@69A, <pa.us019@I-376(69A)>, pa.us022@I-376(69A), pa.us030@I-376(69A), pa.us019trkpit@I-376(69A)
    |               if w1.route is not r:
    |               # True for all but pa.us019@I-376(69A)
    |                   for w2 in s.waypoint2.colocated:
    |                   # w2 = pa.i376@69B, pa.us019@I-376(69B), pa.us022@I-376(69B), pa.us030@I-376(69B), pa.us019trkpit@I-376(69B)_S, pa.us019trkpit@I-376(69B)_N
    |                       if w1.route is w2.route:
    |                       # True for I-376, US19, 22, 30, and True twice for US19Trk because it has two "w2"s
    |                           other = w1.route.find_segment_by_waypoints(w1,w2)
    |                           if other is not None:
    |                           # other is not None:
    |                               if s.concurrent is None:
    |                               # False; received items in earlier pass
    |                                   s.concurrent = []
    |                                   #
    |                                   other.concurrent = s.concurrent
    |                                   #
    |                                   s.concurrent.append(s)
    |                                   #
    |                                   s.concurrent.append(other)
    |                                   #
    |                                   concurrencyfile.write("New concurrency [" + str(s) + "][" + str(other) + "] (" + str(len(s.concurrent)) + ")\n")
    |                               else:
    |                                   if other not in s.concurrent:
    |__________________________________ # False: s.concurrent was fully populated in previous pass; nothing else happens
                                            s.concurrent.append(other)
                                            #
                                            #concurrencyfile.write("Added concurrency [" + str(s) + "]-[" + str(other) + "] ("+ str(len(s.concurrent)) + ")\n")
                                            concurrencyfile.write("Extended concurrency ")
                                            for x in s.concurrent:
                                                concurrencyfile.write("[" + str(x) + "]")
                                            concurrencyfile.write(" (" + str(len(s.concurrent)) + ")\n")
I-376 US19 US22 US30 TrkS TrkN
I-376 I-376 None None None None
US19 US19
US22 US22
US30 US30
TrkS TrkS
TrkN TrkN

@yakra
Copy link
Contributor Author

yakra commented Nov 21, 2018

for h in highway_systems:
# h = usaus
    for r in h.route_list:
    # r = pa.us022
        for s in r.segment_list:
        # s = [I-376(69A) to I-376(69B) via pa.us022]
            if s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:
            # True
                for w1 in s.waypoint1.colocated:
                # w1 = pa.us022@I-376(69A)
                    if w1.route is not r:
                    # w1.route = pa.us022; True
                        for w2 in s.waypoint2.colocated:
                        # w2 = pa.i376@69B
                            if w1.route is w2.route:
                            # True
                                other = w1.route.find_segment_by_waypoints(w1,w2)
                                if other is not None:
                                # other = [69A to 69B via pa.i376]
                                    if s.concurrent is None:
                                    # First pass for US22; True
                                        s.concurrent = []
_______________________________________ # empty list _______________________________________
                                        other.concurrent = s.concurrent
                                        #
                                        s.concurrent.append(s)
                                        #
                                        s.concurrent.append(other)
                                        #
                                        concurrencyfile.write("New concurrency [" + str(s) + "][" + str(other) + "] (" + str(len(s.concurrent)) + ")\n")
                                    else:
                                        if other not in s.concurrent:
                                        #
                                            s.concurrent.append(other)
                                            #
                                            #concurrencyfile.write("Added concurrency [" + str(s) + "]-[" + str(other) + "] ("+ str(len(s.concurrent)) + ")\n")
                                            concurrencyfile.write("Extended concurrency ")
                                            for x in s.concurrent:
                                                concurrencyfile.write("[" + str(x) + "]")
                                            concurrencyfile.write(" (" + str(len(s.concurrent)) + ")\n")
I-376 US19 US22 US30 TrkS TrkN
I-376 I-376 [] None None None
US19 US19
US22 US22
US30 US30
TrkS TrkS
TrkN TrkN

@yakra
Copy link
Contributor Author

yakra commented Nov 21, 2018

for h in highway_systems:
# h = usaus
    for r in h.route_list:
    # r = pa.us022
        for s in r.segment_list:
        # s = [I-376(69A) to I-376(69B) via pa.us022]
            if s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:
            # True
                for w1 in s.waypoint1.colocated:
                # w1 = pa.us022@I-376(69A)
                    if w1.route is not r:
                    # w1.route = pa.us022; True
                        for w2 in s.waypoint2.colocated:
                        # w2 = pa.i376@69B
                            if w1.route is w2.route:
                            # True
                                other = w1.route.find_segment_by_waypoints(w1,w2)
                                if other is not None:
                                # other = [69A to 69B via pa.i376]
                                    if s.concurrent is None:
                                    # First pass for US22; True
                                        s.concurrent = []
                                        # empty list
                                        other.concurrent = s.concurrent
_______________________________________ # The I-376 segment's list becomes empty too. Wait. Did we mean to do that? _______________________________________
                                        s.concurrent.append(s)
                                        #
                                        s.concurrent.append(other)
                                        #
                                        concurrencyfile.write("New concurrency [" + str(s) + "][" + str(other) + "] (" + str(len(s.concurrent)) + ")\n")
                                    else:
                                        if other not in s.concurrent:
                                        #
                                            s.concurrent.append(other)
                                            #
                                            #concurrencyfile.write("Added concurrency [" + str(s) + "]-[" + str(other) + "] ("+ str(len(s.concurrent)) + ")\n")
                                            concurrencyfile.write("Extended concurrency ")
                                            for x in s.concurrent:
                                                concurrencyfile.write("[" + str(x) + "]")
                                            concurrencyfile.write(" (" + str(len(s.concurrent)) + ")\n")
I-376 US19 US22 US30 TrkS TrkN
[] I-376 [] None None None
US19
US22
US30
TrkS
TrkN

@yakra
Copy link
Contributor Author

yakra commented Nov 21, 2018

for h in highway_systems:
# h = usaus
^   for r in h.route_list:
|   # r = pa.us022
|___.   for s in r.segment_list:
    |   # s = [I-376(69A) to I-376(69B) via pa.us022]
    |       if s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:
    |       # True
    |_______.   for w1 in s.waypoint1.colocated:
            |   # w1 = pa.us022@I-376(69A)
            |       if w1.route is not r:
            |       # w1.route = pa.us022; True
            |_______.   for w2 in s.waypoint2.colocated:
                    |   # w2 = pa.i376@69B
                    |       if w1.route is w2.route:
                    |       # True
                    |           other = w1.route.find_segment_by_waypoints(w1,w2)
                    |           if other is not None:
                    |           # other = [69A to 69B via pa.i376]
                    |               if s.concurrent is None:
                    |               # First pass for US22; True
                    |                   s.concurrent = []
                    |                   # empty list
                    |                   other.concurrent = s.concurrent
                    |                   # I-376 segments' list empty too.
                    |                   s.concurrent.append(s)
                    |                   # I-376 & US22 get US22
                    |                   s.concurrent.append(other)
                    |                   # I-376 & US22 get I-376
                    |__________________ concurrencyfile.write("New concurrency [" + str(s) + "][" + str(other) + "] (" + str(len(s.concurrent)) + ")\n")
                                    else:
                                        if other not in s.concurrent:
                                        #
                                            s.concurrent.append(other)
                                            #
                                            #concurrencyfile.write("Added concurrency [" + str(s) + "]-[" + str(other) + "] ("+ str(len(s.concurrent)) + ")\n")
                                            concurrencyfile.write("Extended concurrency ")
                                            for x in s.concurrent:
                                                concurrencyfile.write("[" + str(x) + "]")
                                            concurrencyfile.write(" (" + str(len(s.concurrent)) + ")\n")
I-376 US19 US22 US30 TrkS TrkN
US22 I-376 US22 None None None
I-376 US19 I-376
US22
US30
TrkS
TrkN

...and so on until the rest of the two lists are populated.
...and so on with each new route overwriting I-376's progress with an empty list, until...

@yakra
Copy link
Contributor Author

yakra commented Nov 21, 2018

for h in highway_systems:
# h = usausb
    for r in h.route_list:
    # r = pa.us019trkpit
        for s in r.segment_list:
        # s = [I-376(69B)_S to I-376(69A) via pa.us019trkpit]
            if s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:
            # True
            .-> for w1 in s.waypoint1.colocated:
            |   # w1 = pa.i376@69B, pa.us019@I-376(69B), pa.us022@I-376(69B), pa.us030@I-376(69B) ...
            |       if w1.route is not r:
            |       # True for I-376, US19, US22, US30
            |           for w2 in s.waypoint2.colocated:
            |           # w2 = pa.i376@69A, pa.us019@I-376(69A), pa.us022@I-376(69A), pa.us030@I-376(69A) ...
            |               if w1.route is w2.route:
            |               # True once for each
            |                   other = w1.route.find_segment_by_waypoints(w1,w2)
            |                   if other is not None:
            |                   # other is not None:
            |                       if s.concurrent is None:
            |                       # First pass for [I-376(69B)_S to I-376(69A) via pa.us019trkpit] True; subsequent passes false
            |                           s.concurrent = []
            |                           # empty list
            |                           other.concurrent = s.concurrent
            |                           # 1st pass: I-376 segments' list empty too.
            |                           s.concurrent.append(s)
            |                           # 1st pass: I-376 & TrkS get TrkS
            |                           s.concurrent.append(other)
            |                           # 1st pass: I-376 & TrkS get I-376
            |                           concurrencyfile.write("New concurrency [" + str(s) + "][" + str(other) + "] (" + str(len(s.concurrent)) + ")\n")
            |                       else:
            |                           if other not in s.concurrent:
            |                           #
            |                               s.concurrent.append(other)
            |                               # 2nd+ passes: I-376 & TrkS get US19, 22, 30
            |                               #concurrencyfile.write("Added concurrency [" + str(s) + "]-[" + str(other) + "] ("+ str(len(s.concurrent)) + ")\n")
            |                               concurrencyfile.write("Extended concurrency ")
            |                               for x in s.concurrent:
            |                                   concurrencyfile.write("[" + str(x) + "]")
            |______________________________ concurrencyfile.write(" (" + str(len(s.concurrent)) + ")\n")
I-376 US19 US22 US30 TrkS TrkN
TrkS I-376 US22 US30 TrkS None
I-376 US19 I-376 I-376 I-376
US19 US22 US19 US19 US19
US22 US30 US30 US22 US22
US30 TrkS TrkS TrkS US30
TrkN TrkN TrkN

@yakra
Copy link
Contributor Author

yakra commented Nov 21, 2018

for h in highway_systems:
# h = usausb
    for r in h.route_list:
    # r = pa.us019trkpit
    .-> for s in r.segment_list:
    |   # s = [I-376(69B)_S to I-376(69A) via pa.us019trkpit]
    |       if s.waypoint1.colocated is not None and s.waypoint2.colocated is not None:
    |       # True
    |           for w1 in s.waypoint1.colocated:
    |           # w1 = ... pa.us019trkpit@I-376(69B)_S, pa.us019trkpit@I-376(69B)_N
    |               if w1.route is not r:
    |______________ # w1.route is r for both remaining points; nothing else happens; concurrency remains at 5 routes
                        for w2 in s.waypoint2.colocated:
                        #
                            if w1.route is w2.route:
                            #
                                other = w1.route.find_segment_by_waypoints(w1,w2)
                                if other is not None:
                                #
                                    if s.concurrent is None:
                                    #
                                        s.concurrent = []
                                        #
                                        other.concurrent = s.concurrent
                                        #
                                        s.concurrent.append(s)
                                        #
                                        s.concurrent.append(other)
                                        #
                                        concurrencyfile.write("New concurrency [" + str(s) + "][" + str(other) + "] (" + str(len(s.concurrent)) + ")\n")
                                    else:
                                        if other not in s.concurrent:
                                        #
                                            s.concurrent.append(other)
                                            #
                                            #concurrencyfile.write("Added concurrency [" + str(s) + "]-[" + str(other) + "] ("+ str(len(s.concurrent)) + ")\n")
                                            concurrencyfile.write("Extended concurrency ")
                                            for x in s.concurrent:
                                                concurrencyfile.write("[" + str(x) + "]")
                                            concurrencyfile.write(" (" + str(len(s.concurrent)) + ")\n")
I-376 US19 US22 US30 TrkS TrkN
TrkS I-376 US22 US30 TrkS None
I-376 US19 I-376 I-376 I-376
US19 US22 US19 US19 US19
US22 US30 US30 US22 US22
US30 TrkS TrkS TrkS US30
TrkN TrkN TrkN

...Finally we test the one last segment, [I-376(69A) to I-376(69B)_N via pa.us019trkpit].
As with [I-376(69B)_S to I-376(69A) via pa.us019trkpit], two of the w1 points are for its own route.
[I-376(69A) to I-376(69B)_N via pa.us019trkpit] thus plugs itself into its own concurrency list, and I-376, and doesn't detect [I-376(69B)_S to I-376(69A) via pa.us019trkpit].
This leaves our final concurrency lists looking like:

I-376 US19 US22 US30 TrkS TrkN
TrkN I-376 US22 US30 TrkS TrkN
I-376 US19 I-376 I-376 I-376 I-376
US19 US22 US19 US19 US19 US19
US22 US30 US30 US22 US22 US22
US30 TrkS TrkS TrkS US30 US30
TrkN TrkN TrkN

...which we can see in concurrencies.log.

@yakra
Copy link
Contributor Author

yakra commented Nov 21, 2018

Why the differences in concurrencies.log?

One more line sometimes, in concurrency detection:

  • Lines occur in clusters, when a new currency is found, and when it's extended.
  • A cluster for the 2nd route in a concurrency is not shown: new concurrencies are not found because they were flagged during the 1st pass, from the 1st route's HighwaySegment.
  • Sometimes 6 concurrencies are found, and sometimes 5: 5 when searching for a concurrent segment for US19TrkPit itself, and 6 when searching for a concurrent segment for one of the other routes.
  • Normally, as is the case when running siteupdate with 1 thread, US19 (or another non-US19TrkPit route) is second, and we don't see a cluster of 5 lines for a 6-segment concurrency. Sometimes when multithreaded, US19TrkPit is second, and we don't see a cluster of 4 lines for a 5-segment concurrency. US19 (or whatever else) is no longer second, so we do see its cluster of 5 lines now. BOOM! Extra line.

We see this on line 114911 of
http://yakra.teresco.org/tests/concurrencies/y20181119/m/concurrencies-3.log :
Extended concurrency [69A to 69B via pa.i376][I-376(69B)_S to I-376(69A) via pa.us019trkpit][I-376(69A) to I-376(69B)_N via pa.us019trkpit][I-376(69A) to I-376(69B) via pa.us019][I-376(69A) to I-376(69B) via pa.us022][I-376(69A) to I-376(69B) via pa.us030] (6)
This also explains...

Why we have 18 more augments for the travelers .listing only the I-376 segment:

  • When running siteupdate with 1 thread, the northern US19Trk segment is tested last, overwriting the concurrency list for I-376 in the process. The southern US19Trk segment isn't detected, so it gets no entry in I-376's list, and thus these 18 travelers get no concurrency augment.
  • When running with multiple threads, a different route (US30 in the above example) is usually last. All concurrencies are found & written to I-376's list, and these travelers get their augments.

As noted in the OP, adding a single other.concurrent = s.concurrent to the ELSE block ought to fix things.

What if US19TrkPit is tested first?

Shouldn't be a problem. 5 concurrencies will be detected in the first pass. On the second pass, when checking a different route, all 6 concurrencies will be found. The 6th one, newly detected, will be added to all the lists.

Yeah man. I'm gonna try this out!

@jteresco
Copy link
Contributor

Wow, thanks for the epic debugging session. If this works (or even if not) I hereby award you TM's first ever Excellence in Finding Insidious Bugs award, and all the rights, privileges, and responsibilities appertaining thereto.

@michihdeu
Copy link
Contributor

🥇

@yakra
Copy link
Contributor Author

yakra commented Nov 21, 2018

Responsibilities?

;)

@yakra
Copy link
Contributor Author

yakra commented Nov 22, 2018

What if US19TrkPit is tested first?

Shouldn't be a problem. 5 concurrencies will be detected in the first pass. On the second pass, when checking a different route, all 6 concurrencies will be found. The 6th one, newly detected, will be added to all the lists.

This is in fact what happens.
A detail that I didn't think of, but is obvious now that I've seen it:

  • First pass, checking [I-376(69B)_S to I-376(69A) via pa.us019trkpit], 5 concurrent segments are found, including itself. [I-376(69A) to I-376(69B)_N via pa.us019trkpit] is not found, because w1.route is r.
  • Second pass, still checking segments in pa.us019trkpit, [I-376(69A) to I-376(69B)_N via pa.us019trkpit] now. This segment has no concurrency list, so as the other segments are found, other.concurrent = s.concurrent, and their concurrency lists are overwritten & repopulated.
  • We now have 5 segments with a concurrency list of
    [I-376(69A) to I-376(69B)_N via pa.us019trkpit][69A to 69B via pa.i376][I-376(69A) to I-376(69B) via pa.us019][I-376(69A) to I-376(69B) via pa.us022][I-376(69A) to I-376(69B) via pa.us030].
    The 6th, original, segment, not detected is this pass, keeps its original concurrency list of [I-376(69B)_S to I-376(69A) via pa.us019trkpit][69A to 69B via pa.i376][I-376(69A) to I-376(69B) via pa.us019][I-376(69A) to I-376(69B) via pa.us022][I-376(69A) to I-376(69B) via pa.us030]
  • Third pass, when checking a different route: I-376 had its list cleared & repopulated in the 2nd pass, so [I-376(69B)_S to I-376(69A) via pa.us019trkpit] has been forgotten about. It's detected again, and since since I-376 does have a concurrency list (s.concurrent is not None), we go to the else: block: other.concurrent = s.concurrent, overwriting the one remaining list for the [I-376(69B)_S to I-376(69A) via pa.us019trkpit] segment that's not linked to the other 5. Then, this last remaining segment is added to all six lists. Six segments, six lists, each listing all six segments in the same order. Voila!

Thus in concurrencies.log we see:

New concurrency [I-376(69B)_S to I-376(69A) via pa.us019trkpit][69A to 69B via pa.i376] (2)
Extended concurrency [I-376(69B)_S to I-376(69A) via pa.us019trkpit][69A to 69B via pa.i376][I-376(69A) to I-376(69B) via pa.us019] (3)
Extended concurrency [I-376(69B)_S to I-376(69A) via pa.us019trkpit][69A to 69B via pa.i376][I-376(69A) to I-376(69B) via pa.us019][I-376(69A) to I-376(69B) via pa.us022] (4)
Extended concurrency [I-376(69B)_S to I-376(69A) via pa.us019trkpit][69A to 69B via pa.i376][I-376(69A) to I-376(69B) via pa.us019][I-376(69A) to I-376(69B) via pa.us022][I-376(69A) to I-376(69B) via pa.us030] (5)
New concurrency [I-376(69A) to I-376(69B)_N via pa.us019trkpit][69A to 69B via pa.i376] (2)
Extended concurrency [I-376(69A) to I-376(69B)_N via pa.us019trkpit][69A to 69B via pa.i376][I-376(69A) to I-376(69B) via pa.us019] (3)
Extended concurrency [I-376(69A) to I-376(69B)_N via pa.us019trkpit][69A to 69B via pa.i376][I-376(69A) to I-376(69B) via pa.us019][I-376(69A) to I-376(69B) via pa.us022] (4)
Extended concurrency [I-376(69A) to I-376(69B)_N via pa.us019trkpit][69A to 69B via pa.i376][I-376(69A) to I-376(69B) via pa.us019][I-376(69A) to I-376(69B) via pa.us022][I-376(69A) to I-376(69B) via pa.us030] (5)

...and then several thousand lines later,

Extended concurrency [+X01 to 69A via pa.i376][+X01 to I-376(69A) via pa.us022][+X01 to I-376(69A) via pa.us030] (3)
Extended concurrency [I-376(69A) to I-376(69B)_N via pa.us019trkpit][69A to 69B via pa.i376][I-376(69A) to I-376(69B) via pa.us019][I-376(69A) to I-376(69B) via pa.us022][I-376(69A) to I-376(69B) via pa.us030][I-376(69B)_S to I-376(69A) via pa.us019trkpit] (6)
New concurrency [70A to 70D via pa.i376][I-376(70A) to I-376(70D) via pa.us022] (2)

To emphasize, this does not harm anything (Again, 6 segments, 6 lists listing 6 segments). It just makes concurrencies.log look a little ugly.

If I really wanted to, I could change the innermost IF statement:

if s.concurrent is None:
    if other.concurrent is None:
        s.concurrent = []
        other.concurrent = s.concurrent
        s.concurrent.append(s)
        s.concurrent.append(other)
        concurrencyfile.write("New concurrency [" + str(s) + "][" + str(other) + "] (" + str(len(s.concurrent)) + ")\n")
    else: # the very unusual case of a route colocated with itself, such as PA US19TrkPit
        s.concurrent = other.concurrent
        s.concurrent.append(s)
        concurrencyfile.write("Extended concurrency ")
        for x in s.concurrent:
            concurrencyfile.write("[" + str(x) + "]")
        concurrencyfile.write(" (" + str(len(s.concurrent)) + ")\n")

but this is unnecessary; the concurrencies are detected either way. All it gets us is a prettier concurrencies.log:

New concurrency [I-376(69B)_S to I-376(69A) via pa.us019trkpit][69A to 69B via pa.i376] (2)
Extended concurrency [I-376(69B)_S to I-376(69A) via pa.us019trkpit][69A to 69B via pa.i376][I-376(69A) to I-376(69B) via pa.us019] (3)
Extended concurrency [I-376(69B)_S to I-376(69A) via pa.us019trkpit][69A to 69B via pa.i376][I-376(69A) to I-376(69B) via pa.us019][I-376(69A) to I-376(69B) via pa.us022] (4)
Extended concurrency [I-376(69B)_S to I-376(69A) via pa.us019trkpit][69A to 69B via pa.i376][I-376(69A) to I-376(69B) via pa.us019][I-376(69A) to I-376(69B) via pa.us022][I-376(69A) to I-376(69B) via pa.us030] (5)
Extended concurrency [I-376(69B)_S to I-376(69A) via pa.us019trkpit][69A to 69B via pa.i376][I-376(69A) to I-376(69B) via pa.us019][I-376(69A) to I-376(69B) via pa.us022][I-376(69A) to I-376(69B) via pa.us030][I-376(69A) to I-376(69B)_N via pa.us019trkpit] (6)

...all together in one cluster.
I don't want to add extraneous lines of clutter to the code that would involve doing an extra IF every time a new concurrency is found.
These self-concurrency cases are exceedingly rare, and rarer still that the offending route should be the first one checked for concurrencies, which I had to create artificially for this test.

Nope.
The one new line
other.concurrent = s.concurrent
is fine.

I'll open a pull request once I have Thanksgiving out of the way.
After that, I see some potential for more tweaks to efficiency that can be done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants