1 | /* |
---|
2 | * This program is free software; you can redistribute it and/or modify |
---|
3 | * it under the terms of the GNU General Public License as published by |
---|
4 | * the Free Software Foundation; either version 2 of the License, or |
---|
5 | * (at your option) any later version. |
---|
6 | * |
---|
7 | * This program is distributed in the hope that it will be useful, |
---|
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
10 | * GNU General Public License for more details. |
---|
11 | * |
---|
12 | * You should have received a copy of the GNU General Public License |
---|
13 | * along with this program; if not, write to the Free Software |
---|
14 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
15 | */ |
---|
16 | |
---|
17 | /* |
---|
18 | * ParentSet.java |
---|
19 | * Copyright (C) 2001 University of Waikato, Hamilton, New Zealand |
---|
20 | * |
---|
21 | */ |
---|
22 | package weka.classifiers.bayes.net; |
---|
23 | |
---|
24 | import weka.core.Instances; |
---|
25 | import weka.core.RevisionHandler; |
---|
26 | import weka.core.RevisionUtils; |
---|
27 | |
---|
28 | import java.io.Serializable; |
---|
29 | |
---|
30 | /** |
---|
31 | * Helper class for Bayes Network classifiers. Provides datastructures to |
---|
32 | * represent a set of parents in a graph. |
---|
33 | * |
---|
34 | * @author Remco Bouckaert (rrb@xm.co.nz) |
---|
35 | * @version $Revision: 1.8 $ |
---|
36 | */ |
---|
37 | public class ParentSet |
---|
38 | implements Serializable, RevisionHandler { |
---|
39 | |
---|
40 | /** for serialization */ |
---|
41 | static final long serialVersionUID = 4155021284407181838L; |
---|
42 | |
---|
43 | /** |
---|
44 | * Holds indexes of parents |
---|
45 | */ |
---|
46 | private int[] m_nParents; |
---|
47 | |
---|
48 | /** |
---|
49 | * returns index parent of parent specified by index |
---|
50 | * |
---|
51 | * @param iParent Index of parent |
---|
52 | * @return index of parent |
---|
53 | */ |
---|
54 | public int getParent(int iParent) { |
---|
55 | return m_nParents[iParent]; |
---|
56 | } |
---|
57 | public int [] getParents() {return m_nParents;} |
---|
58 | |
---|
59 | /** |
---|
60 | * sets index parent of parent specified by index |
---|
61 | * |
---|
62 | * @param iParent Index of parent |
---|
63 | * @param nNode index of the node that becomes parent |
---|
64 | */ |
---|
65 | public void SetParent(int iParent, int nNode) { |
---|
66 | m_nParents[iParent] = nNode; |
---|
67 | } // SetParent |
---|
68 | |
---|
69 | |
---|
70 | /** |
---|
71 | * Holds number of parents |
---|
72 | */ |
---|
73 | private int m_nNrOfParents = 0; |
---|
74 | |
---|
75 | /** |
---|
76 | * returns number of parents |
---|
77 | * @return number of parents |
---|
78 | */ |
---|
79 | public int getNrOfParents() { |
---|
80 | return m_nNrOfParents; |
---|
81 | } |
---|
82 | |
---|
83 | /** |
---|
84 | * test if node is contained in parent set |
---|
85 | * @param iNode node to test for |
---|
86 | * @return number of parents |
---|
87 | */ |
---|
88 | public boolean contains(int iNode) { |
---|
89 | for (int iParent = 0; iParent < m_nNrOfParents; iParent++) { |
---|
90 | if (m_nParents[iParent] == iNode) { |
---|
91 | return true; |
---|
92 | } |
---|
93 | } |
---|
94 | return false; |
---|
95 | } |
---|
96 | /** |
---|
97 | * Holds cardinality of parents (= number of instantiations the parents can take) |
---|
98 | */ |
---|
99 | private int m_nCardinalityOfParents = 1; |
---|
100 | |
---|
101 | /** |
---|
102 | * returns cardinality of parents |
---|
103 | * |
---|
104 | * @return the cardinality |
---|
105 | */ |
---|
106 | public int getCardinalityOfParents() { |
---|
107 | return m_nCardinalityOfParents; |
---|
108 | } |
---|
109 | |
---|
110 | /** |
---|
111 | * returns cardinality of parents after recalculation |
---|
112 | * |
---|
113 | * @return the cardinality |
---|
114 | */ |
---|
115 | public int getFreshCardinalityOfParents(Instances _Instances) { |
---|
116 | m_nCardinalityOfParents = 1; |
---|
117 | for (int iParent = 0; iParent < m_nNrOfParents; iParent++) { |
---|
118 | m_nCardinalityOfParents *= _Instances.attribute(m_nParents[iParent]).numValues(); |
---|
119 | } |
---|
120 | return m_nCardinalityOfParents; |
---|
121 | } |
---|
122 | /** |
---|
123 | * default constructor |
---|
124 | */ |
---|
125 | public ParentSet() { |
---|
126 | m_nParents = new int[10]; |
---|
127 | m_nNrOfParents = 0; |
---|
128 | m_nCardinalityOfParents = 1; |
---|
129 | } // ParentSet |
---|
130 | |
---|
131 | /** |
---|
132 | * constructor |
---|
133 | * @param nMaxNrOfParents upper bound on nr of parents |
---|
134 | */ |
---|
135 | public ParentSet(int nMaxNrOfParents) { |
---|
136 | m_nParents = new int[nMaxNrOfParents]; |
---|
137 | m_nNrOfParents = 0; |
---|
138 | m_nCardinalityOfParents = 1; |
---|
139 | } // ParentSet |
---|
140 | |
---|
141 | /** |
---|
142 | * copy constructor |
---|
143 | * @param other other parent set |
---|
144 | */ |
---|
145 | public ParentSet(ParentSet other) { |
---|
146 | m_nNrOfParents = other.m_nNrOfParents; |
---|
147 | m_nCardinalityOfParents = other.m_nCardinalityOfParents; |
---|
148 | m_nParents = new int[m_nNrOfParents]; |
---|
149 | |
---|
150 | for (int iParent = 0; iParent < m_nNrOfParents; iParent++) { |
---|
151 | m_nParents[iParent] = other.m_nParents[iParent]; |
---|
152 | } |
---|
153 | } // ParentSet |
---|
154 | |
---|
155 | /** |
---|
156 | * reserve memory for parent set |
---|
157 | * |
---|
158 | * @param nSize maximum size of parent set to reserver memory for |
---|
159 | */ |
---|
160 | public void maxParentSetSize(int nSize) { |
---|
161 | m_nParents = new int[nSize]; |
---|
162 | } // MaxParentSetSize |
---|
163 | |
---|
164 | /** |
---|
165 | * Add parent to parent set and update internals (specifically the cardinality of the parent set) |
---|
166 | * |
---|
167 | * @param nParent parent to add |
---|
168 | * @param _Instances used for updating the internals |
---|
169 | */ |
---|
170 | public void addParent(int nParent, Instances _Instances) { |
---|
171 | if (m_nNrOfParents == 10) { |
---|
172 | // reserve more memory |
---|
173 | int [] nParents = new int[50]; |
---|
174 | for (int i = 0; i < m_nNrOfParents; i++) { |
---|
175 | nParents[i] = m_nParents[i]; |
---|
176 | } |
---|
177 | m_nParents = nParents; |
---|
178 | } |
---|
179 | m_nParents[m_nNrOfParents] = nParent; |
---|
180 | m_nNrOfParents++; |
---|
181 | m_nCardinalityOfParents *= _Instances.attribute(nParent).numValues(); |
---|
182 | } // AddParent |
---|
183 | |
---|
184 | /** |
---|
185 | * Add parent to parent set at specific location |
---|
186 | * and update internals (specifically the cardinality of the parent set) |
---|
187 | * |
---|
188 | * @param nParent parent to add |
---|
189 | * @param iParent location to add parent in parent set |
---|
190 | * @param _Instances used for updating the internals |
---|
191 | */ |
---|
192 | public void addParent(int nParent, int iParent, Instances _Instances) { |
---|
193 | if (m_nNrOfParents == 10) { |
---|
194 | // reserve more memory |
---|
195 | int [] nParents = new int[50]; |
---|
196 | for (int i = 0; i < m_nNrOfParents; i++) { |
---|
197 | nParents[i] = m_nParents[i]; |
---|
198 | } |
---|
199 | m_nParents = nParents; |
---|
200 | } |
---|
201 | for (int iParent2 = m_nNrOfParents; iParent2 > iParent; iParent2--) { |
---|
202 | m_nParents[iParent2] = m_nParents[iParent2 - 1]; |
---|
203 | } |
---|
204 | m_nParents[iParent] = nParent; |
---|
205 | m_nNrOfParents++; |
---|
206 | m_nCardinalityOfParents *= _Instances.attribute(nParent).numValues(); |
---|
207 | } // AddParent |
---|
208 | |
---|
209 | /** delete node from parent set |
---|
210 | * @param nParent node number of the parent to delete |
---|
211 | * @param _Instances data set |
---|
212 | * @return location of the parent in the parent set. This information can be |
---|
213 | * used to restore the parent set using the addParent method. |
---|
214 | */ |
---|
215 | public int deleteParent(int nParent, Instances _Instances) { |
---|
216 | int iParent = 0; |
---|
217 | while ((m_nParents[iParent] != nParent) && (iParent < m_nNrOfParents)) { |
---|
218 | iParent++; |
---|
219 | } |
---|
220 | int iParent2 = -1; |
---|
221 | if (iParent < m_nNrOfParents) { |
---|
222 | iParent2 = iParent; |
---|
223 | } |
---|
224 | if (iParent < m_nNrOfParents) { |
---|
225 | while (iParent < m_nNrOfParents - 1) { |
---|
226 | m_nParents[iParent] = m_nParents[iParent + 1]; |
---|
227 | iParent++; |
---|
228 | } |
---|
229 | m_nNrOfParents--; |
---|
230 | m_nCardinalityOfParents /= _Instances.attribute(nParent).numValues(); |
---|
231 | } |
---|
232 | return iParent2; |
---|
233 | } // DeleteParent |
---|
234 | |
---|
235 | /** |
---|
236 | * Delete last added parent from parent set and update internals (specifically the cardinality of the parent set) |
---|
237 | * |
---|
238 | * @param _Instances used for updating the internals |
---|
239 | */ |
---|
240 | public void deleteLastParent(Instances _Instances) { |
---|
241 | m_nNrOfParents--; |
---|
242 | m_nCardinalityOfParents = |
---|
243 | m_nCardinalityOfParents |
---|
244 | / _Instances.attribute(m_nParents[m_nNrOfParents]).numValues(); |
---|
245 | } // DeleteLastParent |
---|
246 | |
---|
247 | /** Copy makes current parents set equal to other parent set |
---|
248 | * |
---|
249 | * @param other : parent set to make a copy from |
---|
250 | */ |
---|
251 | public void copy(ParentSet other) { |
---|
252 | m_nCardinalityOfParents = other.m_nCardinalityOfParents; |
---|
253 | m_nNrOfParents = other.m_nNrOfParents; |
---|
254 | for (int iParent = 0; iParent < m_nNrOfParents; iParent++) { |
---|
255 | m_nParents[iParent] = other.m_nParents[iParent]; |
---|
256 | } |
---|
257 | } // Copy |
---|
258 | |
---|
259 | /** |
---|
260 | * Returns the revision string. |
---|
261 | * |
---|
262 | * @return the revision |
---|
263 | */ |
---|
264 | public String getRevision() { |
---|
265 | return RevisionUtils.extract("$Revision: 1.8 $"); |
---|
266 | } |
---|
267 | |
---|
268 | } // class ParentSet |
---|