// 判断是否是i是否在关键路径上,m_ve[i] == m_vl[i] public CriticalPath(IDirectedGraph digraph) { var topology = new TopologicalAOE(digraph); if (!topology.IsDAG()) { throw new ArgumentException("不能获取拓扑排序"); } var ve = topology.GetVE(); // m_ve[i] 表示顶点编号i的最早开始时间 var vl = new int[digraph.V]; // 最晚发生 var topAOEOrder = topology.Order(); // 这个最终返回的拓扑排序,但是是从最后一个元素到起点的顺序。 for (int i = 0; i < vl.Length; ++i) { vl[i] = ve[digraph.V - 1];//保存为终点的最大的时间 } while (topAOEOrder.Count > 0) { int v = topAOEOrder.Pop();// 获取检测的点 foreach (var arc in digraph.GetEdge(v)) { int w = arc.Other(v); int weight = (int)arc.Weight; if (vl[w] - weight < vl[v]) { vl[v] = vl[w] - weight; } } } m_criticalPaths = new List <string>(); for (int j = 0; j < digraph.V; ++j) { foreach (var arc in digraph.GetEdge(j)) { int w = arc.Other(j); int weight = (int)arc.Weight; int ee = ve[j]; int el = vl[w] - weight; // 后继的节点 - 边表示这个活动可以最晚开始的时间 char c = (ee == el) ? '*' : '\0'; //是否是关键路径。也就是如果最晚开始的时间和最早开始的时间相同。 m_criticalPaths.Add($"{j}--{weight}-->{w} {c}"); } } }
public EdgeType GetEdge(NodeType source, NodeType target) { EdgeType edge = graph.GetEdge(source, target); if (predicate(edge)) { return(edge); } else { throw new EdgeNotFoundException(source, target); } }
private void solve(IDirectedGraph g) { // 度的信息 int count = 0; // 顶点计数 Stack <int> S = new Stack <int>(), T = new Stack <int>(); // 储存入度为0的点,拓扑顶点序列 Degrees degrees_info = new Degrees(g); int[] degrees = new int[g.V]; for (int i = 0; i < g.V; ++i) { degrees[i] = degrees_info.InDegree(i); if (degrees[i] == 0) { S.Push(i); } } while (S.Count > 0) { int v = S.Pop(); T.Push(v); // 这个是起始 ++count; foreach (var arc in g.GetEdge(v)) { // 遍历所有的边 int w = arc.Other(v); if (--degrees[w] == 0) { S.Push(w); //下一个入点被钦定 } if (m_ve[v] + arc.Weight > m_ve[w]) // 如果 w 可以尽量晚开始,那就 { m_ve[w] = m_ve[v] + (int)arc.Weight; } } } if (count >= g.V) { result = T; } }
public void AddClause(IClause clause) { if (clause == null) { return; } _satisfiedLiterals.Clear(); if (clause.Head != null && clause.Head.Negated && clause.Body.Count > 0) { var newClause = new Clause(new Literal(clause.Head.NegatedValue())); foreach (var literal in clause.Body) { newClause.Body.Add(new Literal(literal.NegatedValue())); } AddClause(newClause); return; } var headNode = clause.Head != null ? (_graph.GetNode(clause.Head.Value) ?? _graph.AddNode(clause.Head.Negated ? (ILogicNode) new ClauseNode(clause.Head.Value) : new LiteralNode(clause.Head.Value)).GetNode(clause.Head.Value)) : null; if (clause.Body.Count < 1) { if (headNode == null) { throw new NullReferenceException("Clause Head is null"); } headNode.Fact = true; } else if (clause.Body.Count == 1) { if (clause.Head == null) { throw new NullReferenceException("Clause Head is null"); } var literal = clause.Body.First(); if (clause.Head.Value != literal.Value) { var node = _graph.GetNode(literal.Value) ?? _graph.AddNode(literal.Negated ? (ILogicNode) new ClauseNode(literal.Value) : new LiteralNode(literal.Value)).GetNode(literal.Value); if (_graph.GetEdge(headNode, node) == null) { _graph.AddEdge(new DirectedEdge <ILogicNode> (headNode, node)); } } } else if (clause.Body.Count > 1) { if (clause.Head != null) { var literals = clause.Body.Where(literal => clause.Head.Value != literal.Value).ToList(); if (literals.Count > 0) { var clauseKey = ClauseKey(literals); var clauseNode = _graph.GetNode(clauseKey) ?? _graph.AddNode(new ClauseNode(clauseKey)).GetNode(clauseKey); if (_graph.GetEdge(headNode, clauseNode) == null) { _graph.AddEdge(new DirectedEdge <ILogicNode> (headNode, clauseNode)); } foreach (var literalNode in literals.Select(literal => _graph.GetNode(literal.Value) ?? _graph.AddNode(literal.Negated ? (ILogicNode) new ClauseNode(literal.Value) : new LiteralNode(literal.Value)).GetNode(literal.Value)).Where(literalNode => _graph.GetEdge(clauseNode, literalNode) == null)) { _graph.AddEdge(new WeightedDirectedEdge <ILogicNode> (clauseNode, literalNode, 1)); } } } else { var disjointLiteralKey = DisjointLiteralKey(clause.Body); var disjointLiteral = _graph.GetNode(disjointLiteralKey) ?? _graph.AddNode(new LiteralNode(disjointLiteralKey)).GetNode(disjointLiteralKey); foreach (var literalNode in clause.Body.Select(literal => _graph.GetNode(literal.Value) ?? _graph.AddNode(literal.Negated ? (ILogicNode) new ClauseNode(literal.Value) : new LiteralNode(literal.Value)).GetNode(literal.Value)).Where(literalNode => _graph.GetEdge(disjointLiteral, literalNode) == null)) { _graph.AddEdge(new DirectedEdge <ILogicNode>(disjointLiteral, literalNode)); } } } var negated = clause.Head != null ? new Clause(new Literal(clause.Head.NegatedValue())) : new Clause(); foreach (var dependency in clause.Body) { negated.Body.Add(new Literal(dependency.NegatedValue())); } AddNegatedClause(negated); if (headNode != null && negated.Head != null) { var negatedHeadNode = _graph.GetNode(negated.Head.Value); if (negatedHeadNode != null) { if (headNode.Fact && negatedHeadNode.Fact) { throw new Exception("KB is inconsistent, " + headNode.Id + " and " + negatedHeadNode.Id + " are both facts!"); } if (clause.Body.Count > 0) { var nodesA = clause.Body.Select(literal => _graph.GetNode(literal.Value)); var nodesB = clause.Body.Select(literal => _graph.GetNode(literal.NegatedValue())); if (SharedAncestor(nodesA, nodesB)) { Console.WriteLine("Adding " + clause.ToProperString() + " will cause conflict skipping clause..."); RemoveClause(clause); } } } } if (headNode != null && headNode.Fact) { FactFlow(headNode); } if (clause.Body.Count > 0) { foreach (var node in clause.Body.Select(literal => _graph.GetNode(literal.Value)).Where(node => node.Fact)) { FactFlow(node); } foreach (var node in clause.Body.Select(literal => _graph.GetNode(literal.NegatedValue())).Where(node => node.Fact)) { FactFlow(node); } } }