001: /*
002: * This program is free software; you can redistribute it and/or modify
003: * it under the terms of the GNU General Public License as published by
004: * the Free Software Foundation; either version 2 of the License, or
005: * (at your option) any later version.
006: *
007: * This program is distributed in the hope that it will be useful,
008: * but WITHOUT ANY WARRANTY; without even the implied warranty of
009: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
010: * GNU General Public License for more details.
011: *
012: * You should have received a copy of the GNU General Public License
013: * along with this program; if not, write to the Free Software
014: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
015: */
016:
017: /*
018: * ParentSet.java
019: * Copyright (C) 2001 University of Waikato, Hamilton, New Zealand
020: *
021: */
022: package weka.classifiers.bayes.net;
023:
024: import weka.core.Instances;
025:
026: import java.io.Serializable;
027:
028: /**
029: * Helper class for Bayes Network classifiers. Provides datastructures to
030: * represent a set of parents in a graph.
031: *
032: * @author Remco Bouckaert (rrb@xm.co.nz)
033: * @version $Revision: 1.6 $
034: */
035: public class ParentSet implements Serializable {
036:
037: /** for serialization */
038: static final long serialVersionUID = 4155021284407181838L;
039:
040: /**
041: * Holds indexes of parents
042: */
043: private int[] m_nParents;
044:
045: /**
046: * returns index parent of parent specified by index
047: *
048: * @param iParent Index of parent
049: * @return index of parent
050: */
051: public int getParent(int iParent) {
052: return m_nParents[iParent];
053: }
054:
055: /**
056: * sets index parent of parent specified by index
057: *
058: * @param iParent Index of parent
059: * @param nNode index of the node that becomes parent
060: */
061: public void SetParent(int iParent, int nNode) {
062: m_nParents[iParent] = nNode;
063: } // SetParent
064:
065: /**
066: * Holds number of parents
067: */
068: private int m_nNrOfParents = 0;
069:
070: /**
071: * returns number of parents
072: * @return number of parents
073: */
074: public int getNrOfParents() {
075: return m_nNrOfParents;
076: }
077:
078: /**
079: * test if node is contained in parent set
080: * @param iNode node to test for
081: * @return number of parents
082: */
083: public boolean contains(int iNode) {
084: for (int iParent = 0; iParent < m_nNrOfParents; iParent++) {
085: if (m_nParents[iParent] == iNode) {
086: return true;
087: }
088: }
089: return false;
090: }
091:
092: /**
093: * Holds cardinality of parents (= number of instantiations the parents can take)
094: */
095: private int m_nCardinalityOfParents = 1;
096:
097: /**
098: * returns cardinality of parents
099: *
100: * @return the cardinality
101: */
102: public int getCardinalityOfParents() {
103: return m_nCardinalityOfParents;
104: }
105:
106: /**
107: * default constructor
108: */
109: public ParentSet() {
110: m_nParents = new int[10];
111: m_nNrOfParents = 0;
112: m_nCardinalityOfParents = 1;
113: } // ParentSet
114:
115: /**
116: * constructor
117: * @param nMaxNrOfParents upper bound on nr of parents
118: */
119: public ParentSet(int nMaxNrOfParents) {
120: m_nParents = new int[nMaxNrOfParents];
121: m_nNrOfParents = 0;
122: m_nCardinalityOfParents = 1;
123: } // ParentSet
124:
125: /**
126: * copy constructor
127: * @param other other parent set
128: */
129: public ParentSet(ParentSet other) {
130: m_nNrOfParents = other.m_nNrOfParents;
131: m_nCardinalityOfParents = other.m_nCardinalityOfParents;
132: m_nParents = new int[m_nNrOfParents];
133:
134: for (int iParent = 0; iParent < m_nNrOfParents; iParent++) {
135: m_nParents[iParent] = other.m_nParents[iParent];
136: }
137: } // ParentSet
138:
139: /**
140: * reserve memory for parent set
141: *
142: * @param nSize maximum size of parent set to reserver memory for
143: */
144: public void maxParentSetSize(int nSize) {
145: m_nParents = new int[nSize];
146: } // MaxParentSetSize
147:
148: /**
149: * Add parent to parent set and update internals (specifically the cardinality of the parent set)
150: *
151: * @param nParent parent to add
152: * @param _Instances used for updating the internals
153: */
154: public void addParent(int nParent, Instances _Instances) {
155: if (m_nNrOfParents == 10) {
156: // reserve more memory
157: int[] nParents = new int[50];
158: for (int i = 0; i < m_nNrOfParents; i++) {
159: nParents[i] = m_nParents[i];
160: }
161: m_nParents = nParents;
162: }
163: m_nParents[m_nNrOfParents] = nParent;
164: m_nNrOfParents++;
165: m_nCardinalityOfParents *= _Instances.attribute(nParent)
166: .numValues();
167: } // AddParent
168:
169: /**
170: * Add parent to parent set at specific location
171: * and update internals (specifically the cardinality of the parent set)
172: *
173: * @param nParent parent to add
174: * @param iParent location to add parent in parent set
175: * @param _Instances used for updating the internals
176: */
177: public void addParent(int nParent, int iParent, Instances _Instances) {
178: if (m_nNrOfParents == 10) {
179: // reserve more memory
180: int[] nParents = new int[50];
181: for (int i = 0; i < m_nNrOfParents; i++) {
182: nParents[i] = m_nParents[i];
183: }
184: m_nParents = nParents;
185: }
186: for (int iParent2 = m_nNrOfParents; iParent2 > iParent; iParent2--) {
187: m_nParents[iParent2] = m_nParents[iParent2 - 1];
188: }
189: m_nParents[iParent] = nParent;
190: m_nNrOfParents++;
191: m_nCardinalityOfParents *= _Instances.attribute(nParent)
192: .numValues();
193: } // AddParent
194:
195: /** delete node from parent set
196: * @param nParent node number of the parent to delete
197: * @param _Instances data set
198: * @return location of the parent in the parent set. This information can be
199: * used to restore the parent set using the addParent method.
200: */
201: public int deleteParent(int nParent, Instances _Instances) {
202: int iParent = 0;
203: while ((m_nParents[iParent] != nParent)
204: && (iParent < m_nNrOfParents)) {
205: iParent++;
206: }
207: int iParent2 = -1;
208: if (iParent < m_nNrOfParents) {
209: iParent2 = iParent;
210: }
211: if (iParent < m_nNrOfParents) {
212: while (iParent < m_nNrOfParents - 1) {
213: m_nParents[iParent] = m_nParents[iParent + 1];
214: iParent++;
215: }
216: m_nNrOfParents--;
217: m_nCardinalityOfParents /= _Instances.attribute(nParent)
218: .numValues();
219: }
220: return iParent2;
221: } // DeleteParent
222:
223: /**
224: * Delete last added parent from parent set and update internals (specifically the cardinality of the parent set)
225: *
226: * @param _Instances used for updating the internals
227: */
228: public void deleteLastParent(Instances _Instances) {
229: m_nNrOfParents--;
230: m_nCardinalityOfParents = m_nCardinalityOfParents
231: / _Instances.attribute(m_nParents[m_nNrOfParents])
232: .numValues();
233: } // DeleteLastParent
234:
235: /** Copy makes current parents set equal to other parent set
236: *
237: * @param other : parent set to make a copy from
238: */
239: public void copy(ParentSet other) {
240: m_nCardinalityOfParents = other.m_nCardinalityOfParents;
241: m_nNrOfParents = other.m_nNrOfParents;
242: for (int iParent = 0; iParent < m_nNrOfParents; iParent++) {
243: m_nParents[iParent] = other.m_nParents[iParent];
244: }
245: } // Copy
246:
247: } // class ParentSet
|