private static void linearCrossover(Program gp1, Program gp2, LGP manager, RandEngine randEngine) {
      // length(gp1) <= length(gp2)
      if (gp1.length() > gp2.length())
      {
         gp1 = gp2;
         gp2 = gp1;
      }

      // select i1 from gp1 and i2 from gp2 such that abs(i1-i2) <= max_crossover_point_distance
      // max_crossover_point_distance=min{length(gp1) - 1, m_max_distance_of_crossover_points}
      int i1 = randEngine.nextInt(gp1.length());
      int i2 = randEngine.nextInt(gp2.length());
      int cross_point_distance = (i1 > i2) ? (i1 - i2) : (i2 - i1);
      int max_crossover_point_distance = (gp1.length() - 1 > manager.getMaxDistanceOfCrossoverPoints() ? manager.getMaxDistanceOfCrossoverPoints() : gp1.length() - 1);
      while (cross_point_distance > max_crossover_point_distance)
      {
         i1 = randEngine.nextInt(gp1.length());
         i2 = randEngine.nextInt(gp2.length());
         cross_point_distance = (i1 > i2) ? (i1 - i2) : (i2 - i1);
      }

      int s1_max = (gp1.length() - i1) > manager.getMaxDifferenceOfSegmentLength() ? manager.getMaxDifferenceOfSegmentLength() : (gp1.length() - i1);
      int s2_max = (gp2.length() - i2) > manager.getMaxDifferenceOfSegmentLength() ? manager.getMaxDifferenceOfSegmentLength() : (gp2.length() - i2);

      // select s1 from gp1 (start at i1) and s2 from gp2 (start at i2)
      // such that length(s1) <= length(s2)
      // and abs(length(s1) - length(s2)) <= m_max_difference_of_segment_length)
      int ls1 = 1 + randEngine.nextInt(s1_max);
      int ls2 = 1 + randEngine.nextInt(s2_max);
      int lsd = (ls1 > ls2) ? (ls1 - ls2) : (ls2 - ls1);
      while ((ls1 > ls2) && (lsd > manager.getMaxDifferenceOfSegmentLength()))
      {
         ls1 = 1 + randEngine.nextInt(s1_max);
         ls2 = 1 + randEngine.nextInt(s2_max);
         lsd = (ls1 > ls2) ? (ls1 - ls2) : (ls2 - ls1);
      }

      if(((gp2.length() - (ls2-ls1)) < manager.getMinProgramLength() || ((gp1.length()+(ls2-ls1)) > manager.getMaxProgramLength())))
      {
         if(randEngine.uniform() < 0.5)
         {
            ls2=ls1;
         }
         else
         {
            ls1=ls2;
         }
         if((i1+ls1) > gp1.length())
         {
            ls1 = gp1.length() - i1;
         }
         if((i2 + ls2) > gp2.length()) {
            ls2 = gp2.length() - i2;
         }
      }



      List<Instruction> instructions1=gp1.getInstructions();
      List<Instruction> instructions2=gp2.getInstructions();

      List<Instruction> instructions1_1=new ArrayList<>();
      List<Instruction> instructions1_2=new ArrayList<>();
      List<Instruction> instructions1_3=new ArrayList<>();

      List<Instruction> instructions2_1=new ArrayList<>();
      List<Instruction> instructions2_2=new ArrayList<>();
      List<Instruction> instructions2_3=new ArrayList<>();

      for(int i=0; i < i1; ++i)
      {
         instructions1_1.add(instructions1.get(i));
      }
      for(int i=i1; i < i1+ls1; ++i)
      {
         instructions1_2.add(instructions1.get(i));
      }
      for(int i=i1+ls1; i < instructions1.size(); ++i)
      {
         instructions1_3.add(instructions1.get(i));
      }

      for(int i=0; i < i2; ++i)
      {
         instructions2_1.add(instructions2.get(i));
      }
      for(int i=i2; i < i2+ls2; ++i)
      {
         instructions2_2.add(instructions2.get(i));
      }
      for(int i=i2+ls2; i < instructions2.size(); ++i)
      {
         instructions2_3.add(instructions2.get(i));
      }

      instructions1.clear();
      instructions2.clear();

      for(int i=0; i < i1; ++i)
      {
         instructions1.add(instructions1_1.get(i));
      }
      for(int i=0; i < ls2; ++i)
      {
         instructions1.add(InstructionHelper.reassign2Program(instructions2_2.get(i), gp1));
      }
      for(int i=0; i < instructions1_3.size(); ++i)
      {
         instructions1.add(instructions1_3.get(i));
      }

      for(int i=0; i < i2; ++i)
      {
         instructions2.add(instructions2_1.get(i));
      }
      for(int i=0; i < ls1; ++i)
      {
         instructions2.add(InstructionHelper.reassign2Program(instructions1_2.get(i), gp2));
      }
      for(int i=0; i < instructions2_3.size(); ++i)
      {
         instructions2.add(instructions2_3.get(i));
      }

      gp1.invalidateCost();
      gp2.invalidateCost();
   }
