Toad/Tree Code
< Toad
Jump to navigation
Jump to search
- Toad Sub-pages:
- Toad - Version History - Segmentation Tree - Tree Code - Movement - RRGC
This is the code used in Toad RRGC 1.1
package florent;
import java.io.File;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Vector;
import robocode.AdvancedRobot;
import robocode.Condition;
import robocode.RobocodeFileOutputStream;
//TODO add a thread dedicated to add leaves
public class SegmentationTree implements Serializable,Runnable{
//TODO try segmentation on distance traveled in the last 15,30 ticks
/**
*
*/
private static final long serialVersionUID = 2503026896538361157L;
private static final boolean RUMBLE = Toad.RUMBLE;
private boolean saveToFile = false, showSegementation = false;
private int completeRebuildRound = 7;
private int GF_ZERO;
private int GF_ONE;
private double[] ALL_ACCEL = {Double.NEGATIVE_INFINITY,-1.5,-.5,0,.5,Double.POSITIVE_INFINITY};//-1.5,0,.5 vs FloodMini & PulsarMAX
private double[] ALL_DISTANCE = {Double.NEGATIVE_INFINITY,100,150,200,250,300,350,400,450,500,550,600,650,Double.POSITIVE_INFINITY};
private double[] ALL_POWER = {Double.NEGATIVE_INFINITY,.5,1,1.5,2,2.5,Double.POSITIVE_INFINITY};
private double[] ALL_TIME = {Double.NEGATIVE_INFINITY,.1,.15,.25,.3,.45,.55,.65,.7,.9,1.1,Double.POSITIVE_INFINITY};
private double[] ALL_VEL = {Double.NEGATIVE_INFINITY,1,1.5,2,2.5,3,3.5,4,4.5,5,5.5,6,6.5,7,7.5,Double.POSITIVE_INFINITY};
private double[] ALL_WALL = {Double.NEGATIVE_INFINITY,.15,.4,.8,.1,1.3,1.6,Double.POSITIVE_INFINITY};
private double[] ALL_WALL_REVERSE = {Double.NEGATIVE_INFINITY,.5,.75,1,1.45,Double.POSITIVE_INFINITY};//1.45 & 0.73 vs Quest
private double minAccel=.5,minVel=1.5,minLatvel = 1.5,minDistance=150,minPower=4,minWall=.15,minTime=.1,minWallReverse = .35;
private int threshold;
private boolean verbose = false;
private int rebuilding = 0;
private boolean start = false;
private boolean rebuild = true;
private Node root;
private int leaves = 0,weightedLeaves = 0;;
public AdvancedRobot me;
private boolean bufferingEntry = false;
private Vector buffer = new Vector();
private Thread rebuildThread,treeThread;
private boolean rebuildingInProcess = false,addingInProcess = false;
private WeightedVisitRecorder recorder = new WeightedVisitRecorder();
private boolean dynamicTree = true;
private boolean quitThread = false;
private double round;
private Segmentation seg;
public SegmentationTree(int gf0,int gf1, int threshold){
GF_ZERO = gf0;
GF_ONE = gf1;
this.threshold =threshold*5;
root = new NonPreTerminalNode();
root.nSeg=new NodeSegmentation();
}
public void init(){
quitThread=false;
round = me.getRoundNum();
treeThread = ((Toad)me).giveThread(this);//new Thread(this);
//System.out.println(treeThread.getThreadGroup());
treeThread.start();
treeThread.setPriority(Thread.MAX_PRIORITY);
}
public void setRoot(Node node){
System.out.println("Root changed");
root = node;
}
private int getRealThreshold(){
return threshold;
}
public void newEntry(double d, double e, double f, double g, double h, double i, double j, double k, double wallReverse, boolean vb){
//System.out.println("newEntry");
//if (!vb){
leaves++;
weightedLeaves += vb ? 1 : 5;
//System.out.println("add new leaf " + leaves);
Leaf leaf = new Leaf(d,e,f,g,h,i,j,k,wallReverse);
leaf.weigth = vb ? 1 : 5;
buffer.add(leaf);
treeThread.setPriority(Thread.MAX_PRIORITY);
/* //root.accept(new TreeAddVisitor(leaf));
if (!bufferingEntry){
TreeAddVisitor v =new TreeAddVisitor(leaf);
v.test();
// Thread p = new Thread(v);
// p.start();
// me.addCustomEvent(v);
//}
} else {
buffer.add(leaf);
}*/
}
public void run(){
quitThread=false;
if (!RUMBLE)
System.out.println("Tree started");
while(!quitThread){
if(!rebuildingInProcess){
if (buffer.size()>0){
// System.out.println(buffer.size());
Leaf leaf = (Leaf)buffer.get(0);
buffer.remove(leaf);
TreeAddVisitor v = new TreeAddVisitor(leaf);
addingInProcess = true;
v.test();
addingInProcess = false;
} else
treeThread.setPriority(Thread.MIN_PRIORITY);
}
}
}
public int getPeak(double d, double e, double f, double g, double h, double i, double j, double k, double wallReverse){
Leaf leaf = new Leaf(d,e,f,g,h,i,j,k,wallReverse);
return getPeak(leaf);
}
public int getPeak(Leaf leaf){
if (leaves == 0) return GF_ZERO;
TreePeakVisitor peak = new TreePeakVisitor(leaf);
root.accept(peak);
return peak.getPeak();
}
public void clean(){
TreeCleanerVisitor v = new TreeCleanerVisitor();
root.accept(v);
if (!RUMBLE) System.out.println("NPTN:"+v.nptn+"|PTN:"+v.ptn);
}
public void populate(){
TreeVisitor v = new TreePopulatorVisitor();
root.accept(v);
}
public void rebuild(){
if (!rebuild)
return;
//root.accept(new TreeRebuildVisitor());
bufferingEntry = true;
TreeRebuildVisitor visitor = new TreeRebuildVisitor();
rebuildThread = new Thread(visitor);
while(addingInProcess){};
rebuildThread.start();
rebuildThread.setPriority(Thread.MAX_PRIORITY);
//me.addCustomEvent(visitor);
//visitor.priority=50;
}
public void endRound(){
quitThread=true;
if (!RUMBLE)
System.out.println(buffer.size()+":"+rebuildingInProcess+":"+addingInProcess);
}
public void setRebuild(boolean rebuild) {
this.rebuild = rebuild;
}
public boolean isRebuilding(){
return ((rebuilding != 0)||start);
}
public Node save(){
root.accept(new TreeCleanerVisitor());
return root;
}
public SymbolicTree saveSymbolic(){
TreeSaveSymbolicVisitor v = new TreeSaveSymbolicVisitor();
root.accept(v);
return v.getTheNode();
}
public void restoreFromSymbolicTree (SymbolicTree sTree){
SymbolicTree.TreeRestoreSymbolicVisitor v = sTree.new TreeRestoreSymbolicVisitor(sTree,root,this);
Thread restoreThread = new Thread(v);
restoreThread.start();
}
public void restore(Node node){
node.accept(new TreePopulatorVisitor());
root = node;
}
public NonPreTerminalNode getNode(int code){
int offset = 0;
if (code == -1)
return new NonPreTerminalNode();
if (code<ALL_ACCEL.length)
return new AccelNode(ALL_ACCEL[code]);
offset+=ALL_ACCEL.length;
if (code<offset+ALL_DISTANCE.length)
return new DistanceNode(ALL_DISTANCE[code-offset]);
offset+=ALL_DISTANCE.length;
if (code<offset+ALL_VEL.length)
return new LatvelNode(ALL_VEL[code-offset]);
offset += ALL_VEL.length;
if (code<offset+ALL_POWER.length)
return new PowerNode(ALL_POWER[code-offset]);
offset+=ALL_POWER.length;
if (code<offset+ALL_TIME.length)
return new MoveTimeNode(ALL_TIME[code-offset]);
offset+=ALL_TIME.length;
if (code<offset+ALL_VEL.length)
return new VelNode(ALL_VEL[code-offset]);
offset+=ALL_VEL.length;
if (code<offset+ALL_WALL.length)
return new WallNode(ALL_WALL[code-offset]);
offset+=ALL_WALL.length;
if (code<offset+ALL_WALL_REVERSE.length)
return new WallReverseNode(ALL_WALL_REVERSE[code-offset]);
return null;
}
/**
* @return Returns the start.
*/
public boolean isStart() {
return start;
}
/**
* @param start The start to set.
*/
public void setStart(boolean start) {
this.start = start;
}
/**
* @param verbose The verbose to set.
*/
public void setVerbose(boolean verbose) {
this.verbose = verbose;
}
//tree structure
abstract class Node implements Serializable {
protected int count;
protected NodeSegmentation nSeg;
public void accept(TreeVisitor v){
count = 0;
}
/**
* @return Returns the count.
*/
public int getCount() {
return count;
}
/**
* @param count The count to set.
*/
public void setCount(int count) {
this.count = count;
};
}
/**
* we need a state pattern here
*/
public class NonPreTerminalNode extends Node{
/**
*
*/
private static final long serialVersionUID = 2511616405755008534L;
protected Node right,left;
protected ArrayList[] factors;
protected NonPreTerminalNode(){
factors = new ArrayList[GF_ONE+1];
for (int i=0;i<GF_ONE+1;i++)
factors[i]=new ArrayList();
if (rebuild){
left = new DynamicNode();
right = new DynamicNode();
left.nSeg=new NodeSegmentation();
right.nSeg=new NodeSegmentation();
} else {
left = new StaticNode();
right = new StaticNode();
}
}
public boolean goRight(Leaf leaf) {
return false;
}
/**
* @return Returns the left.
*/
public Node getLeft() {
return left;
}
/**
* @param left The left to set.
*/
public void setLeft(Node left) {
this.left = left;
}
/**
* @return Returns the right.
*/
public Node getRight() {
return right;
}
/**
* @param right The right to set.
*/
public void setRight(Node right) {
this.right = right;
}
/**
* precond right and left are PreTerminalNode
* @param list
*/
public void fillFactors(ArrayList[] list){
for (int k = 0; k<GF_ONE;k++){
Iterator it = list[k].listIterator();
while(it.hasNext()){
count++;
Leaf leaf = ((Leaf)it.next());
add(leaf);
if (goRight(leaf)){
((PreTerminalNode)right).add(leaf);
}
else
((PreTerminalNode)left).add(leaf);
}
}
}
public void add(Leaf leaf){
factors[(int) FUtils.bindToRange(Math.round((1d+leaf.gf)*GF_ZERO),0,GF_ONE)].add(leaf);
}
public ArrayList[] getLeaves(){
return factors;
}
/* (non-Javadoc)
* @see florent.segmentation.DynamicSegmentation.Node#accept(florent.segmentation.DynamicSegmentation.TreeVisitor)
*/
public void accept(TreeVisitor v) {
v.visitNPTN(this);
}
public int code(){
return -1;
}
public String toString(){
return "NonPreTerminal root";
}
}
class StaticNonPreTerminalNode extends NonPreTerminalNode{
private NonPreTerminalNode node;
private double[] factors = new double[GF_ONE+1];
public StaticNonPreTerminalNode(NonPreTerminalNode node){
this.node = node;
}
public void addLeaf(Leaf leaf){
recorder.setWeight(leaf.getWeigth());
recorder.registerVisit(leaf.getGf(),factors);
}
public void accept(TreeVisitor v) {
v.visitSNPTN(this);
v.visitNPTN(node);
}
public int code(){
return node.code();
}
}
class DistanceNode extends NonPreTerminalNode {
/**
*
*/
private static final long serialVersionUID = -3017031763049964074L;
protected double distance;
public DistanceNode(double distance){
this.distance= distance;
}
public boolean goRight(Leaf leaf){
return leaf.getDistance()>distance;
}
/**
* @return Returns the distance.
*/
public double getDistance() {
return distance;
}
public int code(){
return Arrays.binarySearch(ALL_DISTANCE,distance)+ALL_ACCEL.length;
}
public String toString(){
return "Distance:"+distance;
}
}
class AccelNode extends NonPreTerminalNode {
/**
*
*/
private static final long serialVersionUID = -5774124356484777243L;
protected double accel;
public AccelNode(double accel){
this.accel=accel;
}
public boolean goRight(Leaf leaf){
return leaf.getAccel()>accel;
}
public double getAccel(){
return accel;
}
public int code(){
return Arrays.binarySearch(ALL_ACCEL,accel);
}
public String toString(){
return "Acceleration:"+accel;
}
}
class VelNode extends NonPreTerminalNode {
/**
*
*/
private static final long serialVersionUID = 943213232679268372L;
protected double velocity;
public VelNode(double velocity){
this.velocity=velocity;
}
public boolean goRight(Leaf leaf){
return leaf.getVelocity()>velocity;
}
public double getVelocity(){
return velocity;
}
public int code(){
return Arrays.binarySearch(ALL_VEL,velocity)+ALL_ACCEL.length+ALL_DISTANCE.length+ALL_VEL.length+ALL_POWER.length+ALL_TIME.length;
}
public String toString(){
return "Velocity:"+velocity;
}
}
class LatvelNode extends NonPreTerminalNode {
/**
*
*/
private static final long serialVersionUID = 2699104696000932491L;
protected double latvel;
public LatvelNode(double latvel){
this.latvel=latvel;
}
public boolean goRight(Leaf leaf){
return leaf.getLatvel()>latvel;
}
public double getLatvel(){
return latvel;
}
public int code(){
return Arrays.binarySearch(ALL_VEL,latvel)+ALL_ACCEL.length+ALL_DISTANCE.length;
}
public String toString(){
return "Lateral Velocity:"+latvel;
}
}
class MoveTimeNode extends NonPreTerminalNode {
/**
*
*/
private static final long serialVersionUID = -403423486376627154L;
protected double move;
public MoveTimeNode(double move){
this.move=move;
}
public boolean goRight(Leaf leaf){
return leaf.getMoveTime()>move;
}
public double getMoveTime(){
return move;
}
public int code(){
return Arrays.binarySearch(ALL_TIME,move)+ALL_ACCEL.length+ALL_DISTANCE.length+ALL_VEL.length+ALL_POWER.length;
}
public String toString(){
return "Move Time:"+move;
}
}
class PowerNode extends NonPreTerminalNode {
/**
*
*/
private static final long serialVersionUID = -4244374812884848001L;
protected double power;
public PowerNode(double power){
this.power=power;
}
public boolean goRight(Leaf leaf){
return leaf.getFirePower()>power/50d;
}
public double getPower(){
return power;
}
public int code(){
return Arrays.binarySearch(ALL_POWER,power)+ALL_ACCEL.length+ALL_DISTANCE.length+ALL_VEL.length;
}
public String toString(){
return "Power:"+power;
}
}
class WallNode extends NonPreTerminalNode {
/**
*
*/
private static final long serialVersionUID = -2695158178698601457L;
protected double wall;
public WallNode(double wall){
this.wall= wall;
}
public boolean goRight(Leaf leaf){
return leaf.getWallIndex()>wall;
}
public double getWall(){
return wall;
}
public int code(){
return Arrays.binarySearch(ALL_WALL,wall)+ALL_ACCEL.length+ALL_DISTANCE.length+ALL_VEL.length+ALL_POWER.length+ALL_TIME.length+ALL_VEL.length;
}
public String toString(){
return "Wall:"+wall;
}
}
class WallReverseNode extends NonPreTerminalNode {
/**
*
*/
private static final long serialVersionUID = -2695158178698601457L;
protected double wall;
public WallReverseNode(double wall){
this.wall= wall;
}
public boolean goRight(Leaf leaf){
return leaf.getWallIndex()>wall;
}
public double getWall(){
return wall;
}
public int code(){
return Arrays.binarySearch(ALL_WALL_REVERSE,wall)+ALL_ACCEL.length+ALL_DISTANCE.length+ALL_VEL.length+ALL_POWER.length+ALL_TIME.length+ALL_VEL.length+ALL_WALL.length;
}
public String toString(){
return "Wall Reverse:"+wall;
}
}
abstract class PreTerminalNode extends Node{
/**
*
*/
protected Leaf leaf;
protected boolean done = false;
public boolean isDone(){
return done;
}
/**
* @param leaf The leaf to set.
*/
public void setLeaf(Leaf leaf) {
this.leaf = leaf;
}
public abstract void add(Leaf leaf);
public abstract int getPeak();
public void fillFactors(ArrayList[] list){
for (int k = 0; k<GF_ONE;k++){
Iterator it = list[k].listIterator();
while(it.hasNext()){
add((Leaf)it.next());
}
}
}
/* (non-Javadoc)
* @see florent.segmentation.DynamicSegmentation.Node#accept(florent.segmentation.DynamicSegmentation.TreeVisitor)
*/
public void accept(TreeVisitor v) {
v.visitPTN(this);
}
}
class StaticNode extends PreTerminalNode{
/**
*
*/
private static final long serialVersionUID = -8584356499226512475L;
private double[] factors;
public StaticNode(){
factors = new double[GF_ONE+1];
if (verbose) System.out.println("new static node");
}
public void add(Leaf leaf) {
recorder.setWeight(leaf.getWeigth());
recorder.registerVisit(leaf.getGf(),factors);
}
public int getPeak(){
int bestGF = (int)(GF_ZERO*(6d/5d));
double bestVal = 0;
int halfWidth = (int)Math.floor(Math.atan(18d/leaf.distance)*GF_ONE);
for (int gf = GF_ONE; gf > 0; gf--){
double tmp = 0;
// for (int i = Math.max(1, gf-halfWidth); i <= Math.min(gf+halfWidth, GF_ONE); i++){
tmp += factors[gf];
if (tmp > bestVal){
bestGF = gf;
bestVal = tmp;
}
// }
}
return bestGF;
}
}
class DynamicNode extends PreTerminalNode implements Runnable{
/**
*
*/
private static final long serialVersionUID = -3948835283424191222L;
/**
*
*/
private ArrayList[] factors;
private Leaf leaf;
private boolean done = false;
private boolean accelDone=false,velDone=false,latvelDone=false,distanceDone=false,powerDone=false,wallDone=false,moveDone=false,wallReverseDone=false;
private double minAccel1 = Double.POSITIVE_INFINITY,minVel1 = Double.POSITIVE_INFINITY, minLatvel1 = Double.POSITIVE_INFINITY, minDistance1 = Double.POSITIVE_INFINITY, minPower1 = Double.POSITIVE_INFINITY, minWall1 = Double.POSITIVE_INFINITY, minMove1 = Double.POSITIVE_INFINITY, minWallReverse1 = Double.POSITIVE_INFINITY;
private double maxAccel1 = Double.NEGATIVE_INFINITY,maxVel1 = Double.NEGATIVE_INFINITY, maxLatvel1 = Double.NEGATIVE_INFINITY, maxDistance1 = Double.NEGATIVE_INFINITY, maxPower1 = Double.NEGATIVE_INFINITY, maxWall1 = Double.NEGATIVE_INFINITY, maxMove1 = Double.NEGATIVE_INFINITY, maxWallReverse1 = Double.NEGATIVE_INFINITY;
public DynamicNode(){
factors = new ArrayList[GF_ONE+1];
for (int i=0;i<=GF_ONE;i++)
factors[i]=new ArrayList();
}
public DynamicNode(ArrayList[] factors){
this.factors = factors;
}
public boolean isDone(){
return done;
}
/**
* @param leaf The leaf to set.
*/
public void setLeaf(Leaf leaf) {
this.leaf = leaf;
}
/**
* @return Returns the factors.
*/
public ArrayList[] getFactors() {
return factors;
}
public void add(Leaf leaf){
//for (int i =0 ;i<leaf.weigth ;i++)
try{
factors[(int) FUtils.bindToRange((int)(FUtils.bindToRange(leaf.getGf(),-1,1)*GF_ZERO+GF_ZERO),0,GF_ONE)].add(leaf);
/* minAccel1 = Math.min(minAccel1,leaf.accel);
minVel1 = Math.min(minVel1,leaf.velocity);
minLatvel1 = Math.min(minLatvel1,leaf.latvel);
minDistance1 = Math.min(minDistance1,leaf.distance);
minWall1 = Math.min(minWall1,leaf.wallIndex);
minWallReverse1 = Math.min(minWallReverse1,leaf.wallReverse);
minMove1 = Math.min(minMove1,leaf.moveTime);
minPower1 = Math.min(minPower1,leaf.firePower);
maxAccel1 = Math.max(maxAccel1,leaf.accel);
maxVel1 = Math.max(maxVel1,leaf.velocity);
maxLatvel1 = Math.max(maxLatvel1,leaf.latvel);
maxDistance1 = Math.max(maxDistance1,leaf.distance);
maxWall1 = Math.max(maxWall1,leaf.wallIndex);
maxWallReverse1 = Math.max(maxWallReverse1,leaf.wallReverse);
maxMove1 = Math.max(maxMove1,leaf.moveTime);
maxPower1 = Math.max(maxPower1,leaf.firePower);*/
// System.out.println(minAccel1+"/"+maxAccel1+":"+minAccel+"|"+minVel1+"/"+maxVel1);
}catch(Exception e){
System.out.println("gf"+leaf.getGf()+"\n"+e);
}
}
public int getPeak(){
/* int idx = GF_ONE;
int val = 0;
int best = 0;
for (int i=GF_ONE;i>-1;i--){
val = 0;
if (i==GF_ONE) val = 2*factors[GF_ONE].size()+factors[GF_ONE-1].size();
else if (i==0) val = 2*factors[0].size()+factors[1].size();
else val=factors[i-1].size()+factors[i].size()+factors[i+1].size();
if (val>best){
idx = i;
best = val;
}
}
*/
int bestGF = (int)(GF_ZERO*(6d/5d));
double bestVal = 0;
int halfWidth = (int)Math.floor(Math.atan(18d/leaf.distance)*GF_ONE);
for (int gf = GF_ONE; gf > 0; gf--){
double tmp = 0;
// for (int i = Math.max(1, gf-halfWidth); i <= Math.min(gf+halfWidth, GF_ONE); i++){
tmp += factors[gf].size();
if (tmp > bestVal){
bestGF = gf;
bestVal = tmp;
}
// }
}
return bestGF;
}
public void run(){
split();
}
public NonPreTerminalNode split(){
rebuilding++;
start = false;
accelDone=velDone=latvelDone=powerDone=wallDone=moveDone=distanceDone=wallReverseDone = false;
/* accelDone = maxAccel1-minAccel1 < minAccel;
velDone = maxVel1- minVel1 > minVel;
latvelDone = maxLatvel1- minLatvel1 < minLatvel;
powerDone = maxPower1- minPower1 < minPower;
wallDone = maxWall1- minWall1 < minWall;
wallReverseDone = maxWallReverse1- minWallReverse1 < minWallReverse;
distanceDone = maxDistance1- minDistance1 < minDistance;
moveDone = maxMove1- minMove1 < minTime;
*/ if (accelDone&&velDone&&latvelDone&&powerDone&&wallDone&&moveDone&&distanceDone&&wallReverseDone)
return null;
ArrayList accelArray = accelDone ? null : new ArrayList() ;
ArrayList velArray = velDone ? null : new ArrayList();
ArrayList latvelArray = latvelDone ? null : new ArrayList();
ArrayList powerArray = powerDone ? null : new ArrayList();
ArrayList wallArray = wallDone ? null : new ArrayList();
ArrayList wallReverseArray = wallReverseDone ? null : new ArrayList();
ArrayList moveArray = moveDone ? null : new ArrayList();
ArrayList distanceArray = distanceDone ? null : new ArrayList();
// Iterator it;
for (int i=0;i<=GF_ONE;i++){
//it = factors[i].listIterator();
//while(it.hasNext()){
// Leaf leaf = (Leaf) it.next();
for (int j=0;j<factors[i].size();j++){
Leaf leaf = (Leaf)factors[i].get(j);
if (!accelDone) accelArray.add(new java.lang.Double(leaf.getAccel()));
if (!velDone) velArray.add(new java.lang.Double(leaf.getVelocity()));
if (!latvelDone) latvelArray.add(new java.lang.Double(leaf.getLatvel()));
if (!powerDone) powerArray.add(new java.lang.Double(leaf.getFirePower()));
if (!wallDone) wallArray.add(new java.lang.Double(leaf.getWallIndex()));
if (!wallReverseDone) wallReverseArray.add(new java.lang.Double(leaf.getWallReverse()));
if (!moveDone) moveArray.add(new java.lang.Double(leaf.getMoveTime()));
if (!distanceDone) distanceArray.add(new java.lang.Double(leaf.getDistance()));
}
}
if (!accelDone) Collections.sort(accelArray);
if (!velDone) Collections.sort(velArray);
if (!latvelDone) Collections.sort(latvelArray);
if (!powerDone) Collections.sort(powerArray);
if (!wallDone) Collections.sort(wallArray);
if (!wallReverseDone) Collections.sort(wallReverseArray);
if (!moveDone) Collections.sort(moveArray);
if (!distanceDone) Collections.sort(distanceArray);
//TODO add checks for minimum width of segmentation and an attribute to tell if the node can be split any further
accelDone = accelDone ? accelDone : Math.abs(((Double)accelArray.get(0)).doubleValue()-((Double)accelArray.get(accelArray.size()-1)).doubleValue())<minAccel;
latvelDone = latvelDone ? latvelDone : Math.abs(((Double)latvelArray.get(0)).doubleValue()-((Double)latvelArray.get(latvelArray.size()-1)).doubleValue())<minLatvel;
velDone = velDone ? velDone : Math.abs(((Double)velArray.get(0)).doubleValue()-((Double)velArray.get(velArray.size()-1)).doubleValue())<minVel;
distanceDone = distanceDone ? distanceDone : Math.abs(((Double)distanceArray.get(0)).doubleValue()-((Double)distanceArray.get(distanceArray.size()-1)).doubleValue())<minDistance;
powerDone = powerDone ? powerDone : Math.abs(((Double)powerArray.get(0)).doubleValue()-((Double)powerArray.get(powerArray.size()-1)).doubleValue())<minPower;
moveDone = moveDone ? moveDone : Math.abs(((Double)moveArray.get(0)).doubleValue()-((Double)moveArray.get(moveArray.size()-1)).doubleValue())<minTime;
wallDone = wallDone ? wallDone : Math.abs(((Double)wallArray.get(0)).doubleValue()-((Double)wallArray.get(wallArray.size()-1)).doubleValue())<minWall;
wallReverseDone = wallReverseDone ? wallReverseDone : Math.abs(((Double)wallReverseArray.get(0)).doubleValue()-((Double)wallReverseArray.get(wallReverseArray.size()-1)).doubleValue())<minWallReverse;
if (accelDone&&velDone&&latvelDone&&powerDone&&wallDone&&moveDone&&distanceDone&&wallReverseDone)
return null;
double accelMean =accelDone ? -1000 : FUtils.closestBorder(ALL_ACCEL,((java.lang.Double)(accelArray.get(accelArray.size()/2))).doubleValue());
double velMean =velDone ? -1000 :FUtils.closestBorder(ALL_VEL,((java.lang.Double)(velArray.get(velArray.size()/2))).doubleValue());
double latvelMean =latvelDone ? -1000 :FUtils.closestBorder(ALL_VEL,((java.lang.Double)(latvelArray.get(latvelArray.size()/2))).doubleValue());
double powerMean =powerDone ? -1000 :FUtils.closestBorder(ALL_POWER,((java.lang.Double)(powerArray.get(powerArray.size()/2))).doubleValue());
double wallMean =wallDone ? -1000 :FUtils.closestBorder(ALL_WALL,((java.lang.Double)(wallArray.get(wallArray.size()/2))).doubleValue());
double wallReverseMean =wallReverseDone ? -1000 :FUtils.closestBorder(ALL_WALL_REVERSE,((java.lang.Double)(wallReverseArray.get(wallReverseArray.size()/2))).doubleValue());
double moveMean =moveDone ? -1000 :FUtils.closestBorder(ALL_TIME,((java.lang.Double)(moveArray.get(moveArray.size()/2))).doubleValue());
double distanceMean =distanceDone ? -1000 :FUtils.closestBorder(ALL_DISTANCE,((java.lang.Double)(distanceArray.get(distanceArray.size()/2))).doubleValue());
AccelNode accelNode = accelDone ? null :new AccelNode(accelMean);
MoveTimeNode moveNode = moveDone ? null : new MoveTimeNode(moveMean);
VelNode velNode = velDone ? null : new VelNode(velMean);
LatvelNode latvelNode = latvelDone ? null : new LatvelNode(latvelMean);
PowerNode powerNode = powerDone ? null : new PowerNode(powerMean);
WallNode wallNode = wallDone ? null : new WallNode(wallMean);
WallReverseNode wallReverseNode = wallReverseDone ? null : new WallReverseNode(wallReverseMean);
DistanceNode distanceNode = distanceDone ? null : new DistanceNode(distanceMean);
if (!accelDone) accelNode.fillFactors(factors);
if (!moveDone) moveNode.fillFactors(factors);
if (!velDone) velNode.fillFactors(factors);
if (!latvelDone) latvelNode.fillFactors(factors);
if (!powerDone) powerNode.fillFactors(factors);
if (!wallDone) wallNode.fillFactors(factors);
if (!wallReverseDone) wallReverseNode.fillFactors(factors);
if (!distanceDone) distanceNode.fillFactors(factors);
double[] factorsCount = getFactorsCount();
double accel =accelDone || FUtils.isConstant(accelArray) ? 0 : getGain(accelNode,factorsCount);
double vel = velDone || FUtils.isConstant(velArray) ? 0 :getGain(velNode,factorsCount);
double latvel = latvelDone || FUtils.isConstant(latvelArray) ? 0 : getGain(latvelNode,factorsCount);
double dist = distanceDone || FUtils.isConstant(distanceArray) ? 0 : getGain(distanceNode,factorsCount);
double power = powerDone || FUtils.isConstant(powerArray) ? 0 : getGain(powerNode,factorsCount);
double move = moveDone || FUtils.isConstant(moveArray) ? 0 : getGain(moveNode,factorsCount);
double wall = wallDone || FUtils.isConstant(wallArray) ? 0 : getGain(wallNode,factorsCount);
double wallReverse = wallReverseDone || FUtils.isConstant(wallReverseArray) ? 0 : getGain(wallReverseNode,factorsCount);
NonPreTerminalNode best;// = new NonDynamicNode(maxAccel,maxDistance,maxFirePower,maxLatVel,maxMoveTime,maxVelocity,maxWallIndex,minAccel,minDistance,minFirePower,minLatVel,minMoveTime,minVelocity,minWallIndex);
if (verbose) System.out.print("Splitting on acceleration...");
best = accelNode;
if (best != null){
best.nSeg=new NodeSegmentation(nSeg);
best.nSeg.decisionValue=accelMean;
best.left.nSeg=new NodeSegmentation(nSeg);
best.right.nSeg=new NodeSegmentation(nSeg);
best.left.nSeg.highAcceleration=accelMean;
best.right.nSeg.lowAcceleration=accelMean;
}
double bestGain = accel;
if (vel>=bestGain || best == null){
if (verbose) System.out.print("NO/velocity...");
best=velNode;
bestGain = vel;
if (best != null){
best.nSeg=new NodeSegmentation(nSeg);
best.nSeg.decisionValue=velMean;
best.left.nSeg=new NodeSegmentation(nSeg);
best.right.nSeg=new NodeSegmentation(nSeg);
best.left.nSeg.highVelocity=velMean;
best.right.nSeg.lowVelocity=velMean;
}
}
if (latvel>=bestGain || best == null){
if (verbose) System.out.print("NO/lateral velocity...");
best=latvelNode;
bestGain = latvel;
if (best != null){
best.nSeg=new NodeSegmentation(nSeg);
best.nSeg.decisionValue=latvelMean;
best.left.nSeg=new NodeSegmentation(nSeg);
best.right.nSeg=new NodeSegmentation(nSeg);
best.left.nSeg.highLateralVelocity=latvelMean;
best.right.nSeg.lowLateralVelocity=latvelMean;
}
}
if (dist>=bestGain || best == null){
if (verbose) System.out.print("NO/distance...");
best=distanceNode;
bestGain = dist;
if (best != null){
best.nSeg=new NodeSegmentation(nSeg);
best.nSeg.decisionValue=distanceMean;
best.left.nSeg=new NodeSegmentation(nSeg);
best.right.nSeg=new NodeSegmentation(nSeg);
best.left.nSeg.highDistance=distanceMean;
best.right.nSeg.lowDistance=distanceMean;
}
}
if (power>=bestGain || best == null){
if (verbose) System.out.print("NO/fire power...");
best=powerNode;
bestGain = power;
if (best != null){
best.nSeg=new NodeSegmentation(nSeg);
best.nSeg.decisionValue=powerMean;
best.left.nSeg=new NodeSegmentation(nSeg);
best.right.nSeg=new NodeSegmentation(nSeg);
best.left.nSeg.highPower=powerMean;
best.right.nSeg.lowPower=powerMean;
}
}
if (move>=bestGain || best == null){
if (verbose) System.out.print("NO/move time...");
best=moveNode;
bestGain = move;
if (best != null){
best.nSeg=new NodeSegmentation(nSeg);
best.nSeg.decisionValue=moveMean;
best.left.nSeg=new NodeSegmentation(nSeg);
best.right.nSeg=new NodeSegmentation(nSeg);
best.left.nSeg.highTime=moveMean;
best.right.nSeg.lowTime=moveMean;
}
}
if (wall>=bestGain || best == null){
if (verbose) System.out.print("NO/wall...");
best=wallNode;
bestGain = wall;
if (best != null){
best.nSeg=new NodeSegmentation(nSeg);
best.nSeg.decisionValue=wallMean;
best.left.nSeg=new NodeSegmentation(nSeg);
best.right.nSeg=new NodeSegmentation(nSeg);
best.left.nSeg.highWall=wallMean;
best.right.nSeg.lowWall=wallMean;
}
}
if (wallReverse>=bestGain || best == null){
if (verbose) System.out.print("NO/wall reverse...");
best=wallReverseNode;
bestGain = wallReverse;
if (best != null){
best.nSeg=new NodeSegmentation(nSeg);
best.nSeg.decisionValue=wallReverseMean;
best.left.nSeg=new NodeSegmentation(nSeg);
best.right.nSeg=new NodeSegmentation(nSeg);
best.left.nSeg.highWallReverse=wallReverseMean;
best.right.nSeg.lowWallReverse=wallReverseMean;
}
}
if (verbose) System.out.println("YES");
if (bestGain == 0)
return null;
Node son;
try{
if (best.getRight().getCount()>getRealThreshold() && (son=((DynamicNode) best.getRight()).split()) != null)
best.setRight(son);
if (best.getLeft().getCount()>getRealThreshold() && (son=((DynamicNode) best.getLeft()).split())!=null)
best.setLeft(son);
} catch (Exception e){System.out.println(e+"\n"+bestGain+best+"\n"+accel+accelDone+accelNode+"\n"+vel+velDone+velNode+"\n"+latvel+latvelDone+latvelNode+"\n"+dist+distanceDone+distanceNode+"\n"+power+powerDone+powerNode+"\n"+wall+wallDone+wallNode+"\n"+move+moveDone+moveNode);}
rebuilding--;
return best;
}
/**
* precond node kids are DynamicNodes
* @param node
* @param factorsCount
* @return
*/
private double getGain(NonPreTerminalNode node,double[] factorsCount){
DynamicNode right,left;
right = (DynamicNode) node.getRight();
left = (DynamicNode) node.getLeft();
double[][] seg = new double[2][GF_ONE+1];
seg[0] = right.getFactorsCount();
seg[1] = left.getFactorsCount();
return FUtils.informationGain(factorsCount,seg);
}
public int getCount(){
double[] factorsCount = getFactorsCount();
int val = 0;
for (int i=0;i<GF_ONE+1;i++)
val += factorsCount[i];
return val;
}
public double[] getFactorsCount(){
double[] factorsCount= new double[GF_ONE+1];
for (int i=0;i<GF_ONE+1;i++){
factorsCount[i] = factors[i].size();
}
return factorsCount;
}
/* (non-Javadoc)
* @see florent.segmentation.DynamicSegmentation.Node#accept(florent.segmentation.DynamicSegmentation.TreeVisitor)
*/
public void accept(TreeVisitor v) {
v.visitPTN(this);
}
}
class Leaf implements Serializable{
/**
*
*/
private static final long serialVersionUID = 8764985023831432109L;
private double accel;
private double velocity;
private double latvel;
private double distance;
private double firePower;
private double wallIndex;
private double gf;
private double moveTime;
private double weigth;
private double wallReverse;
/**
* @param accel
* @param distance
* @param power
* @param gf
* @param latvel
* @param time
* @param velocity
* @param index
*/
public Leaf(double accel, double distance, double power, double gf, double latvel, double time, double velocity, double index, double wallReverse) {
this.accel = accel;
this.distance = distance;
firePower = power;
this.gf = gf;
this.latvel = Math.abs(latvel);
moveTime = time;
this.velocity = Math.abs(velocity);
wallIndex = index;
this.wallReverse=wallReverse;
}
/**
* @return Returns the accel.
*/
public double getAccel() {
return accel;
}
/**
* @return Returns the distance.
*/
public double getDistance() {
return distance;
}
/**
* @return Returns the firePower.
*/
public double getFirePower() {
return firePower;
}
/**
* @return Returns the latvel.
*/
public double getLatvel() {
return latvel;
}
/**
* @return Returns the velocity.
*/
public double getVelocity() {
return velocity;
}
/**
* @return Returns the wallIndex.
*/
public double getWallIndex() {
return wallIndex;
}
/**
* @return Returns the gf.
*/
public double getGf() {
return gf;
}
/**
* @return Returns the moveTime.
*/
public double getMoveTime() {
return moveTime;
}
public double getWeigth() {
return weigth;
}
public void setWeigth(double weigth) {
this.weigth = weigth;
}
public double getWallReverse() {
return wallReverse;
}
}
//visitor pattern for the tree
abstract class TreeVisitor extends Condition{
public void visitNPTN(NonPreTerminalNode node){if (verbose)System.out.println(node.left+"|"+node.right);};
public void visitSNPTN(StaticNonPreTerminalNode node){};
public void visitPTN(PreTerminalNode node){if (verbose)System.out.println("counts:"+node.getCount());};
public boolean test(){
return false;
}
}
//implements the visit based on a leaf
class TreeLeafVisitor extends TreeVisitor{
protected Leaf leaf;
protected NonPreTerminalNode father;
protected boolean done =false;
protected PreTerminalNode theNode;
public TreeLeafVisitor(Leaf leaf){
this.leaf=leaf;
}
public void visitNPTN(NonPreTerminalNode node){
father = node;
if (node.goRight(leaf)){
node.getRight().accept(this);
}
else
node.getLeft().accept(this);
};
public void visitPTN(PreTerminalNode node){
theNode = node;
node.setLeaf(leaf);
done = true;
};
public PreTerminalNode getNode(){
while (!done){};
return theNode;
}
}
class TreeAddVisitor extends TreeLeafVisitor implements Runnable{
private boolean running = false;
public TreeAddVisitor(Leaf leaf){
super(leaf);
}
public boolean test(){
if (!running){
running=true;
root.accept(this);
me.removeCustomEvent(this);
}
return false;
}
public void run(){
running=true;
root.accept(this);
running=false;
}
public void visitNPTN(NonPreTerminalNode node){
father = node;
node.setCount((int) (node.getCount()+leaf.weigth));
node.add(leaf);
if (node.goRight(leaf)){
node.getRight().accept(this);
}
else
node.getLeft().accept(this);
};
public void visitSNTPN(StaticNonPreTerminalNode node){
node.addLeaf(leaf);
}
public void visitPTN(PreTerminalNode node){
if (dynamicTree)
for (int i =0 ;i<leaf.weigth ;i++)
node.add(leaf);
else
node.add(leaf);
node.setCount((int) (node.getCount()+leaf.weigth));
if (rebuild&&dynamicTree){
//System.out.println(node.getCount());
if (node.getCount() > getRealThreshold()){
Node son = ((DynamicNode) node).split();
if (node.equals(father.getRight())&& son!= null){
father.setRight(son);
if (verbose) {
double[] factorsCount = ((DynamicNode) node).getFactorsCount();
System.out.println("split"+((PreTerminalNode)((NonPreTerminalNode)(father.getRight())).getRight()).getCount()+"/"+((PreTerminalNode)((NonPreTerminalNode)(father.getRight())).getLeft()).getCount());
double[] factorsCountRight = ((DynamicNode) ((NonPreTerminalNode)(father.getRight())).getRight()).getFactorsCount();
double[] factorsCountLeft = ((DynamicNode)((NonPreTerminalNode)(father.getRight())).getLeft()).getFactorsCount();
System.out.print(FUtils.doubleArrayToString(factorsCount)+"\n"+FUtils.doubleArrayToString(factorsCountLeft)+"|"+FUtils.doubleArrayToString(factorsCountRight));
}
}
else if (son!=null){
father.setLeft(son);
if (verbose){
double[] factorsCount = ((DynamicNode) node).getFactorsCount();
System.out.println("split"+((PreTerminalNode)((NonPreTerminalNode)(father.getLeft())).getRight()).getCount()+"/"+((PreTerminalNode)((NonPreTerminalNode)(father.getLeft())).getLeft()).getCount());
double[] factorsCountRight = ((DynamicNode)((NonPreTerminalNode)(father.getLeft())).getRight()).getFactorsCount();
double[] factorsCountLeft = ((DynamicNode)((NonPreTerminalNode)(father.getLeft())).getLeft()).getFactorsCount();
System.out.print(FUtils.doubleArrayToString(factorsCount)+"\n"+FUtils.doubleArrayToString(factorsCountLeft)+"\n"+FUtils.doubleArrayToString(factorsCountRight)+"\n");
}
}
}
}
};
}
//TODO modify to allow static tree && use NPTN node as well as PTN node
class TreePeakVisitor extends TreeLeafVisitor{
private int idx;
private ArrayList factorsList = new ArrayList(15);
public TreePeakVisitor(Leaf leaf){
super(leaf);
}
public void visitSNTPN(StaticNonPreTerminalNode node){
factorsList.add(node.factors);
}
public void visitPTN(PreTerminalNode node){
node.setLeaf(leaf);
if (!dynamicTree)
factorsList.add(((StaticNode)node).factors);
idx = node.getPeak();
};
public int getPeak(){
if (!dynamicTree){
double[][] buffers = (double[][]) factorsList.toArray();
// for (int i=0;i<factorsList.size();i++){
// buffers[i]=(double[])factorsList.get(i);
// }
double bestVal=0;
idx = (int) (GF_ZERO*(6d/5d));
for (int gf = 0;gf<GF_ONE;gf++){
double tmp = 0;
for (int i=0;i<factorsList.size();i++){
tmp += 1000*buffers[i][gf]/Math.max(1,buffers[i][0]);
}
if (tmp>bestVal){
bestVal = tmp;
idx = gf;
}
}
}
return idx;
}
}
class TreeCleanerVisitor extends TreeVisitor{
NonPreTerminalNode father;
int nptn,ptn;
public void visitNPTN(NonPreTerminalNode node){
nptn++;
father = node;
if (node.getRight()!=null)
node.getRight().accept(this);
if (node.getLeft()!=null)
node.getLeft().accept(this);
};
public void visitPTN(PreTerminalNode node){
ptn++;
if (node.equals(father.getRight())){
father.setRight(null);
} else {
father.setLeft(null);
}
};
}
class TreePopulatorVisitor extends TreeVisitor{
public void visitNPTN(NonPreTerminalNode node){
if (node.getRight() == null)
node.setRight(new StaticNode());
else
node.getRight().accept(this);
if (node.getLeft() == null)
node.setLeft(new StaticNode());
else
node.getLeft().accept(this);
};
}
/**
*
* @author Florent Lacroute
* called only when reubild == true
*/
class TreeRebuildVisitor extends TreeVisitor implements Runnable{
private NonPreTerminalNode father;
private int MAX_REBUILD = weightedLeaves<10000 ? weightedLeaves+1: threshold*16;
private int MIN_REBUILD = getRealThreshold();
private boolean running = false;
private double startTime;
private int heigth = 0;
public void run(){
startTime=me.getTime();
running = true;
rebuildingInProcess=true;
root.accept(this);
rebuildingInProcess=false;
bufferingEntry = false;
/* for (int i = 0; i<buffer.size();i++){
TreeAddVisitor v = new TreeAddVisitor((Leaf)buffer.get(i));
v.test();
}
buffer.clear(); */
running = false;
if (!RUMBLE)
System.out.println("tree rebuilded:"+(me.getTime()-startTime)+"|maxRebuild"+MAX_REBUILD+"|weightedLeaves:"+weightedLeaves);
if (saveToFile || showSegementation){
TreeSegmentationVisitor v = new TreeSegmentationVisitor();
v.seg = new Segmentation();
root.accept(v);
System.out.println(v.seg.toString());
if (saveToFile){
try{
File file = me.getDataFile("seg");
RobocodeFileOutputStream o = new RobocodeFileOutputStream(file);
OutputStreamWriter out = new OutputStreamWriter(o);
out.write(v.ptnSeg);
out.flush();
out.close();
} catch(Exception e){System.out.println(e);};
}
}
}
public boolean test(){
if (!running){
running=true;
root.accept(this);
me.removeCustomEvent(this);
}
return false;
}
public void visitNPTN(NonPreTerminalNode node){
if (quitThread)
return;
if ((node.getCount()<MAX_REBUILD)&&(node.getCount()>MIN_REBUILD)){
if (verbose) System.out.println("rebuild");
// TreeCollectorVisitor v = new TreeCollectorVisitor(node);
// node.accept(v);
// while (!v.isDone()){}
// DynamicNode newNode = new DynamicNode(v.getLeaves());
DynamicNode newNode = new DynamicNode(node.getLeaves());
newNode.nSeg = new NodeSegmentation(node.nSeg);
if (verbose) System.out.println(FUtils.doubleArrayToString(newNode.getFactorsCount()));
Node theNode= newNode.split();
if (theNode == null)
return;
if (father == null){
node.setRight(new DynamicNode());
node.setLeft(theNode);
}
else if (father.getRight().equals(node)){
father.setRight(theNode);
// ((NonPreTerminalNode) father.getRight()).getRight().accept(this);
// ((NonPreTerminalNode) father.getRight()).getLeft().accept(this);
}
else if (father.getLeft().equals(node)){
father.setLeft(theNode);
// ((NonPreTerminalNode) father.getLeft()).getRight().accept(this);
// ((NonPreTerminalNode) father.getLeft()).getLeft().accept(this);
}
}
else {
father = node;
if (!RUMBLE){
String space = "";
for (int i=0;i<heigth;i++)
space +=" ";
System.out.println("No more rebuild for "+space+node.toString());
}
heigth++;
if (node.getRight() != null)
node.getRight().accept(this);
if (node.getLeft() != null)
node.getLeft().accept(this);
heigth--;
}
};
public void visitPTN(PreTerminalNode node) {
try {
visitPTN((DynamicNode)node);
} catch (Exception e){
System.out.println("inappropriate use of TreeRebuildVisitor"+e);
}
}
public void visitPTN(DynamicNode node){
Node son ;
if (node.getCount() > threshold && (son=node.split()) != null){
if (node.equals(father.getRight())){
father.setRight(son);
}
else if (son!=null){
father.setLeft(son);
}
}
};
}
/**
* used only on dynamic trees
*/
class TreeCollectorVisitor extends TreeVisitor{
private ArrayList[] leaves;
private boolean done = false;
private int count;
public TreeCollectorVisitor(Node node){
leaves = new ArrayList[GF_ONE+1];
count = node.getCount();
for (int i=0;i<GF_ONE+1;i++){
leaves[i] = new ArrayList();
}
}
public boolean isDone(){
return done;
}
/**
* @return Returns the leaves.
*/
public ArrayList[] getLeaves() {
return leaves;
}
public void visitNPTN(NonPreTerminalNode node){
if (node.getRight() != null)
node.getRight().accept(this);
if (node.getLeft() != null)
node.getLeft().accept(this);
};
public void visitPTN(PreTerminalNode node) {
try {
visitPTN((DynamicNode)node);
} catch (Exception e){
System.out.println("inappropriate use of TreeCollectorVisitor"+e);
}
}
public void visitPTN(DynamicNode node){
ArrayList[] all = node.getFactors();
int size = 0;
for (int i=0;i<all.length;i++){
leaves[i].addAll(all[i]);
size += leaves[i].size();
}
if (count==size)
done =true;
};
}
public class TreeSegmentationVisitor extends TreeVisitor{
Segmentation seg;
String ptnSeg = "";
public TreeSegmentationVisitor(){
}
public void visitPTN(PreTerminalNode node) {
ptnSeg += node.nSeg.toString()+"\n";
}
public void visitNPTN(NonPreTerminalNode node) {
if (node.getLeft() != null)
node.getLeft().accept(this);
if (node instanceof DistanceNode) {
DistanceNode node2 = (DistanceNode) node;
seg.addDistance(node2.getDistance());
}
if (node instanceof PowerNode) {
PowerNode node2 = (PowerNode) node;
seg.addPower(node2.getPower());
}
if (node instanceof WallNode) {
WallNode node2 = (WallNode) node;
seg.addWall(node2.getWall());
}
if (node instanceof WallReverseNode) {
WallReverseNode node2 = (WallReverseNode) node;
seg.addWallReverse(node2.getWall());
}
if (node instanceof VelNode) {
VelNode node2 = (VelNode) node;
seg.addVelocity(node2.getVelocity());
}
if (node instanceof LatvelNode) {
LatvelNode node2 = (LatvelNode) node;
seg.addLateralVelocity(node2.getLatvel());
}
if (node instanceof MoveTimeNode) {
MoveTimeNode node2 = (MoveTimeNode) node;
seg.addMove(node2.getMoveTime());
}
if (node instanceof AccelNode) {
AccelNode node2 = (AccelNode) node;
seg.addAcceleration(node2.getAccel());
}
if (node.getRight() != null)
node.getRight().accept(this);
}
}
public class TreeSaveSymbolicVisitor extends TreeVisitor{
SymbolicTree right,left,theNode;
public void visitNPTN(NonPreTerminalNode node){
theNode = new SymbolicTree(node.code());
if (node.left!=null){
TreeSaveSymbolicVisitor visitorLeft = new TreeSaveSymbolicVisitor();
node.left.accept(visitorLeft);
theNode.setLeft(visitorLeft.theNode);
}
if (node.right!=null){
TreeSaveSymbolicVisitor visitorRight = new TreeSaveSymbolicVisitor();
node.right.accept(visitorRight);
theNode.setRight(visitorRight.theNode);
}
}
public SymbolicTree getTheNode() {
return theNode;
};
}
}
class SymbolicTree implements Serializable{
/**
*
*/
private static final long serialVersionUID = -7361823116265138539L;
private byte code;
private SymbolicTree left,right;
public SymbolicTree(int code){
this.code=(byte)code;
}
public SymbolicTree getLeft() {
return left;
}
public void setLeft(SymbolicTree left) {
this.left = left;
}
public SymbolicTree getRight() {
return right;
}
public void setRight(SymbolicTree right) {
this.right = right;
}
public int getCode() {
return code;
}
public void accept(TreeRestoreSymbolicVisitor v){
v.visit(this);
}
//TODO test this
public class TreeRestoreSymbolicVisitor implements Runnable{
private SegmentationTree.Node root;
private SegmentationTree.NonPreTerminalNode newNode;
private SegmentationTree fullTree;
private SymbolicTree tree;
// public TreeRestoreSymbolicVisitor(){};
public TreeRestoreSymbolicVisitor(SymbolicTree tree,SegmentationTree.Node root,SegmentationTree fullTree){
this.tree=tree;
this.root = root;
this.fullTree=fullTree;
}
public void visit(SymbolicTree node){
//TODO add a decorator pattern to Node to allow to register hits at different heights in the tree
newNode = fullTree.getNode(node.code);//fullTree.new StaticNonPreTerminalNode(fullTree.getNode(node.code));
System.out.println(newNode.toString()+"|symbolic code:"+node.code);
if (node.left != null){
TreeRestoreSymbolicVisitor v = new TreeRestoreSymbolicVisitor(null,null,fullTree);
node.left.accept(v);
newNode.left=v.newNode;
} else {
newNode.left = fullTree.new StaticNode();
}
if (node.right!=null){
TreeRestoreSymbolicVisitor v = new TreeRestoreSymbolicVisitor(null,null,fullTree);
node.right.accept(v);
newNode.right=v.newNode;
} else {
newNode.right = fullTree.new StaticNode();
}
}
public void run() {
tree.accept(this);
fullTree.setRoot(newNode);
}
}
}
class Segmentation {
HashSet wallSlices = new HashSet(),wallReverseSlices = new HashSet(),distanceSlices = new HashSet(),velocitySlices = new HashSet(),lateralVelocitySlices = new HashSet(),accelerationSlices = new HashSet(),powerSlices = new HashSet(),moveTimeSlices = new HashSet();
public void addDistance(double distance){
distanceSlices.add(new Double(distance));
}
public void addWall(double wall){
wallSlices.add(new Double(wall));
}
public void addWallReverse(double wall){
wallReverseSlices.add(new Double(wall));
}
public void addVelocity(double velocity){
velocitySlices.add(new Double(velocity));
}
public void addLateralVelocity(double lateralVelocity){
lateralVelocitySlices.add(new Double(lateralVelocity));
}
public void addAcceleration(double acceleration){
accelerationSlices.add(new Double(acceleration));
}
public void addPower(double power){
powerSlices.add(new Double(power));
}
public void addMove(double move){
moveTimeSlices.add(new Double(move));
}
public String toString(){
String res = "wall";
for (Iterator it = wallSlices.iterator(); it.hasNext();){
res += ":"+((Double)it.next()).toString();
}
res+="\nwall reverse";
for (Iterator it = wallReverseSlices.iterator(); it.hasNext();){
res += ":"+((Double)it.next()).toString();
}
res+="\ndistance";
for (Iterator it = distanceSlices.iterator(); it.hasNext();){
res += ":"+((Double)it.next()).toString();
}
res+="\naccel";
for (Iterator it = accelerationSlices.iterator(); it.hasNext();){
res += ":"+((Double)it.next()).toString();
}
res+="\nvel";
for (Iterator it = velocitySlices.iterator(); it.hasNext();){
res += ":"+((Double)it.next()).toString();
}
res+="\nlatvel";
for (Iterator it = lateralVelocitySlices.iterator(); it.hasNext();){
res += ":"+((Double)it.next()).toString();
}
res+="\npower";
for (Iterator it = powerSlices.iterator(); it.hasNext();){
res += ":"+((Double)it.next()).toString();
}
res+="\nmoveTime";
for (Iterator it = moveTimeSlices.iterator(); it.hasNext();){
res += ":"+((Double)it.next()).toString();
}
return res;
}
}
class NodeSegmentation{
double lowDistance, highDistance;
double lowVelocity, highVelocity;
double lowLateralVelocity, highLateralVelocity;
double lowAcceleration, highAcceleration;
double lowPower,highPower;
double lowTime,highTime;
double lowWall,highWall;
double lowWallReverse,highWallReverse;
double decisionValue;
public NodeSegmentation(){
lowDistance=lowVelocity=lowLateralVelocity=lowAcceleration=lowPower=lowTime=lowWall=lowWallReverse=Double.NEGATIVE_INFINITY;
highDistance=highVelocity=highLateralVelocity=highAcceleration=highPower=highTime=highWall=highWallReverse=Double.POSITIVE_INFINITY;
};
public NodeSegmentation(NodeSegmentation seg){
lowDistance=seg.lowDistance;
highDistance=seg.highDistance;
lowVelocity=seg.lowVelocity;
highVelocity=seg.highVelocity;
lowAcceleration=seg.lowAcceleration;
highAcceleration=seg.highAcceleration;
lowLateralVelocity=seg.lowLateralVelocity;
highLateralVelocity=seg.highLateralVelocity;
lowPower=seg.lowPower;
highPower=seg.highPower;
lowTime=seg.lowTime;
highTime=seg.highTime;
lowWall=seg.lowWall;
highWall=seg.highWall;
lowWallReverse=seg.lowWallReverse;
highWallReverse=seg.highWallReverse;
decisionValue=seg.decisionValue;
}
public String toString(){
String res = "";
res += "["+lowDistance+":"+highDistance+"]";
res += "["+lowVelocity+":"+highVelocity+"]";
res += "["+lowLateralVelocity+":"+highLateralVelocity+"]";
res += "["+lowAcceleration+":"+highAcceleration+"]";
res += "["+lowPower+":"+highPower+"]";
res += "["+lowTime+":"+highTime+"]";
res += "["+lowWall+":"+highWall+"]";
res += "["+lowWallReverse+":"+highWallReverse+"]";
return res;
}
}