Class PositionBasedCrossover
- All Implemented Interfaces:
PermutationFullBinaryOperator
,Splittable<CrossoverOperator<Permutation>>
,CrossoverOperator<Permutation>
To illustrate its behavior, consider the following example. Let parent p1 = [2, 5, 1, 4, 3, 0] and parent p2 = [5, 4, 3, 2, 1, 0]. Step 1 generates a list that maps each element to its indexes in the parents. From the above, we'd have the element to index mapping: [ 0 : {5, 5}, 1 : {2, 4}, 2 : {0, 3}, 3 : {4, 2}, 4 : {3, 1}, 5 : {1, 0}]. Randomize the ordering of this list of element to index mappings: [3 : {4, 2}, 5 : {1, 0}, 0 : {5, 5}, 2 : {0, 3}, 1 : {2, 4}, 4 : {3, 1}]. Pick a random subset of elements, with each element equally likely chosen (on average n/2 elements will be chosen). For this example, imagine that elements 5 and 1 were chosen. For each of these, in the element to index mappings list, swap the two indexes. For example, element 5 currently has the mapping: 5 : {1, 0}. Swap the indexes to instead get: 5 : {0, 1}. Doing this for both elements 5 and 1 leads to: [3 : {4, 2}, 5 : {0, 1}, 0 : {5, 5}, 2 : {0, 3}, 1 : {4, 2}, 4 : {3, 1}]. In this list of element to index mappings, the first index for each element is where we will attempt to put that element in child c1, and the second is where we will attempt to put it in c2. Proceed as follows. Initialize empty children c1 = [x, x, x, x, x, x] and c2 = [x, x, x, x, x, x]. Iterate over the mappings and if the corresponding index in a child is empty, place the element there. Otherwise skip that element in that child for now. In this case, we'll get: c1 = [5, x, x, 4, 3, 0] and c2 = [x, 5, 3, 2, x, 0]. Next, using the same ordering, attempt to put the missing elements in the opposite index. For example, c1 is missing element 2. Its mapping is {0, 3}. We failed to put it at index 0 because the 5 was already there in c1. So we would attempt to put it at index 3. However, c1 already has 4 there, so we will again skip element 2 for now. Element 1 is mapped to the indexes {4, 2}. We couldn't put it at index 4 in c1 because the 3 is there, and we couldn't put it at index 2 in c2 because the 3 is there. So try the opposite indexes. Both of which work, so we now have: c1 = [5, x, 1, 4, 3, 0] and c2 = [x, 5, 3, 2, 1, 0]. The next element in the ordered mapping list is 4, which we failed to put in c2 at index 3 because the 2 is there, so we would instead try to put it at the other index 1, but that index is also taken. The last stage fills in any missing elements. It again uses the ordered list, and it fills them into any empty indexes left to right. In this case, there is only one missing element in each, so those elements go in the only remaining spots: c1 = [5, 2, 1, 4, 3, 0] and c2 = [4, 5, 3, 2, 1, 0].
The worst case runtime of a call to cross
is O(n), where n is the length of the
permutations.
The PBX operator was introduced in the following paper:
T. Barecke and M. Detyniecki, Memetic algorithms for inexact graph matching. 2007 IEEE Congress on Evolutionary Computation, Singapore, 2007, pp. 4238-4245, doi: 10.1109/CEC.2007.4425024.
-
Constructor Summary
ConstructorDescriptionConstructs a position based crossover (PBX) operator. -
Method Summary
Modifier and TypeMethodDescriptionvoid
apply
(int[] raw1, int[] raw2, Permutation p1, Permutation p2) SeePermutationFullBinaryOperator
for details of this method.void
cross
(Permutation c1, Permutation c2) Performs a crossover for an evolutionary algorithm, such that crossover forms two children from two parents.split()
Generates a functionally identical copy of this object, for use in multithreaded implementations of search algorithms.
-
Constructor Details
-
PositionBasedCrossover
public PositionBasedCrossover()Constructs a position based crossover (PBX) operator.
-
-
Method Details
-
cross
Description copied from interface:CrossoverOperator
Performs a crossover for an evolutionary algorithm, such that crossover forms two children from two parents. Implementations of this method modify the parameters, transforming the parents into the children.- Specified by:
cross
in interfaceCrossoverOperator<Permutation>
- Parameters:
c1
- A candidate solution subject to the crossover. This method changes the state of c1.c2
- A candidate solution subject to the crossover. This method changes the state of c2.
-
split
Description copied from interface:Splittable
Generates a functionally identical copy of this object, for use in multithreaded implementations of search algorithms. The state of the object that is returned may or may not be identical to that of the original. Thus, this is a distinct concept from the functionality of theCopyable
interface. Classes that implement this interface must ensure that the object returned performs the same functionality, and that it does not share any state data that would be either unsafe or inefficient for concurrent access by multiple threads. The split method is allowed to simply return the this reference, provided that it is both safe and efficient for multiple threads to share a single copy of the Splittable object. The intention is to provide a multithreaded search with the capability to provide spawned threads with their own distinct search operators. Such multithreaded algorithms can call the split method for each thread it spawns to generate a functionally identical copy of the operator, but with independent state.- Specified by:
split
in interfaceSplittable<CrossoverOperator<Permutation>>
- Returns:
- A functionally identical copy of the object, or a reference to this if it is both safe and efficient for multiple threads to share a single instance of this Splittable object.
-
apply
SeePermutationFullBinaryOperator
for details of this method. This method is not intended for direct usage. Use thecross(org.cicirello.permutations.Permutation, org.cicirello.permutations.Permutation)
method instead.- Specified by:
apply
in interfacePermutationFullBinaryOperator
- Parameters:
raw1
- The raw representation of the first permutation.raw2
- The raw representation of the second permutation.p1
- The first permutation.p2
- The second permutation.
-