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    }