package org.streaminer.stream.classifier.tree;
import org.streaminer.stream.data.Data;
import org.streaminer.stream.learner.Regressor;
import java.io.Serializable;
public class InnerNode extends RegressionTreeNode implements Serializable {
private static final long serialVersionUID = -7739559317623140189L;
/**
* feature associated with this node
*/
private final String feature;
/**
* value of associated feature
*/
private final Serializable value;
/**
* left child of the node
*/
private RegressionTreeNode leftChild;
/**
* right child of the node
*/
private RegressionTreeNode rightChild;
public InnerNode(String feature, Serializable value, Regressor<Data> linearRegression, int n){
this.feature = feature;
this.value = value;
this.leftChild = new LeafNode(this, false, linearRegression, n);
this.rightChild = new LeafNode(this, true, linearRegression, n);
}
/**
* traverses node to find matching leaf node
* @param value a valid value for the associated feature
* @return next node following the path of the given value, null if node does not exists
*/
public RegressionTreeNode traverseNode(Serializable value){
if(value instanceof Number && this.value instanceof Number){
Double number = ((Number) value).doubleValue();
return this.traverseNumericalNode(number);
}else{
return this.traverseNominalNode(value);
}
}
/**
* traverses numerical node to find matching leaf node
* @param value a valid value for the associated feature
* @return next node following the path of the given value, null if node does not exists
*/
private RegressionTreeNode traverseNumericalNode(Double v) {
double val = (Double) this.value;
if(v.compareTo(val) <= 0){
return this.leftChild;
}else{
return this.rightChild;
}
}
/**
* traverses nominal node to find matching leaf node
* @param value a valid value for the associated feature
* @return next node following the path of the given value, null if node does not exists
*/
private RegressionTreeNode traverseNominalNode(Serializable value) {
if(value.equals(this.value)){
return this.leftChild;
}else{
return this.rightChild;
}
}
/**
* @return name of feature associated with this node
*/
public String getFeature() {
return this.feature;
}
/**
* @return left child of this node
*/
public RegressionTreeNode getLeftChild() {
return this.leftChild;
}
/**
* @return right child of this node
*/
public RegressionTreeNode getRightChild() {
return this.rightChild;
}
/**
* sets new left child of this node
* @param leftChild RegressionTreeNode to be left child of this node
*/
public void setLeftChild(RegressionTreeNode leftChild) {
this.leftChild = leftChild;
}
/**
* sets new right child of this node
* @param rightChild RegressionTreeNode to be right child of this node
*/
public void setRightChild(RegressionTreeNode rightChild) {
this.rightChild = rightChild;
}
@Override
public String toString(int blanks){
StringBuffer out = new StringBuffer();
int length = 8 + this.feature.length() + this.value.toString().length() + blanks;
out.append(this.rightChild.toString(length + 4));
out.append(LINE_SEPATATOR);
for(int i = 0; i < blanks; i++){
out.append(" ");
}
if(blanks > 0){
out.append("-- ");
}
String compare;
if(this.value instanceof Number){
compare = "<=";
}else{
compare = "=";
}
out.append("("+this.feature+ compare +this.value.toString()+")");
out.append(LINE_SEPATATOR);
out.append(this.leftChild.toString(length + 4));
return out.toString();
}
}