private static void linearCrossover ( Program gp1 , Program gp2 , LGP manager , RandEngine randEngine ) { if ( gp1 . length ( ) > gp2 . length ( ) ) { gp1 = gp2 ; gp2 = gp1 ; } int i1 = randEngine . nextInt ( gp1 . length ( ) ) ; int i2 = randEngine . nextInt ( gp2 . length ( ) ) ; int cross_point_distance = ( i1 > i2 ) ? ( i1 - i2 ) : ( i2 - i1 ) ; int max_crossover_point_distance = ( gp1 . length ( ) - 1 > manager . getMaxDistanceOfCrossoverPoints ( ) ? manager . getMaxDistanceOfCrossoverPoints ( ) : gp1 . length ( ) - 1 ) ; while ( cross_point_distance > max_crossover_point_distance ) { i1 = randEngine . nextInt ( gp1 . length ( ) ) ; i2 = randEngine . nextInt ( gp2 . length ( ) ) ; cross_point_distance = ( i1 > i2 ) ? ( i1 - i2 ) : ( i2 - i1 ) ; } int s1_max = ( gp1 . length ( ) - i1 ) > manager . getMaxDifferenceOfSegmentLength ( ) ? manager . getMaxDifferenceOfSegmentLength ( ) : ( gp1 . length ( ) - i1 ) ; int s2_max = ( gp2 . length ( ) - i2 ) > manager . getMaxDifferenceOfSegmentLength ( ) ? manager . getMaxDifferenceOfSegmentLength ( ) : ( gp2 . length ( ) - i2 ) ; int ls1 = 1 + randEngine . nextInt ( s1_max ) ; int ls2 = 1 + randEngine . nextInt ( s2_max ) ; int lsd = ( ls1 > ls2 ) ? ( ls1 - ls2 ) : ( ls2 - ls1 ) ; while ( ( ls1 > ls2 ) && ( lsd > manager . getMaxDifferenceOfSegmentLength ( ) ) ) { ls1 = 1 + randEngine . nextInt ( s1_max ) ; ls2 = 1 + randEngine . nextInt ( s2_max ) ; lsd = ( ls1 > ls2 ) ? ( ls1 - ls2 ) : ( ls2 - ls1 ) ; } if ( ( ( gp2 . length ( ) - ( ls2 - ls1 ) ) < manager . getMinProgramLength ( ) || ( ( gp1 . length ( ) + ( ls2 - ls1 ) ) > manager . getMaxProgramLength ( ) ) ) ) { if ( randEngine . uniform ( ) < 0.5 ) { ls2 = ls1 ; } else { ls1 = ls2 ; } if ( ( i1 + ls1 ) > gp1 . length ( ) ) { ls1 = gp1 . length ( ) - i1 ; } if ( ( i2 + ls2 ) > gp2 . length ( ) ) { ls2 = gp2 . length ( ) - i2 ; } } List < Instruction > instructions1 = gp1 . getInstructions ( ) ; List < Instruction > instructions2 = gp2 . getInstructions ( ) ; List < Instruction > instructions1_1 = new ArrayList < > ( ) ; List < Instruction > instructions1_2 = new ArrayList < > ( ) ; List < Instruction > instructions1_3 = new ArrayList < > ( ) ; List < Instruction > instructions2_1 = new ArrayList < > ( ) ; List < Instruction > instructions2_2 = new ArrayList < > ( ) ; List < Instruction > instructions2_3 = new ArrayList < > ( ) ; for ( int i = 0 ; i < i1 ; ++ i ) { instructions1_1 . add ( instructions1 . get ( i ) ) ; } for ( int i = i1 ; i < i1 + ls1 ; ++ i ) { instructions1_2 . add ( instructions1 . get ( i ) ) ; } for ( int i = i1 + ls1 ; i < instructions1 . size ( ) ; ++ i ) { instructions1_3 . add ( instructions1 . get ( i ) ) ; } for ( int i = 0 ; i < i2 ; ++ i ) { instructions2_1 . add ( instructions2 . get ( i ) ) ; } for ( int i = i2 ; i < i2 + ls2 ; ++ i ) { instructions2_2 . add ( instructions2 . get ( i ) ) ; } for ( int i = i2 + ls2 ; i < instructions2 . size ( ) ; ++ i ) { instructions2_3 . add ( instructions2 . get ( i ) ) ; } instructions1 . clear ( ) ; instructions2 . clear ( ) ; for ( int i = 0 ; i < i1 ; ++ i ) { instructions1 . add ( instructions1_1 . get ( i ) ) ; } for ( int i = 0 ; i < ls2 ; ++ i ) { instructions1 . add ( InstructionHelper . reassign2Program ( instructions2_2 . get ( i ) , gp1 ) ) ; } for ( int i = 0 ; i < instructions1_3 . size ( ) ; ++ i ) { instructions1 . add ( instructions1_3 . get ( i ) ) ; } for ( int i = 0 ; i < i2 ; ++ i ) { instructions2 . add ( instructions2_1 . get ( i ) ) ; } for ( int i = 0 ; i < ls1 ; ++ i ) { instructions2 . add ( InstructionHelper . reassign2Program ( instructions1_2 . get ( i ) , gp2 ) ) ; } for ( int i = 0 ; i < instructions2_3 . size ( ) ; ++ i ) { instructions2 . add ( instructions2_3 . get ( i ) ) ; } gp1 . invalidateCost ( ) ; gp2 . invalidateCost ( ) ; }
this linear crossover can also be considered as two-point crossover