public < S extends Object > void migrate ( List < List < EvaluatedCandidate < S > > > islandPopulations , int migrantCount , Random rng ) { // The first batch of immigrants is from the last island to the first. List < EvaluatedCandidate < S >> lastIsland = islandPopulations . get ( islandPopulations . size ( ) - 1 ) ; Collections . shuffle ( lastIsland , rng ) ; List < EvaluatedCandidate < S > > migrants = lastIsland . subList ( lastIsland . size ( ) - migrantCount , lastIsland . size ( ) ) ; for ( List < EvaluatedCandidate < S > > island : islandPopulations ) { // Migrants from the last island are immigrants for this island. List < EvaluatedCandidate < S >> immigrants = migrants ; if ( island != lastIsland ) // We've already migrated individuals from the last island. { // Select the migrants that will move to the next island to make room for the immigrants here. // Randomise the population so that there is no bias concerning which individuals are migrated. Collections . shuffle ( island , rng ) ; migrants = new ArrayList < EvaluatedCandidate < S > > ( island . subList ( island . size ( ) - migrantCount , island . size ( ) ) ) ; } // Copy the immigrants over the last members of the population (those that are themselves // migrating to the next island). for ( int i = 0 ; i < immigrants . size ( ) ; i ++ ) { island . set ( island . size ( ) - migrantCount + i , immigrants . get ( i ) ) ; } } }
Migrates a fixed number of individuals from each island to the adjacent island . Operates as if the islands are arranged in a ring with migration occurring in a clockwise direction . The individuals to be migrated are chosen completely at random .