@@ -621,31 +621,32 @@ public :
621
621
return m_turns[rp.turn_index ].operations [rp.operation_index ];
622
622
}
623
623
624
- inline sort_by_side::rank_type select_rank (sbs_type const & sbs,
625
- bool skip_isolated) const
624
+ inline sort_by_side::rank_type select_rank (sbs_type const & sbs) const
626
625
{
626
+ static bool const is_intersection
627
+ = target_operation == operation_intersection;
628
+
627
629
// Take the first outgoing rank corresponding to incoming region,
628
630
// or take another region if it is not isolated
629
- turn_operation_type const & incoming_op
630
- = operation_from_rank (sbs.m_ranked_points .front ());
631
+ auto const & in_op = operation_from_rank (sbs.m_ranked_points .front ());
631
632
632
633
for (std::size_t i = 0 ; i < sbs.m_ranked_points .size (); i++)
633
634
{
634
- typename sbs_type::rp const & rp = sbs.m_ranked_points [i];
635
+ auto const & rp = sbs.m_ranked_points [i];
635
636
if (rp.rank == 0 || rp.direction == sort_by_side::dir_from)
636
637
{
637
638
continue ;
638
639
}
639
- turn_operation_type const & op = operation_from_rank (rp);
640
+ auto const & out_op = operation_from_rank (rp);
640
641
641
- if (op .operation != target_operation
642
- && op .operation != operation_continue)
642
+ if (out_op .operation != target_operation
643
+ && out_op .operation != operation_continue)
643
644
{
644
645
continue ;
645
646
}
646
647
647
- if (op .enriched .region_id == incoming_op .enriched .region_id
648
- || (skip_isolated && ! op .enriched .isolated ))
648
+ if (in_op .enriched .region_id == out_op .enriched .region_id
649
+ || (is_intersection && ! out_op .enriched .isolated ))
649
650
{
650
651
// Region corresponds to incoming region, or (for intersection)
651
652
// there is a non-isolated other region which should be taken
@@ -660,7 +661,7 @@ public :
660
661
int & op_index, sbs_type const & sbs,
661
662
signed_size_type start_turn_index, int start_op_index) const
662
663
{
663
- sort_by_side::rank_type const selected_rank = select_rank (sbs, false );
664
+ sort_by_side::rank_type const selected_rank = select_rank (sbs);
664
665
665
666
int current_priority = 0 ;
666
667
for (std::size_t i = 1 ; i < sbs.m_ranked_points .size (); i++)
@@ -688,49 +689,59 @@ public :
688
689
inline bool analyze_cluster_intersection (signed_size_type& turn_index,
689
690
int & op_index, sbs_type const & sbs) const
690
691
{
691
- sort_by_side::rank_type const selected_rank = select_rank (sbs, true );
692
+ // Select the rank based on regions and isolation
693
+ sort_by_side::rank_type const selected_rank = select_rank (sbs);
692
694
693
- if (selected_rank > 0 )
695
+ if (selected_rank <= 0 )
694
696
{
695
- typename turn_operation_type::comparable_distance_type
696
- min_remaining_distance = 0 ;
697
+ return false ;
698
+ }
697
699
698
- std::size_t selected_index = sbs.m_ranked_points .size ();
699
- for (std::size_t i = 0 ; i < sbs.m_ranked_points .size (); i++)
700
+ // From these ranks, select the index: the first, or the one with
701
+ // the smallest remaining distance
702
+ typename turn_operation_type::comparable_distance_type
703
+ min_remaining_distance = 0 ;
704
+
705
+ std::size_t selected_index = sbs.m_ranked_points .size ();
706
+ for (std::size_t i = 0 ; i < sbs.m_ranked_points .size (); i++)
707
+ {
708
+ auto const & ranked_point = sbs.m_ranked_points [i];
709
+
710
+ if (ranked_point.rank > selected_rank)
711
+ {
712
+ break ;
713
+ }
714
+ else if (ranked_point.rank == selected_rank)
700
715
{
701
- typename sbs_type::rp const & ranked_point = sbs. m_ranked_points [i] ;
716
+ auto const & op = operation_from_rank (ranked_point) ;
702
717
703
- if (ranked_point. rank == selected_rank )
718
+ if (op. visited . finalized () )
704
719
{
705
- turn_operation_type const & op = operation_from_rank (ranked_point);
706
-
707
- if (op.visited .finalized ())
708
- {
709
- // This direction is already traveled before, the same
710
- // cannot be traveled again
711
- continue ;
712
- }
713
-
714
- // Take turn with the smallest remaining distance
715
- if (selected_index == sbs.m_ranked_points .size ()
716
- || op.remaining_distance < min_remaining_distance)
717
- {
718
- selected_index = i;
719
- min_remaining_distance = op.remaining_distance ;
720
- }
720
+ // This direction is already traveled,
721
+ // it cannot be traveled again
722
+ continue ;
721
723
}
722
- }
723
724
724
- if (selected_index < sbs.m_ranked_points .size ())
725
- {
726
- typename sbs_type::rp const & ranked_point = sbs.m_ranked_points [selected_index];
727
- turn_index = ranked_point.turn_index ;
728
- op_index = ranked_point.operation_index ;
729
- return true ;
725
+ if (selected_index == sbs.m_ranked_points .size ()
726
+ || op.remaining_distance < min_remaining_distance)
727
+ {
728
+ // It was unassigned or it is better
729
+ selected_index = i;
730
+ min_remaining_distance = op.remaining_distance ;
731
+ }
730
732
}
731
733
}
732
734
733
- return false ;
735
+ if (selected_index == sbs.m_ranked_points .size ())
736
+ {
737
+ // Should not happen, there must be points with the selected rank
738
+ return false ;
739
+ }
740
+
741
+ auto const & ranked_point = sbs.m_ranked_points [selected_index];
742
+ turn_index = ranked_point.turn_index ;
743
+ op_index = ranked_point.operation_index ;
744
+ return true ;
734
745
}
735
746
736
747
inline bool fill_sbs (sbs_type& sbs,
@@ -819,6 +830,7 @@ public :
819
830
return result;
820
831
}
821
832
833
+ // Analyzes a non-clustered "ii" intersection, as if it is clustered.
822
834
inline bool analyze_ii_intersection (signed_size_type& turn_index, int & op_index,
823
835
turn_type const & current_turn,
824
836
segment_identifier const & previous_seg_id)
0 commit comments