

BeginPackage["GeneticOperators`"]

DiagonalCrossover::usage=""
NPointCrossover::usage=""
UniformCrossover::usage=""

RouletteWheelSelection::usage=""
TurnajovaSelekce::usage=""

Mutation::usage=""

Inversion::usage="Inversion[string] vraci bitovou inverzi retezce."
CreateVariable::usage=""

Begin["Private`"];

CreateVariable[n_] := Module[{start},
  start = ToCharacterCode["a"];
  StringJoin["a", FromCharacterCode[start + n]]
];



(***************************************************
 * Recombination                                   *
 ***************************************************)

Clear[DiagonalCrossover];
DiagonalCrossover[ parents_ ] := Module[{NumberOfParents, CutPositionsArray, SplittedParents},
  If [Global`debugMode, Print["DiagonalCrossover ", parents]];
  NumberOfParents=Length[parents];
  If[NumberOfParents<2, Return[parents];];

  CutPositionsArray=RandomPositionsSelection[NumberOfParents-1, Length[parents[[1]]]-1];
  SplittedParents=Table[SplitString[parents[[i1]], CutPositionsArray], {i1, 1, NumberOfParents}];

  Table[
      Flatten[ Table[
      If[(i2+i3-1)>NumberOfParents,
        SplittedParents[[(i2+i3-1)-NumberOfParents, i3]],
        SplittedParents[[i2+i3-1, i3]]]
      ,
        {i3,1,NumberOfParents}
      ]],
    {i2, 1, NumberOfParents}
  ]
];


Clear[NPointCrossover];
NPointCrossover[ parents_, NumberOfCrossoverPoints_ ] := Module[{CutPositionsArray, SplittedParents, idx},
  If [Global`debugMode, Print["NPointCrossover ", parents, NumberOfCrossoverPoints]];
  If [ Length[parents]!= 2, Throw["NPointCrossover::spatny pocet rodicu"]];
  CutPositionsArray=RandomPositionsSelection[NumberOfCrossoverPoints, Length[parents[[1]]]-1];
  SplittedParents=Table[SplitString[parents[[idx]], CutPositionsArray], {idx, 1, 2}];

  {Flatten[Table[
    If[OddQ[i2], SplittedParents[[1, idx]], SplittedParents[[2, idx]]],
    {idx, 1, NumberOfCrossoverPoints+1}]],
   Flatten[Table[
    If[EvenQ[idx], SplittedParents[[1, idx]], SplittedParents[[2, idx]]],
    {idx, 1, NumberOfCrossoverPoints+1}]]}
  ];

Clear[UniformCrossover];
UniformCrossover[ parents_ ] := Module[{idx, uniform, potomek1, potomek2},
  If [Global`debugMode, Print["UniformCrossover ", parents]];

  If [ Length[parents]!= 2, Throw["UniformCrossover::spatny pocet rodicu"]];

  uniform = Table[If[OddQ[Random[Integer, {1, 10}]], 0, 1], {idx, 1,Length[parents[[1]]]}];

  potomek1 = {}; potomek2 = {};
  Table[
    If[uniform[[i]] == 0,
      AppendTo[potomek1, parents[[1,i]]]; AppendTo[potomek2, parents[[2,i]]];
      ,
      AppendTo[potomek1, parents[[2,i]]]; AppendTo[potomek2, parents[[1,i]]];
      ]
      , {i, 1, Length[parents[[1]]]}];
      {potomek1, potomek2}
];



(***************************************************
 * Selection                                       *
 ***************************************************)


Clear[RouletteWheelSelection];
RouletteWheelSelection[gen_] :=
Module[{ruleta, temp, jmin, jmax, suma = 0.0, nahodne, tempsum, ix, i},
       (* vytvor ruletu *)
       jmax = Last[NajdiMaximum[gen]];
       ruleta = Table[jmax - Last[gen[[i]]], {i, 1, Length[gen]}];
       Do[suma += ruleta[[i]], {i, 1, Length[ruleta]}];
       Table[
          tempsum = 0.0;
          ix = -1;
          nahodne = Random[Real, {0.0, suma}];
          Do[tempsum += ruleta[[i]];
             If[tempsum > nahodne, ix = i; Break[]], {i, 1, Length[ruleta]}];
          If[ix == -1, Print["nahodne=", nahodne, "  suma=", suma];
             Throw["renonc"]];
          gen[[ix]]
          , {Length[gen]}]
];

Clear[TournamentSelection];
TournamentSelection[gen_, Tour_] := Module[{},
  If[Tour<2 || Tour>Length[gen],Throw["TournamentSelection::pocet jedincu je vetsi nez populace"];]

];

Clear[TurnajovaSelekce];
TurnajovaSelekce[gen_] := Module[{vel, i1, i2},
                              vel = Length[gen];
                              Table[
                                    i1 = Random[Integer, {1, vel}];
                                    i2 = Random[Integer, {1, vel}];
                                    If[Last[gen[[i1]]] < Last[gen[[i2]]], gen[[i1]], gen[[i2]]],
                              {vel}]
];


Clear[Mutation];
Mutation[ string_ ] := Module[{idx},
  If [Global`debugMode, Print["Mutation ", string]];
  Table[
    If[ Random[] < Global`pravdepodobnostMutace,
      1 - string[[idx]],
      string[[idx]]]
   , {idx, 1, Length[string]}]
];

(***************************************************
 * Advanced                                        *
 ***************************************************)

Clear[Inversion];
Inversion[ string_ ] := Module[{i}, Table[ 1 - string[[i]], {i, 1, Length[string]}]];

End[ ]
EndPackage[ ]

