public Pair<Node,Node> crossover(Node individualA,Node individualB){
  boolean isGood=false;
  Node newIndividualA=null;
  Node newIndividualB=null;
  for (int tries=0; tries < 20; tries++) {
    newIndividualA=individualA.cloneTree();
    newIndividualB=individualB.cloneTree();
    Node randomNodeA=pickRandomNode(newIndividualA);
    Node randomNodeB=pickRandomNode(newIndividualB);
    if (randomNodeA != null && randomNodeB != null) {
      Node aParent=randomNodeA.getParent();
      List<Node> aChilds=aParent.getChildrens();
      int aIndex=aChilds.indexOf(randomNodeA);
      Node bParent=randomNodeB.getParent();
      List<Node> bChilds=bParent.getChildrens();
      int bIndex=bChilds.indexOf(randomNodeB);
      aChilds.set(aIndex,randomNodeB);
      bChilds.set(bIndex,randomNodeA);
      randomNodeA.setParent(bParent);
      randomNodeB.setParent(aParent);
      if (checkMaxDepth(newIndividualA,1) && checkMaxDepth(newIndividualB,1) && newIndividualA.isValid()&& newIndividualB.isValid()) {
        isGood=true;
        break;
      }
    }
  }
  if (isGood) {
    return new Pair<Node,Node>(newIndividualA,newIndividualB);
  }
 else {
    return null;
  }
}

public Pair < Node , Node > crossover ( Node individualA , Node individualB ) { boolean isGood = false ; Node newIndividualA = null ; Node newIndividualB = null ; for ( int tries = 0 ; tries < 20 ; tries ++ ) { newIndividualA = individualA . cloneTree ( ) ; newIndividualB = individualB . cloneTree ( ) ; Node randomNodeA = pickRandomNode ( newIndividualA ) ; Node randomNodeB = pickRandomNode ( newIndividualB ) ; if ( randomNodeA != null && randomNodeB != null ) { Node aParent = randomNodeA . getParent ( ) ; List < Node > aChilds = aParent . getChildrens ( ) ; int aIndex = aChilds . indexOf ( randomNodeA ) ; Node bParent = randomNodeB . getParent ( ) ; List < Node > bChilds = bParent . getChildrens ( ) ; int bIndex = bChilds . indexOf ( randomNodeB ) ; aChilds . set ( aIndex , randomNodeB ) ; bChilds . set ( bIndex , randomNodeA ) ; randomNodeA . setParent ( bParent ) ; randomNodeB . setParent ( aParent ) ; if ( checkMaxDepth ( newIndividualA , 1 ) && checkMaxDepth ( newIndividualB , 1 ) && newIndividualA . isValid ( ) && newIndividualB . isValid ( ) ) { isGood = true ; break ; } } } if ( isGood ) { return new Pair < Node , Node > ( newIndividualA , newIndividualB ) ; } else { return null ; } }
this method performs the crossover operation on two individuals
