package abstrasy.pcfx;
import abstrasy.Node;
import abstrasy.interpreter.InterpreterException;
import abstrasy.interpreter.StdErrors;
/**
* Abstrasy Interpreter
*
* Copyright : Copyright (c) 2006-2012, Luc Bruninx.
*
* Concédée sous licence EUPL, version 1.1 uniquement (la «Licence»).
*
* Vous ne pouvez utiliser la présente oeuvre que conformément à la Licence.
* Vous pouvez obtenir une copie de la Licence à l’adresse suivante:
*
* http://www.osor.eu/eupl
*
* Sauf obligation légale ou contractuelle écrite, le logiciel distribué sous
* la Licence est distribué "en l’état", SANS GARANTIES OU CONDITIONS QUELLES
* QU’ELLES SOIENT, expresses ou implicites.
*
* Consultez la Licence pour les autorisations et les restrictions
* linguistiques spécifiques relevant de la Licence.
*
*
* @author Luc Bruninx
* @version 1.0
*/
public class PCFx_crossover_cx extends PCFx {
/*****
* Implémente nativement l'algorithme 'cycle crossover' du script suivant:
* =======================================================================
*
#
# crossover-cx 'Cycle crossover'
#
(define 'p1 [1 2 3 4 5 6 7 8 9])
(define 'p2 [4 1 2 8 7 6 9 3 5])
(define 'o1 (list (length p1)))
(define 'tp1 (,p1))
(define 'tp2 (,p2))
(define 'j 0)
(while{<? j (length tp1)} do{
(define 'i (,j))
(if{nothing? (@o1 i)} then{
(while{nothing? (@o1 i)} do{
(set! (@o1 i) (@tp1 i))
(set! i (@(find (@tp2 i) in tp1) 0))
})
(swap! tp1 tp2)
})
(incr! j)
})
(define 'o2 (list (length p1)))
(define 'tp1 (,p1))
(define 'tp2 (,p2))
(define 'j 0)
(while{<? j (length tp1)} do{
(define 'i (,j))
(if{nothing? (@o2 i)} then{
(while{nothing? (@o2 i)} do{
(set! (@o2 i) (@tp2 i))
(set! i (@(find (@tp1 i) in tp2) 0))
})
(swap! tp1 tp2)
})
(incr! j)
})
(display "p1 = " p1)
(display "p2 = " p2)
(display)
(display "o1 = " o1)
(display "o2 = " o2)
=>
p1 = [1 2 3 4 5 6 7 8 9]
p2 = [4 1 2 8 7 6 9 3 5]
o1 = [1 2 3 4 7 6 9 8 5]
o2 = [4 1 2 8 5 6 7 3 9]
Ready...
*
* On obtient 4 nouveaux chromozomes (2 fils et les 2 parents).
*
*****/
public PCFx_crossover_cx() {
}
private final static boolean isIn(Node a, Node liste) throws Exception{
for(int i=0;i<liste.size();i++){
if(Node.equalsNodes(a,liste.elementAt(i))){
return true;
}
}
return false;
}
private final static int getPos(Node a, Node liste) throws Exception{
for(int i=0;i<liste.size();i++){
if(Node.equalsNodes(a,liste.elementAt(i))){
return i;
}
}
return -1;
}
/**
* eval
*
* @param startAt Node
* @return Node
* @throws Exception
* @todo Implémenter cette méthode abstrasy.PCFx
*/
public Node eval(Node startAt) throws Exception {
/*
* forme: (crossover-cx [liste1] [liste2])
*/
startAt.isGoodArgsCnt(3);
Node p1 = startAt.getSubNode(1, Node.TYPE_CLIST);
Node p2 = startAt.getSubNode(2, Node.TYPE_CLIST);
if(p1.size()!=p2.size()){
throw new InterpreterException(StdErrors.extend(StdErrors.List_size_mismatch,"(<>? "+p1.size()+" "+p2.size()+")"));
}
Node nothing = Node.createNothing();
// sécuriser la finalité des sources
Node t = Node.createCList();
for(int i=0;i<p1.size();i++){
t.addElement(p1.elementAt(i));
}
p1=t;
t = Node.createCList();
for(int i=0;i<p2.size();i++){
t.addElement(p2.elementAt(i));
}
p2=t;
Node o1 = Node.createCList();
for(int i=0;i<p1.size();i++){
o1.addElement(nothing);
}
Node tp1 = p1;
Node tp2 = p2;
int j = 0;
while(j<tp1.size()){
int i=j;
if(o1.elementAt(i)==nothing){
while(i>=0 && o1.elementAt(i)==nothing){
o1.setElementAt(tp1.elementAt(i), i);
i=getPos(tp2.elementAt(i),tp1);
}
Node tmp=tp1;
tp1=tp2;
tp2=tmp;
}
j++;
}
Node o2 = Node.createCList();
for(int i=0;i<p1.size();i++){
o2.addElement(nothing);
}
tp1 = p1;
tp2 = p2;
j = 0;
while(j<tp1.size()){
int i=j;
if(o2.elementAt(i)==nothing){
while(i>=0 && o2.elementAt(i)==nothing){
o2.setElementAt(tp2.elementAt(i), i);
i=getPos(tp1.elementAt(i),tp2);
}
Node tmp=tp1;
tp1=tp2;
tp2=tmp;
}
j++;
}
Node o3 = Node.createCList();
for(int i=0;i<p1.size();i++){
o3.addElement(p1.elementAt(i));
}
Node o4 = Node.createCList();
for(int i=0;i<p1.size();i++){
o4.addElement(p2.elementAt(i));
}
// ne pas oublier de sécuriser (à l'aide de select)...
return Node.createCList()
.append(o1.select(0, o1.size()))
.append(o2.select(0, o2.size()))
.append(o3.select(0, o3.size()))
.append(o4.select(0, o4.size()));
}
}