/*
* Copyright (c) 2010 Mathew Hall, University of Sheffield.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the University of Sheffield nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
package search.genes;
import static gpinterpreter.vector.VecSymbol.MOVE;
import static gpinterpreter.vector.VecSymbol.NOP;
import gpinterpreter.GPParser;
import gpinterpreter.vector.VecInstruction;
import gpinterpreter.vector.VecSymbol;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jgap.BaseGene;
import org.jgap.Configuration;
import org.jgap.Gene;
import org.jgap.InvalidConfigurationException;
import org.jgap.RandomGenerator;
import org.jgap.UnsupportedRepresentationException;
public class SymbolInstructionGene extends BaseGene implements InstructionGene {
public int graphSize;
private static VecSymbol[] symbols = {MOVE, /* SPLIT, */ NOP // ,MERGE
};
// TODO: profile this with and without SPLIT - why is split so cheap?
public void setGraphSize(int s) {
graphSize = s;
}
public int getGraphSize() {
return graphSize;
}
public InstructionGene clone() {
SymbolInstructionGene sg;
try {
sg = new SymbolInstructionGene(this.getConfiguration(), inst.clone(), graphSize);
} catch (InvalidConfigurationException ex) {
Logger.getLogger(SymbolInstructionGene.class.getName()).log(Level.SEVERE, null, ex);
throw new RuntimeException("Attempt to clone SymbolInstructionGene failed");
}
return sg;
}
private static final long serialVersionUID = 1L;
private VecInstruction inst;
public SymbolInstructionGene() throws InvalidConfigurationException {
this(null);
}
public SymbolInstructionGene(Configuration aConfiguration)
throws InvalidConfigurationException {
super(aConfiguration);
inst = new VecInstruction(NOP);
}
public SymbolInstructionGene(Configuration aConfiguration, int gs)
throws InvalidConfigurationException {
super(aConfiguration);
inst = new VecInstruction(NOP);
graphSize = gs;
}
public SymbolInstructionGene(Configuration aConfiguration, VecInstruction i)
throws InvalidConfigurationException {
super(aConfiguration);
inst = i.clone();
}
public SymbolInstructionGene(Configuration aConfiguration, VecInstruction i,
int gs) throws InvalidConfigurationException {
super(aConfiguration);
inst = i.clone();
graphSize = gs;
}
@Override
protected Object getInternalValue() {
if (inst == null) {
return inst;
}
return inst.clone();
}
@Override
protected Gene newGeneInternal() {
try {
return new SymbolInstructionGene(getConfiguration(), inst,
graphSize);
} catch (InvalidConfigurationException e) {
throw new IllegalStateException(e.getMessage());
}
}
@Override
public void applyMutation(int index, double percentage) {
VecInstruction toMutate = inst;
double pc = percentage;
percentage = Math.abs(percentage);
if (index % 3 == 0) {
toMutate.setOperand1((int) (Math.abs(toMutate.getOperand1()
+ (pc * graphSize))));
} else if (index % 3 == 1) {
toMutate.setOperand2((int) (Math.abs(toMutate.getOperand2()
+ (pc * graphSize))));
} else {
double places = (symbols.length - 1) * percentage;
switch (toMutate.getType()) {
case NOP:
places++;
//case MERGE:
// places++;
//case SPLIT:
// places++;
}
places = Math.round(places) % (symbols.length);
toMutate.setType(symbols[(int) places]);
}
if (toMutate.getOperand1() == toMutate.getOperand2()) {
toMutate.setOperand1(toMutate.getOperand1() + 1);
}
if (toMutate.getOperand1() <= 0) {
toMutate.setOperand1(1);
}
if (toMutate.getOperand2() <= 0) {
toMutate.setOperand2(1);
}
if (toMutate.getOperand1() > graphSize) {
toMutate.setOperand1((int) (toMutate.getOperand1() % (double) graphSize));
}
if (toMutate.getOperand2() > graphSize) {
toMutate.setOperand2((int) (toMutate.getOperand2() % (double) graphSize));
}
}
@Override
public String getPersistentRepresentation()
throws UnsupportedOperationException {
return inst.toString();
}
@Override
public void setAllele(Object arg0) {
inst = ((VecInstruction) arg0).clone();
}
@Override
public void setToRandomValue(RandomGenerator arg0) {
double randDouble = arg0.nextDouble();
randDouble = Math.abs(randDouble);
double places = (symbols.length - 1) * arg0.nextDouble();
places = Math.abs(Math.round(places) % (symbols.length));
if (graphSize < 1) {
Logger.getLogger(SymbolInstructionGene.class.getName()).log(Level.WARNING, "Tried to set a gene to a random value with 0 graph size!");
}
inst = new VecInstruction(symbols[(int) places], arg0.nextInt(graphSize) + 1, arg0.nextInt(graphSize) + 1);
VecInstruction lastInst = inst;
if (lastInst.getOperand1() <= 0) {
lastInst.setOperand1(1);
}
if (lastInst.getOperand2() <= 0) {
lastInst.setOperand2(1);
}
if (lastInst.getOperand3() <= 0) {
lastInst.setOperand3(1);
}
}
@Override
public void setValueFromPersistentRepresentation(String arg0)
throws UnsupportedOperationException,
UnsupportedRepresentationException {
// need to read graphSize here
try {
List<VecInstruction> program = GPParser.parse(arg0);
inst = program.get(0);
} catch (Exception e) {
throw new UnsupportedOperationException(
"Parse error on persistent representation");
}
}
@Override
public int compareTo(Object o) {
if (o == null) {
return 1;
}
if (inst == null) {
if (((SymbolInstructionGene) o).getAllele() == null) {
return 0;
} else {
return -1;
}
}
VecInstruction p2 = (VecInstruction) ((SymbolInstructionGene) o).getAllele();
if (p2 != inst) {
// do something
if (p2.getType() == NOP && inst.getType() != NOP) {
return 1;
}
if (inst.getType() == NOP && p2.getType() != NOP) {
return -1;
}
}
return 0;
}
public int hashCode() {
return inst.hashCode();
}
@Override
public VecInstruction getInstruction() {
return inst;
}
}