// ! the shortest route to the element described by the row
// ! can be reconstructed by following the m_predecessor back-references
public static RouteInfo[][] getAllConnections(Collection<AbstractPetriNetElementModel> netElements,
boolean ignoreArcDirection) {
int nNumNetElements = netElements.size();
RouteInfo routeInfo[][] = new RouteInfo[nNumNetElements][nNumNetElements];
HashMap<AbstractPetriNetElementModel, Integer> nodeToIndex = new HashMap<AbstractPetriNetElementModel, Integer>();
// Build a map from node to index
// We will need this when traversing the graph
// (the graph doesn't know about our collection of input
// net elements)
Iterator<AbstractPetriNetElementModel> nodeIndexIterator = netElements.iterator();
int nNodeIndex = 0;
while (nodeIndexIterator.hasNext()) {
nodeToIndex.put(nodeIndexIterator.next(), new Integer(nNodeIndex));
++nNodeIndex;
}
try {
// Iterate through outer index
for (int i = 0; i < nNumNetElements; ++i) {
int j = 0;
Iterator<AbstractPetriNetElementModel> innerIterator = netElements.iterator();
while (innerIterator.hasNext()) {
routeInfo[i][j] = new RouteInfo();
routeInfo[i][j].m_thisElement = innerIterator.next();
++j;
}
// Apply Moore's algorithm
// We have a distance of zero to ourselves
routeInfo[i][i].m_nDistanceToSource = 0;
// Define the starting point
LinkedList<RouteInfo> currentList = new LinkedList<RouteInfo>();
currentList.add(routeInfo[i][i]);
// Keep going until no more elements need to be processed
while (currentList.size() > 0) {
// Create the follow-up list
LinkedList<RouteInfo> newList = new LinkedList<RouteInfo>();
for (Iterator<RouteInfo> listContent = currentList.iterator(); listContent.hasNext();) {
RouteInfo currentRouteInfo = listContent.next();
// Look up all connections (to and from, only from if directed
// and iterate them)
Set<AbstractPetriNetElementModel> connectedNodes = getDirectlyConnectedNodes(
currentRouteInfo.m_thisElement, connectionTypeOUTBOUND);
if (ignoreArcDirection == true) {
// Depending on our configuration we care about the
// direction of the edge or not
Set<AbstractPetriNetElementModel> wrongDirection = getDirectlyConnectedNodes(
currentRouteInfo.m_thisElement, connectionTypeINBOUND);
connectedNodes.addAll(wrongDirection);
}
Iterator<AbstractPetriNetElementModel> nodeIterator = connectedNodes.iterator();
while (nodeIterator.hasNext()) {
AbstractPetriNetElementModel target = nodeIterator.next();
// Use our node to index lookup table to
// find the RouteInfo object corresponding to the
// target
Integer targetIndex = nodeToIndex.get(target);
if (targetIndex != null) {
RouteInfo newRouteInfo = routeInfo[i][targetIndex.intValue()];
// See whether this node has already been visited
if (newRouteInfo.m_nDistanceToSource == -1) {
// Update the information on this node
newRouteInfo.m_predecessor = currentRouteInfo;
newRouteInfo.m_nDistanceToSource = currentRouteInfo.m_nDistanceToSource + 1;