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_mutate_random extends PCFx {
/*****
* Implémente nativement l'algorithme 'random mutate' du script suivant:
* =====================================================================
*
(function 'mutate-random{(args 'liste 'd 'f)
(assert{>=? (- (max d f) (min d f)) 2})
(define 'lh (select liste 0 d))
(define 'lm (select liste d (- f d)))
(define 'lt (select liste f (- (length liste) f)))
(define 'lpm [])
(define 'lm2 (;lm))
(while{lm2} do{
(define 'k (round (random (- (length lm2) 1) ) ))
(define 'c (@lm2 k))
(define 'o (length (find c in lm)))
(define 'cp (@lm (length lpm)))
(if{<>? o 1} then{
(append! (@lm2 k) to lpm)
(remove! k from lm2)
}
else{
(if{=? c cp} then{
(merge! lm2 lpm)
(set! lpm [])
}
else{
(append! (@lm2 k) to lpm)
(remove! k from lm2)
})
})
})
(return (merge lh lpm lt))
})
(define 's [1 2 3 4 5 6 7 8 9])
(display "s = " s)
(display "p : " (mutate-random s 2 7))
=>
s = [1 2 3 4 5 6 7 8 9]
p : [1 2 4 6 7 5 3 8 9]
Ready...
*
* On un nouveau génomes dans lequel la section délimitée a été permutée aléatoirement de façon sûr.
*
*****/
public PCFx_mutate_random() {
}
private final static boolean isIn(Node a, Node liste) throws Exception{
for(int i=0;i<liste.size();)
if(Node.equalsNodes(a,liste.elementAt(i++)))
return true;
return false;
}
/**
* eval
*
* @param startAt Node
* @return Node
* @throws Exception
* @todo Implémenter cette méthode abstrasy.PCFx
*/
public Node eval(Node startAt) throws Exception {
/*
* formes: (mutate-random [liste] debut longueur)
* (mutate-random [liste] debut)
* (mutate-random [liste])
*
*/
Node s=null;
int d=-1;
int f=-1;
switch(startAt.size()){
case 4:
f=(int)startAt.getSubNode(3, Node.TYPE_NUMBER).getNumber();
d=(int)startAt.getSubNode(2, Node.TYPE_NUMBER).getNumber();
s=startAt.getSubNode(1, Node.TYPE_CLIST);
break;
case 3:
d=(int)startAt.getSubNode(2, Node.TYPE_NUMBER).getNumber();
s=startAt.getSubNode(1, Node.TYPE_CLIST);
f=s.size();
break;
case 2:
d=0;
s=startAt.getSubNode(1, Node.TYPE_CLIST);
f=s.size();
break;
default:
startAt.isGoodArgsCnt(4);
}
if(f<2 || ( s!=null && (d<0 || (d+f)>s.size()))){
throw new InterpreterException(StdErrors.Out_of_range);
}
Node lh = Node.createCList();
for(int i=0;i<d;i++){
lh.addElement(s.elementAt(i));
}
Node lm = Node.createCList();
for(int i=d;i<(d+f);i++){
lm.addElement(s.elementAt(i));
}
Node lt = Node.createCList();
for(int i=(d+f);i<s.size();i++){
lt.addElement(s.elementAt(i));
}
Node lpm = Node.createCList();
Node lm2 = lm.select(0,lm.size()); // copie securisée profonde de lm.
while(lm2.size()>0){
int k = (int)Math.round(Math.random()*(lm2.size()-1));
Node c = lm2.elementAt(k);
int o = 0;
for(int i=0;i<lm.size();i++){
if(Node.equalsNodes(c, lm.elementAt(i))) o++;
}
Node cp = lm.elementAt(lpm.size());
if(o!=1){
lpm.addElement(c);
lm2.removeElementAt(k);
}
else{
if(Node.equalsNodes(c, cp)){
for(int i=0;i<lpm.size();i++){
lm2.addElement(lpm.elementAt(i));
}
lpm = Node.createCList();
}
else{
lpm.addElement(c);
lm2.removeElementAt(k);
}
}
}
for(int i=0;i<lpm.size();i++) lh.addElement(lpm.elementAt(i));
for(int i=0;i<lt.size();i++) lh.addElement(lt.elementAt(i));
return lh.select(0, lh.size());
}
}