java 路径算法_java – 关键路径方法算法

以下是基于

this page提供的解释的算法实现

有一个包装类可以保存任务,成本和关键路径成本.首先,将关键成本计算为所有依赖关系的最大临界成本加上自己的成本.然后,一旦关键成本可用,它就会使用比较器根据关键成本对任务进行排序,并将依赖关系作为平局(如果没有依赖关系则随机选择).请注意,如果存在循环,则会抛出异常,如果任何成本为负,则会失败.

这是实施:

public class CriticalPath {

public static void main(String[] args) {

//The example dependency graph from

//http://www.ctl.ua.edu/math103/scheduling/scheduling_algorithms.htm

HashSet allTasks = new HashSet();

Task end = new Task("End", 0);

Task F = new Task("F", 2, end);

Task A = new Task("A", 3, end);

Task X = new Task("X", 4, F, A);

Task Q = new Task("Q", 2, A, X);

Task start = new Task("Start", 0, Q);

allTasks.add(end);

allTasks.add(F);

allTasks.add(A);

allTasks.add(X);

allTasks.add(Q);

allTasks.add(start);

System.out.println("Critical Path: "+Arrays.toString(criticalPath(allTasks)));

}

//A wrapper class to hold the tasks during the calculation

public static class Task{

//the actual cost of the task

public int cost;

//the cost of the task along the critical path

public int criticalCost;

//a name for the task for printing

public String name;

//the tasks on which this task is dependant

public HashSet dependencies = new HashSet();

public Task(String name, int cost, Task... dependencies) {

this.name = name;

this.cost = cost;

for(Task t : dependencies){

this.dependencies.add(t);

}

}

@Override

public String toString() {

return name+": "+criticalCost;

}

public boolean isDependent(Task t){

//is t a direct dependency?

if(dependencies.contains(t)){

return true;

}

//is t an indirect dependency

for(Task dep : dependencies){

if(dep.isDependent(t)){

return true;

}

}

return false;

}

}

public static Task[] criticalPath(Set tasks){

//tasks whose critical cost has been calculated

HashSet completed = new HashSet();

//tasks whose ciritcal cost needs to be calculated

HashSet remaining = new HashSet(tasks);

//Backflow algorithm

//while there are tasks whose critical cost isn't calculated.

while(!remaining.isEmpty()){

boolean progress = false;

//find a new task to calculate

for(Iterator it = remaining.iterator();it.hasNext();){

Task task = it.next();

if(completed.containsAll(task.dependencies)){

//all dependencies calculated, critical cost is max dependency

//critical cost, plus our cost

int critical = 0;

for(Task t : task.dependencies){

if(t.criticalCost > critical){

critical = t.criticalCost;

}

}

task.criticalCost = critical+task.cost;

//set task as calculated an remove

completed.add(task);

it.remove();

//note we are making progress

progress = true;

}

}

//If we haven't made any progress then a cycle must exist in

//the graph and we wont be able to calculate the critical path

if(!progress) throw new RuntimeException("Cyclic dependency, algorithm stopped!");

}

//get the tasks

Task[] ret = completed.toArray(new Task[0]);

//create a priority list

Arrays.sort(ret, new Comparator() {

@Override

public int compare(Task o1, Task o2) {

//sort by cost

int i= o2.criticalCost-o1.criticalCost;

if(i != 0)return i;

//using dependency as a tie breaker

//note if a is dependent on b then

//critical cost a must be >= critical cost of b

if(o1.isDependent(o2))return -1;

if(o2.isDependent(o1))return 1;

return 0;

}

});

return ret;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
关键路径算法是一种用于确定项目中关键任务和最短完成时间的方法。在Java中,可以使用图论和拓扑排序的思想来实现关键路径算法。以下是一个简单的Java实现示例: ```java import java.util.*; public class CriticalPath { private int V; // 顶点数 private LinkedList<Integer>[] adj; // 邻接表 private int[] indegree; // 入度数组 private int[] earliest; // 最早开始时间数组 private int[] latest; // 最晚开始时间数组 public CriticalPath(int V) { this.V = V; adj = new LinkedList[V]; indegree = new int[V]; earliest = new int[V]; latest = new int[V]; for (int i = 0; i < V; i++) { adj[i] = new LinkedList<>(); } } public void addEdge(int u, int v) { adj[u].add(v); indegree[v]++; } public void findCriticalPath() { // 计算最早开始时间 calculateEarliest(); // 计算最晚开始时间 calculateLatest(); // 打印关键路径 printCriticalPath(); } private void calculateEarliest() { Queue<Integer> queue = new LinkedList<>(); for (int i = 0; i < V; i++) { if (indegree[i] == 0) { queue.add(i); earliest[i] = 0; } } while (!queue.isEmpty()) { int u = queue.poll(); for (int v : adj[u]) { indegree[v]--; if (indegree[v] == 0) { queue.add(v); } earliest[v] = Math.max(earliest[v], earliest[u] + 1); } } } private void calculateLatest() { int lastVertex = V - 1; latest[lastVertex] = earliest[lastVertex]; for (int u = lastVertex - 1; u >= 0; u--) { for (int v : adj[u]) { latest[u] = Math.min(latest[u], latest[v] - 1); } } } private void printCriticalPath() { System.out.println("关键路径为:"); for (int u = 0; u < V; u++) { for (int v : adj[u]) { if (earliest[u] == latest[u]) { System.out.println(u + " -> " + v); } } } } public static void main(String[] args) { int V = 6; // 顶点数 CriticalPath graph = new CriticalPath(V); // 添加边 graph.addEdge(0, 1); graph.addEdge(0, 2); graph.addEdge(1, 3); graph.addEdge(2, 3); graph.addEdge(2, 4); graph.addEdge(3, 5); graph.addEdge(4, 5); // 执行关键路径算法 graph.findCriticalPath(); } } ``` 这是一个简单的关键路径算法Java实现示例。它使用邻接表来表示有向无环图,并使用拓扑排序的思想计算最早开始时间和最晚开始时间。最后,根据最早开始时间和最晚开始时间的比较,找出关键路径并打印出来。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值