001 package org.jaga.reproduction.booleanFormulas.nodes;
002
003
004 /**
005 * TODO: Complete these comments.
006 *
007 * <p><u>Project:</u> JAGA - Java API for Genetic Algorithms.</p>
008 *
009 * <p><u>Company:</u> University College London and JAGA.Org
010 * (<a href="http://www.jaga.org" target="_blank">http://www.jaga.org</a>).
011 * </p>
012 *
013 * <p><u>Copyright:</u> (c) 2004 by G. Paperin.<br/>
014 * This program is free software; you can redistribute it and/or modify
015 * it under the terms of the GNU General Public License as published by
016 * the Free Software Foundation, ONLY if you include a note of the original
017 * author(s) in any redistributed/modified copy.<br/>
018 * This program is distributed in the hope that it will be useful,
019 * but WITHOUT ANY WARRANTY; without even the implied warranty of
020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
021 * GNU General Public License for more details.<br/>
022 * You should have received a copy of the GNU General Public License
023 * along with this program; if not, write to the Free Software
024 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
025 * or see http://www.gnu.org/licenses/gpl.html</p>
026 *
027 * @author Greg Paperin (greg@jaga.org)
028 *
029 * @version JAGA public release 1.0 beta
030 */
031
032 abstract public class OperatorNode extends BooleanFormulaTreeNode {
033
034 BooleanFormulaTreeNode [] children = null;
035
036 public OperatorNode() {}
037
038 abstract public int getRequiredChildrenNumber();
039
040 abstract String getOperatorName();
041
042 public Object clone() {
043 OperatorNode copy = null;
044 try {
045 copy = (OperatorNode) this.getClass().newInstance();
046 } catch(InstantiationException e1) {
047 throw new InstantiationError(e1.getMessage());
048 } catch(IllegalAccessException e2) {
049 throw new IllegalAccessError(e2.getMessage());
050 }
051 assert null != copy : "Problem creating a clone";
052
053 if (null == this.children)
054 return copy;
055
056 for (int i = 0; i < children.length; i++) {
057 if (null != children[i]) {
058 copy.setChild(i, (BooleanFormulaTreeNode) children[i].clone());
059 }
060 }
061 return copy;
062 }
063
064 public int recalcHeight() {
065
066 int height = 0;
067 for (int i = 0; i < getRequiredChildrenNumber(); i++) {
068 BooleanFormulaTreeNode c = getChild(i);
069 if (null != c) {
070 int h = c.recalcHeight();
071 if (h > height)
072 height = h;
073 }
074 }
075 ++height;
076 setHeight(height);
077
078 OperatorNode parent = getParent();
079 if (null != parent)
080 parent.propagateNewHeight();
081
082 return height;
083 }
084
085 void propagateNewHeight() {
086 int height = 0;
087 for (int i = 0; i < getRequiredChildrenNumber(); i++) {
088 BooleanFormulaTreeNode c = getChild(i);
089 if (null != c) {
090 int h = c.getHeight();
091 if (h > height)
092 height = h;
093 }
094 }
095 ++height;
096 setHeight(height);
097
098 OperatorNode parent = getParent();
099 if (null != parent)
100 parent.propagateNewHeight();
101 }
102
103 public void setChild(int index, BooleanFormulaTreeNode node) {
104 validateChildIndex(index);
105 if (null == children)
106 initChildrenArray();
107 children[index] = node;
108 node.setParent(this);
109 }
110
111 private void validateChildIndex(int index) throws IndexOutOfBoundsException {
112 if (index < 0 || getRequiredChildrenNumber() <= index)
113 throw new IndexOutOfBoundsException("Index is " + index
114 + ", but children-indices are from 0 to "
115 + getRequiredChildrenNumber());
116 }
117
118 public int findChild(BooleanFormulaTreeNode node) {
119 for (int i = 0; i < getRequiredChildrenNumber(); i++)
120 if (node == children[i])
121 return i;
122 return -1;
123 }
124
125 public BooleanFormulaTreeNode getChild(int index) {
126 // validateChildIndex(index); // this was generating 12.82% of run time
127 if (null == children)
128 return null;
129 return children[index];
130 }
131
132 private void initChildrenArray() {
133 if (null != children)
134 return;
135 children = new BooleanFormulaTreeNode[getRequiredChildrenNumber()];
136 for (int i = 0; i < children.length; children[i++] = null);
137 }
138
139 }