需要帮助以找到最少的学期

时间:2019-03-24 15:00:30

标签: java topological-sort

我的作业问题提供了一些课程,有多少课程相互依赖。例如,第一个测试(课程,取决于):(1,3)(2,3)(4,1)(4,2),我们确定有5个课程和4个相互依赖(即为什么5不在列表中,它只是0)

从拓扑搜索中我知道,以下是有效的解决方案: 1 3 2 4 0

然后我需要打印出这些课程的学期数,由于它们之间的关系,我知道这是3个学期。首先,我们必须选择课程1和2才能达到3,并且由于我们已经拥有1,所以我们可以选择课程4。

所以我需要帮助弄清楚执行此操作的一些代码。那是我需要你们帮助的地方

我试图简单地计算已连接但失败的课程。我尝试过考虑可以做的事情,但实际上没有任何解决方法。

图形类:

public class Graph {

    int V;
    LinkedList<Integer> adjList[];

    public Graph(int vertex) {
        this.V = vertex;

        //We then define the num of vertexes in the adjlist
        adjList = new LinkedList[vertex];

        //Then create a new list for each vertex so we can create a link between the vertexes
        for (int i = 0; i < vertex; i++) {
            adjList[i] = new LinkedList<>();
        }
    }
    //Directed graph
    public void addEdge(int source, int destination) {
        //Add the edge from the source node to the destination node

        adjList[source].add(destination);
        adjList[destination].add(source);
    }

    //Method to print the graph if necessary
    public void printGraph(Graph graph) {
        for (int i = 0; i < graph.V; i++) {
            System.out.println("Adjacency list over vertex: " + i);
            System.out.print("head");

            for (Integer treeCrawler : graph.adjList[i]) {

                System.out.print("-> " + treeCrawler);
            }
            System.out.println("\n");
        }
    }

    public LinkedList<Integer>[] getAdjList() {
        return adjList;
    }
}

和拓扑排序类,我们用于解决问题的算法

public class TopologicalSort {

    int vertex;

    //This function helps the topological function recursively by marking the vertices and pushing them onto the stack
    public void topologicalHelper(int vertex, boolean marked[], Stack nodes, Graph graph) {

        List<Integer>[] list = graph.getAdjList();

        marked[vertex] = true;

        Iterator<Integer> iterator = list[vertex].iterator();
        while (iterator.hasNext()) {
            int temp = iterator.next();
            if (!marked[temp] && list[temp].size() != 0) {
                topologicalHelper(temp, marked, nodes, graph);
            }

        }
        nodes.add(vertex);
    }


    public TopologicalSort(Graph graph, int vertecies) {
        vertex = vertecies;
        Stack nodes = new Stack();
        boolean[] marked = new boolean[vertex];

        for (int i = 0; i < vertex; i++) {
            if (marked[i] == false) {
                topologicalHelper(i, marked, nodes, graph);
            }
        }
        while(!nodes.empty()) {
            System.out.print(nodes.pop() + " ");
        }
    }
}

结果应该为3,但是我尚未在所有解决方案构想中得出该数字,我需要一些帮助或提示。


哦,下面是控制台输出

Adjacency list over vertex: 0
head

Adjacency list over vertex: 1
head-> 3-> 4

Adjacency list over vertex: 2
head-> 3-> 4

Adjacency list over vertex: 3
head-> 1-> 2

Adjacency list over vertex: 4
head-> 1-> 2

1 3 2 4 0 

1 个答案:

答案 0 :(得分:0)

依赖关系是有向属性,因此您应该使用有向图。填充图形后,u最终将出现一个断开的图形,其中包含一棵或多棵树。找出哪些节点是每棵树的根,然后使用DFS获取每棵树的最大深度。假设每学期没有课程限制,那么所有树木的最大深度就是解决方案。

public class Graph {
int V;
ArrayList<Integer> adjList[];
boolean[] notRoot;
public Graph(int vertex) {
    this.V = vertex;
    adjList = new ArrayList[vertex];
    notRoot = new boolean[vertex];
    for (int i = 0; i < vertex; i++) {
        adjList[i] = new ArrayList<Integer>();
    }
}
public void addEdge(int a, int b) {
    //asuming b is dependent on a
    adjList[b].add(a);
    notRoot[a]=true;
}
int maxDepthDfs(int root){
    int depth=1;
    for(int i=0;i<adjList[root].size();i++){
        int child=adjList[root].get(i);
        depth=Math.max(maxDepthDfs(child)+1,depth);
    }
    return depth;
}
public int getSolution(){
    int ans=0;
    for(int i=0;i<V;i++){
        if(!notRoot[i])
            ans=Math.max(ans,maxDepthDfs(i));
    }
    return ans;
}
}

一种拓扑排序就是将节点添加到堆栈中的DFS(先添加节点的所有子节点,然后再添加根节点)。在Kahn的算法中,首先找到根元素(没有父节点的节点),然后仅调用该方法或那些节点。

int maxDepthDfs(int root){
//since we are only calling this function for root nodes we need not check if nodes were previously visited
int depth=1;
for(int i=0;i<adjList[root].size();i++){
    int child=adjList[root].get(i);
    depth=Math.max(maxDepthDfs(child)+1,depth);
}
s.push(root);
return depth;
}
public int getSolution(){
    s=new Stack<Integer>();
    int ans=0;
    for(int i=0;i<V;i++){
        if(!notRoot[i])
            ans=Math.max(ans,maxDepthDfs(i));
    }
    //stack s contains result of topological sort;
    return ans;
}