I am currently working on a NP-complete problem, and have implemented a personal genetic algorithm for this purpose. The results are more than I could have expected. With a well-designed fitness function and a couple population/mutation carefully tuned, I guess GA can be an excellent tool in certain cases.
Anyway, I am now looking for a metaheuristic (GA, simulated annealing...) capable of producing an optimal shuffling output.
By shuffle, I mean, in this context, an unbiased (à la Fisher-Yates) random permutation of a finite set. Like a card deck. A huge one (~ 500! permutations).
The values of this set are all different. No collisions are to be expected.
Because of this contraint, I have some difficulties to implement a GA solution. Indeed, the shuffled values cannot be used as genes. It is easy to see why:
#include <iostream>
#include <vector>
#define SPLICING 50 // 50|50 one-point crossover
int crossover(int gene, int DNA_length, int A, int B)
{if (gene < (SPLICING*DNA_length)/100) return A; else return B;}
int main() {
std::vector<int> A, B, C;
A = { 3, 4, 8, 12, 2, 0, 9, 7, 10, 20 };
B = { 8, 10, 3, 4, 20, 0, 7, 9, 2, 12 };
int DNA_length = int(A.size());
for (int i=0; i<DNA_length; i++) {
C.push_back(crossover(i, DNA_length, A[i], B[i]));
if (i == DNA_length/2) std::cout << "| ";
std::cout << C[i] << " ";}
}
Output: 3 4 8 12 2 | 0 7 9 2 12
There are two collisions (2, 12).
My expected output is something like this: 3 4 8 12 2 | 0 7 9 10 20 (no collision, perfect shuffle of the original set).
Then, I need to encode the order of these values in order to avoid this kind of difficulties.
A naive way is to identify each value with a unique key. But the set then created is an ordinal one because it refers to the sequencing of the values.
I appears that the crossover function has to deal with the ordinality of the DNAs of the parents. But I can not wrap my head around the issue of mixing two nonlinearly ordered ordinal subsets (parents' DNA slices) of an ordinal set (whole DNA) without collision!
Maybe I can rely only on mutation for convergence. No selection, no parents/children, and only a swap function in the same set (individual's DNA). In short: not very convincing.
It is indeed easy to permute ordinal numbers in a unique finite set (e.g., trivially: the first becomes the seventh; the second, the tenth, etc.). But I am not sure if it makes sense to says that the first of set A becomes the seventh when the second of set B becomes the tenth of the new set.
Then, my question is:
In your opinion, can the ordinality of a set be shuffled using a crossover function in the context of a genetic algorithm? If no, can you suggest a metaheuristic approach more efficient for this purpose than a brute-force, hill climbing technique or genetic algorithm?
Thank you.