FailureDepGraph.java
Go to the documentation of this file.
00001 /*
00002  * (c) copyright 2008, Technische Universitaet Graz and Technische Universitaet Wien
00003  *
00004  * This file is part of jdiagengine.
00005  *
00006  * jdiagengine is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation, either version 3 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * jdiagengine is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * You should have received a copy of the GNU General Public License
00016  * along with jdiagengine. If not, see <http://www.gnu.org/licenses/>.
00017  *
00018  * Authors: Joerg Weber, Franz Wotawa
00019  * Contact: jweber@ist.tugraz.at (preferred), or fwotawa@ist.tugraz.at
00020  *
00021  */
00022 
00023 
00024 package dfengine;
00025 
00026 import java.util.*;
00027 
00028 import utils.*;
00029 
00030 public class FailureDepGraph extends DoubleLinkedDAG {
00031 
00032     protected GraphMatrix indirectDeps;
00033 
00034     protected GraphMatrix commonAncestorGraph;
00035 
00036     protected boolean useProbabilities;
00037 
00038     public FailureDepGraph(boolean useProbabilities) {
00039         this.useProbabilities = useProbabilities;
00040     }
00041 
00042     public String toString() {
00043         StringBuffer result = new StringBuffer(super.toString());
00044         
00045         result.append("\n\nTRANSITIVE CLOSURE:\n\n");
00046         Iterator itEdges = indirectDeps.getEdgeIterator();
00047         while (itEdges.hasNext()) {
00048             GraphMatrix.Edge e = (GraphMatrix.Edge)itEdges.next();
00049             FailureDepNode fromNode = (FailureDepNode)getNode(e.from);
00050             FailureDepNode toNode = (FailureDepNode)getNode(e.to);
00051             result.append(fromNode + " => " + toNode);
00052             
00053             int dist = ((DoubleLinkedDAG.MinMaxDistance)indirectDeps.getTag(e.from, e.to)).minDist;
00054             result.append(" (" + dist + ")\n");
00055         }
00056         
00057         result.append("\n\nCOMMON ANCESTOR GRAPH:\n\n");
00058         itEdges = commonAncestorGraph.getEdgeIterator();
00059         while (itEdges.hasNext()) {
00060             GraphMatrix.Edge e = (GraphMatrix.Edge)itEdges.next();
00061             FailureDepNode fromNode = (FailureDepNode)getNode(e.from);
00062             FailureDepNode toNode = (FailureDepNode)getNode(e.to);
00063             result.append(fromNode + " => " + toNode);
00064             
00065             int dist = ((Integer)commonAncestorGraph.getTag(e.from, e.to)).intValue();
00066             result.append(" (" + dist + ")\n");
00067         }
00068 
00069         return result.toString();
00070     }
00071 
00072     public Object clone() {
00073         throw new UnsupportedOperationException("class FailureDepGraph does not support clone()");
00074     }
00075 
00076     boolean useProbabilities() {
00077         return useProbabilities;
00078     }
00079 
00085     public FailureDepNode addNode(Component comp) {
00086         assert(!useProbabilities || (comp.getProbIF() >= 0.0));
00087 
00088         FailureDepNode newNode = new FailureDepNode(comp);
00089         super.addNode(newNode);
00090         comp.fdNode = newNode;
00091         return newNode;
00092     }
00093 
00099     public void addEdge(Component from, Component to) {
00100         assert(!useProbabilities && (from.fdNode != null) && (to.fdNode != null));
00101 
00102         super.addEdge(from.fdNode, to.fdNode);
00103     }
00104 
00110     public void addEdge(Component from, Component to, double prob_df) {
00111         assert(useProbabilities && (from.fdNode != null) && (to.fdNode != null));
00112 
00113         super.addEdge(from.fdNode, to.fdNode);
00114         to.fdNode.prob_df.put(new Integer(from.fdNode.getID()), new Double(prob_df));
00115     }
00116 
00117     /*
00118      * Does not need to be called explicitely.
00119      * 
00120      * The indirect dependencies are computed implicitely at the first
00121      * invokation of hasIndirectDependency(). However, the
00122      * computation can be triggered earlier by calling this method.
00123      */
00124     public void computeIndirectDeps() {
00125         indirectDeps = computeTransitiveClosure(true);
00126     }
00127 
00128     /*
00129      * True iff there is a path from "from" to "to".
00130      */
00131     public boolean hasIndirectDependency(Component from, Component to) {
00132         if (indirectDeps == null) computeIndirectDeps();
00133 
00134         return (indirectDeps.hasEdge(from.getFDNode().getID(), to.getFDNode().getID()));        
00135     }
00136 
00137     /*
00138      * Returns true iff c1 and c2 have a common ancestor in the FDG,
00139      * but c1 and c2 are not (directly or indirectly) dependent on each other.
00140      */
00141     public boolean haveCommonAncestor(Component c1, Component c2) {
00142         int id1 = c1.getFDNode().getID();
00143         int id2 = c2.getFDNode().getID();
00144         
00145         return commonAncestorGraph.hasEdge(id1, id2);
00146     }
00147 
00148     /*
00149      * The resulting graph has an edge from n1 -> n2 iff
00150      * n1 and n2 have a common ancestor a in the FDG, 
00151      * but n1 and n2 are not indirect dep. on each other
00152      * (i.e., there is no path in the transitive closure
00153      * between n1 and n2).
00154      *
00155      * Note that the resulting graph is undirected, i.e.,
00156      * for each edge n1 -> n2 there must also be an edge
00157      * n2 -> n1.
00158      *
00159      * If computeMinDistance: the edge n1 -> n2 is labelled
00160      * with an integer md= max{d(a, n1), d(a, n2)}  [d..distance],
00161      * and a is the "closest" ancestor.
00162      *
00163      * Must be called AFTER computeIndirectDeps()!
00164      */
00165     public void computeCommonAncestorGraph(boolean computeMinDistances) {
00166         assert(indirectDeps != null);
00167 
00168         commonAncestorGraph = new GraphMatrix(nodes.size());
00169 
00170         for (int i = 0; i < nodes.size(); ++i) {
00171 
00172             for (int j = i + 1; j < nodes.size(); ++j) {
00173 
00174                 if (!indirectDeps.hasEdge(i, j)
00175                     && !indirectDeps.hasEdge(j, i)) {
00176 
00177                     for (int k = 0; k < nodes.size(); ++k) {
00178                         if ((k != i) && (k != j)
00179                             && indirectDeps.hasEdge(k, i)
00180                             && indirectDeps.hasEdge(k, j)) {
00181 
00182                             if (computeMinDistances) {
00183                                 Object tag_i = indirectDeps.getTag(k, i);
00184                                 Object tag_j = indirectDeps.getTag(k, j);
00185                                 assert((tag_i != null) && (tag_j) != null);
00186                                 int di = ((DoubleLinkedDAG.MinMaxDistance)tag_i).minDist;
00187                                 int dj = ((DoubleLinkedDAG.MinMaxDistance)tag_j).minDist;
00188                                 int maxd;
00189                                 if (di > dj) maxd = di;
00190                                 else maxd = dj;
00191 
00192                                 if (commonAncestorGraph.hasEdge(i, j)) {
00193                                     assert(commonAncestorGraph.hasEdge(j, i));
00194 
00195                                     Integer dk = (Integer)commonAncestorGraph.getTag(i, j);
00196                                     if (maxd < dk.intValue()) {
00197                                         commonAncestorGraph.setTag(i, j, new Integer(maxd));
00198                                         commonAncestorGraph.setTag(j, i, new Integer(maxd));
00199                                     }
00200                                 } else {
00201                                     commonAncestorGraph.addEdge(i, j);
00202                                     commonAncestorGraph.addEdge(j, i);
00203                                     commonAncestorGraph.setTag(i, j, new Integer(maxd));
00204                                     commonAncestorGraph.setTag(j, i, new Integer(maxd));
00205                                 }
00206                             } else {
00207                                 commonAncestorGraph.addEdge(i, j);  // edges are "mutual" (2-way)
00208                                 commonAncestorGraph.addEdge(j, i);
00209                                 break;
00210                             }                            
00211 
00212                         }  // for k
00213                     }
00214                 }  // for j
00215             }  // for i
00216         }
00217 
00218     }  // computeCommonAncestorGraph()
00219 
00220     /*
00221      * Returns true iff either c1 is an ancestor of c2, or vice versa, or if they
00222      * have a common ancestor. In the first two cases, only pathes between c1 and c2
00223      * with a length of <= maxPathLen are considered. In the third case, maxPathLen
00224      * refers to the path between the common ancestor and that component c1 or c2
00225      * which has a larger distance to the ancestor.
00226      * 
00227      */
00228     public boolean isAncestorConnected(Component c1, Component c2, int maxPathLen) {
00229         
00230         boolean result = isAncestorConnected_Impl(c1, c2, maxPathLen);
00231         
00232         // assert: this relation is commutative
00233         assert(result == isAncestorConnected_Impl(c2, c1, maxPathLen));
00234         
00235         return result;
00236     }
00237 
00238     protected boolean isAncestorConnected_Impl(Component c1, Component c2, int maxPathLen) {
00239         int id1 = c1.getFDNode().getID();
00240         int id2 = c2.getFDNode().getID();
00241 
00242         boolean result = false;
00243 
00244         if (indirectDeps.hasEdge(id1, id2)) {
00245             int dist = ((DoubleLinkedDAG.MinMaxDistance)indirectDeps.getTag(id1, id2)).minDist;
00246             if (dist <= maxPathLen) result = true;
00247         } else if (indirectDeps.hasEdge(id2, id1)) {
00248             int dist = ((DoubleLinkedDAG.MinMaxDistance)indirectDeps.getTag(id2, id1)).minDist;
00249             if (dist <= maxPathLen) result = true;
00250         } else if (commonAncestorGraph.hasEdge(id1, id2)) {
00251             int dist = ((Integer)commonAncestorGraph.getTag(id1, id2)).intValue();
00252             if (dist <= maxPathLen) result = true;
00253         }
00254 
00255         return result;
00256     }
00257 
00258     /*
00259      * Returns an ArrayList (AL) of AL of Component.
00260      *
00261      * Note that the linked list "comps" is be empty after this algorithm.
00262      * Complexity: O(m^2), where m = comps.size().
00263      *
00264      * maxPathLen restricts the max. length of pathes between components.
00265      */
00266     public ArrayList computeTransPiPartitions(LinkedList comps, int maxPathLen) {
00267     
00268         ArrayList result = new ArrayList();
00269 
00270         while (comps.size() > 0) {
00271          
00272             Component c = (Component)comps.removeFirst();
00273             ArrayList newPart = new ArrayList();
00274             newPart.add(c);
00275 
00276             boolean progress;
00277             do {
00278                 progress = false;
00279                 
00280                 Iterator itR = comps.iterator();
00281                 while (itR.hasNext()) {
00282                     Component cr = (Component)itR.next();
00283 
00284                     Iterator itP = newPart.iterator();
00285                     while (itP.hasNext()) {
00286                         Component cp = (Component)itP.next();
00287                         if (isAncestorConnected(cr, cp, maxPathLen)) {
00288                             newPart.add(cr);
00289                             itR.remove();
00290                             progress = true;
00291                             break;
00292                         }
00293                     }
00294                 }
00295 
00296 
00297             } while (progress);
00298    
00299             result.add(newPart);
00300 
00301         }  //  while (comps.size() > 0)      
00302 
00303         return result;
00304 
00305     }  // computeTransPiPartitions()
00306 }


tug_ist_diagnosis_engine
Author(s): Safdar Zaman, Gerald Steinbauer
autogenerated on Mon Jan 6 2014 11:51:16