避免嵌套循环

时间:2019-03-21 03:58:02

标签: java

我试图避免使用嵌套循环并降低从On ^ 2开始的运行时间,该代码旨在实现一种有效的算法,以计算给定功能的所有路径。 I.深度优先遍历(DFS):实现必须遵循DFS 二。多重性的使用:跟踪每个节点的多重性 三,推送触发器:合并触发器以适当地将多样性从一个节点推送到其后继节点 IV。使用您的实现来列出XINU中所有XINU函数的路径计数。 V.将路径计数存储在电子表格中(使用ExportResults.export) VI。线性和正确性的证明:通过将实现与给定的实现(DFSPathCounter.java)进行比较来证明实现的正确性和线性,这是一种简单得多的指数路径计数算法。

public class DFSPathCounter extends PathCounter {

public DFSPathCounter() {}

/**
 * Counts the number of paths in a given CFG
 *
 * Example Atlas Shell Usage:
 * var dskqopt = functions("dskqopt")
 * var dskqoptCFG = cfg(dskqopt)
 * var dfsCounter = new DFSPathCounter
 * dfsCounter.countPaths(dskqoptCFG)
 *
 * @param cfg
 * @return
 */
public CountingResult countPaths(Q cfg) {
    // the total number of paths discovered
    // and the number of additions required to count the path
    long numPaths = 0;
    long additions = 0;

    // create a directed acyclic graph (DAG)
    DAGTransform transformer = new DAGTransform();
    Q dag = transformer.transform(cfg);

    // the roots and leaves of the DAG
    AtlasSet<Node> dagLeaves = dag.leaves().eval().nodes();
    Node dagRoot = dag.roots().eval().nodes().one();

    // handle some trivial edge cases
    if(dagRoot == null) {
        // function is empty, there are no paths
        return new CountingResult(0L,0L);
    } else if(dagLeaves.contains(dagRoot)) {
        // function contains a single node there must be 1 path
        return new CountingResult(0L,1L);
    }

    // stack for depth first search (DFS)
    Stack<Node> stack = new Stack<Node>();

    // start searching from the root
    stack.push(dagRoot);

    // depth first search on directed acyclic graph
    while (!stack.isEmpty()) {
        // next node to process
        Node currentNode = stack.pop();

        // get the children of the current node
        // note: we iterate by edge in case there are multiple edges from a predecessor to a successor
        for (Edge outgoingEdge : dag.forwardStep(Common.toQ(currentNode)).eval().edges()) {
            Node successor = outgoingEdge.to();
            if(dagLeaves.contains(successor)) {
                // if we reached a leaf increment the counter by 1
                numPaths++;
                additions++;
            } else {
                // push the child node on the stack to be processed
                stack.push(successor);
            }
        }
    }

    // at the end, we have traversed all paths once, so return the count
    return new CountingResult(additions, numPaths);
}

0 个答案:

没有答案
相关问题