#include #include #include #include #include #include #include #include using namespace std; string input = ""; char includedCharacters[26]; char missingCharacters[26]; int default_left = 12; int default_right = 16; int num_characters = 0; int num_missing_characters = 0; int includedCharacterPositions[26]; int missingCharacterPositions[26]; int populationSize = 200; int geneticIterations = 4000; int mutation_rate = 100; int dist_matr[26][26]={0}; int keyX[26]={85,123,161,199,237,275,313,351,389,427,95,133,171,209,247,285,324,362,400,122,160,198,236,275,313,351}; int keyY[26]={140,140,140,140,140,140,140,140,140,140,179,179,179,179,179,179,179,179,179,219,219,219,219,219,219,219}; int n; int tournamentSize = 5; int myRandom(int x) { return rand()%x; } int sqr(int a) { return a*a; } void calculate_dist() { for (int i=0;i<26;i++) for(int j=0;j<26;j++) dist_matr[i][j] = (int) sqrt(sqr(keyX[i]-keyX[j]) + sqr(keyY[i]-keyY[j])); } void initialize() { bool* used = new bool[128]; for (int i='a';i<='z';i++) used[i] = false; for (int i=0;i7) { row2+=row3-7; row3=7; } if (row2>9) { row1+=row2-9; row2=9; } int k=0; int j=0; for(int i=0;ikeyboard = keyboard; this->left = left; this->right = right; } Solution(Solution* other) { left = other->left; right = other->right; keyboard = new char[26]; for (int i=0;i<26;++i) keyboard[i] = other->keyboard[i]; } ~Solution() { delete keyboard; } void mutate() { if (rand()%mutation_rate != 0) return; int pos1 = rand()%num_characters; int pos2 = rand()%num_characters; swap(keyboard[includedCharacterPositions[pos1]], keyboard[includedCharacterPositions[pos2]]); result_calculated = false; } int getResult() { if (result_calculated) return result; int* pos_map = new int[128]; for (int i=0;i<26;i++) pos_map[keyboard[i]] = i; if (dist_matr[default_left][pos_map[input[0]]] < dist_matr[default_right][pos_map[input[0]]]) { left = pos_map[input[0]]; right = default_right; } else { left = default_left; right = pos_map[input[0]]; } int cur_left = left, cur_right = right; result = 0; for (int i=0;i= keyX[cur_right]) { result += dist_matr[cur_right][pos_map[input[i]]]; cur_right = pos_map[input[i]]; continue; } if(dist_matr[cur_left][pos_map[input[i]]] <= dist_matr[cur_left][pos_map[input[i]]]) { result += dist_matr[cur_left][pos_map[input[i]]]; cur_left = pos_map[input[i]]; continue; } result += dist_matr[cur_right][pos_map[input[i]]]; cur_right = pos_map[input[i]]; continue; } delete pos_map; result_calculated = true; return result; } }; class Population { public: vector solutions; Population(bool initialize) { if (initialize) { for (int i=0;i newPopulation; newPopulation.push_back(new Solution(getFittest())); for(int i=1;imutate(); newPopulation.push_back(child); } for(int i=0;i endPos) swap(startPos, endPos); char* keyboard = new char[26]; bool* used = new bool[128]; for (int i='a';i<='z';i++) used[i] = false; for (int i=startPos;ikeyboard[includedCharacterPositions[i]]; used[keyboard[includedCharacterPositions[i]]] = true; } int k=0; for (int i=0;ikeyboard[includedCharacterPositions[k]]]) ++k; keyboard[includedCharacterPositions[i]] = parent2->keyboard[includedCharacterPositions[k]]; ++k; } for (int i=endPos;ikeyboard[includedCharacterPositions[k]]]) ++k; keyboard[includedCharacterPositions[i]] = parent2->keyboard[includedCharacterPositions[k]]; ++k; } for (int i=0;igetResult() < winner->getResult()) winner = next; } return winner; } Solution* tournamentSelection() { Solution* winner = solutions[rand()%populationSize]; for (int i=1;igetResult() < winner->getResult()) winner = next; } return winner; } }; int main() { srand(42); calculate_dist(); ifstream fin; fin.open("keyboard.in"); fin >> n; fin >> input; fin.close(); initialize(); geneticIterations = 4000/max(1,n/50); Population* pop = new Population(true); for (int i=0;ievolve(); Solution* solution = pop->getFittest(); cout << solution->getResult(); ofstream fout; fout.open("keyboard.out"); for (int i=0;i<26;i++) fout << solution->keyboard[i]; fout << endl << solution->left+1 << " " << solution->right+1; fout.close(); return 0; }