1 |
|
//(c): Tuukka Hastrup |
2 |
|
|
3 |
package org.fenfire.util.lava; |
package org.fenfire.util.lava; |
4 |
|
|
15 |
static class CollisionException extends Exception { |
static class CollisionException extends Exception { |
16 |
} |
} |
17 |
|
|
18 |
|
/** Return type for recurseDFS. |
19 |
|
*/ |
20 |
|
static class DFSRet { |
21 |
|
public Object representative; |
22 |
|
public int degree; |
23 |
|
} |
24 |
|
|
25 |
/** Returns an iterator of nodes directly connected to a given node |
/** Returns an iterator of nodes directly connected to a given node |
26 |
* along a given non-directional property. |
* along a given non-directional property. |
27 |
*/ |
*/ |
113 |
} |
} |
114 |
} |
} |
115 |
|
|
116 |
|
/** Finds components disconnected along a given non-directed property, |
117 |
|
* and for each component returns the node of highest degree as a |
118 |
|
* representative. |
119 |
|
* @return set of representatives, one for each component |
120 |
|
*/ |
121 |
|
public static Set findComponents(Object property, ConstGraph g) { |
122 |
|
// XXX "Iterator nodes" could be a parameter |
123 |
|
Iterator nodes = g.findN_XAA_Iter(); // FIXME doesn't find objects |
124 |
|
Set visited = new HashSet(); |
125 |
|
Set components = new HashSet(); |
126 |
|
while(nodes.hasNext()) { |
127 |
|
Object node = nodes.next(); |
128 |
|
if(!visited.contains(node)) { // If found a new component |
129 |
|
visited.add(node); |
130 |
|
components.add(recurseDFS(node, property, g, visited, |
131 |
|
new DFSRet()).representative); |
132 |
|
} |
133 |
|
} |
134 |
|
return components; |
135 |
|
} |
136 |
|
|
137 |
|
/** Recurses depth-first search from a given node, and finds the node |
138 |
|
* of highest degree (with most connections). |
139 |
|
* @return an array: the first element is the node of highest degree |
140 |
|
* the second element is the highest degree as Integer |
141 |
|
*/ |
142 |
|
static DFSRet recurseDFS(Object start, Object property, ConstGraph g, |
143 |
|
Set visited, DFSRet ret) { |
144 |
|
Object representative = null; |
145 |
|
int representativeDegree = -1; |
146 |
|
Iterator conns = findConnected_Iter(g, start, property); |
147 |
|
int degree = 0; |
148 |
|
while(conns.hasNext()) { |
149 |
|
Object found = conns.next(); |
150 |
|
degree++; |
151 |
|
if(!visited.contains(found)) { |
152 |
|
visited.add(found); |
153 |
|
ret = recurseDFS(found, property, g, visited, ret); |
154 |
|
if(ret.degree > representativeDegree) { |
155 |
|
representativeDegree = ret.degree; |
156 |
|
representative = ret.representative; |
157 |
|
} |
158 |
|
} |
159 |
|
} |
160 |
|
if(representativeDegree > degree) { |
161 |
|
ret.representative = representative; |
162 |
|
ret.degree = representativeDegree; |
163 |
|
} else { |
164 |
|
ret.representative = start; |
165 |
|
ret.degree = degree; |
166 |
|
} |
167 |
|
return ret; |
168 |
|
} |
169 |
} |
} |