private static BidirectionalGraph<string, Edge<string>> GenerateJarDependencyGraph(JarAnalyzer jars) { BidirectionalGraph<string, Edge<string>> g = new BidirectionalGraph<string, Edge<string>>(true); foreach(Jar jar in jars.Jars) { g.AddVertex(jar.name); } foreach (Jar jar in jars.Jars) { if (jar.Summary.OutgoingDependencies.Jar != null) { foreach (Jar dstJar in jar.Summary.OutgoingDependencies.Jar) { bool exist = false; foreach (IEdge<string> edge in g.InEdges(dstJar.Text[0])) { if (edge.Source == jar.name) { exist = true; } } if (!g.InEdges(dstJar.Text[0]).Any(v => v.Source == jar.name)) { g.AddEdge(new Edge<string>(dstJar.Text[0], jar.name)); } else { Trace.WriteLine("Warning: loop detected, skipping dependency " + dstJar.Text[0] + " -> " + jar.name); } } } } return g; }
public void actualizarCorr() { int corr = 1; //Recorriendo matriz posición for (int x = 0; x < 10; x++) { for (int y = 0; y < 7; y++) { //Si la posición actual contiene una materia if (positionMatrix[x, y] != null) { //Si el correlativo de la materia ha cambiado if (positionMatrix[x, y].Corr != corr) { //Obteniendo correlativos de los prerrequisitos de la materia string prerreqCorrs = ""; foreach (Edge <NetNode> edge in pensum.InEdges(positionMatrix[x, y])) { prerreqCorrs += edge.Source.Corr + ","; } if (!prerreqCorrs.Equals("")) { prerreqCorrs = prerreqCorrs.Substring(0, prerreqCorrs.Length - 1); //Eliminando coma del final } positionMatrix[x, y].setCorr(corr, prerreqCorrs); //Actualizando correlativos del nodo } corr++; } } } //Recorriendo matriz posición de materias optativas for (int x = 0; x < 2; x++) { for (int y = 0; y < 3; y++) { //Si la posición actual contiene una materia if (ventanaOptativas.positionMatrix[x, y] != null) { //Si el correlativo de la materia ha cambiado if (ventanaOptativas.positionMatrix[x, y].Corr != corr) { //Obteniendo correlativos de los prerrequisitos de la materia string prerreqCorrs = ""; foreach (Edge <NetNode> edge in pensum.InEdges(ventanaOptativas.positionMatrix[x, y])) { prerreqCorrs += edge.Source.Corr + ","; } if (!prerreqCorrs.Equals("")) { prerreqCorrs = prerreqCorrs.Substring(0, prerreqCorrs.Length - 1); //Eliminando coma del final } ventanaOptativas.positionMatrix[x, y].setCorr(corr, prerreqCorrs); //Actualizando correlativos del nodo } corr++; } } } }
/// <summary> /// Generate file containing command lines to run ikvmc including names of referenced dlls. /// </summary> /// <param name="g"></param> /// <param name="path"></param> private static void GenerateIkvmcRunScript(BidirectionalGraph<string, Edge<string>> g, string path) { StreamWriter sw = new StreamWriter(path); foreach (string vertex in AlgoUtility.TopologicalSort<string, Edge<string>>(g)) { IEnumerable<string> names = g.InEdges(vertex).Select<Edge<string>, string>(item => item.Source); string references = ""; foreach(string name in names) { references += " -r:" + name.Replace(".jar", ".dll"); } string commandLine = "ikvmc " + vertex + " -target:library" + references; sw.WriteLine(commandLine); } sw.Close(); }
/// <summary> /// Attempts to break cycles in the graph by removing the deepest remove edge, as defined /// by the supplied predicate function. /// </summary> /// <param name="graph">The bidirectional graph to be processed.</param> /// <param name="isRemovable">A function indicating whether or not a particular edge can be removed (i.e. is a "soft" dependency).</param> /// <typeparam name="TVertex">The <see cref="Type" /> of the vertices of the graph.</typeparam> /// <typeparam name="TEdge">The <see cref="Type" /> of the edges of the graph.</typeparam> /// <returns>The list of edges that were removed to break the cycle(s).</returns> /// <exception cref="NonAcyclicGraphException">Occurs if one or more of the cycles present in the graph cannot be broken by removing one of its edges.</exception> public static IReadOnlyList <TEdge> BreakCycles <TVertex, TEdge>(this BidirectionalGraph <TVertex, TEdge> graph, Func <TEdge, bool> isRemovable) where TEdge : IEdge <TVertex> { var removedEdges = new List <TEdge>(); // Get cyclical dependencies found in the graph var cycles = graph.GetCycles(); // Break circular dependencies foreach (var cycle in cycles) { // Last element of Path repeats first element (so ignore duplicate) var distinctPathVertices = cycle.Path.Take(cycle.Path.Count - 1).ToArray(); var sacrificialDependency = distinctPathVertices .Select( (e, i) => { // Get the next entity in the path (circling around to the first entity on the last item) var dependentVertex = distinctPathVertices[(i + 1) % distinctPathVertices.Length]; return(new { DependentVertex = dependentVertex, CycleEdges = graph.InEdges(dependentVertex).Where(IsCycleEdge) }); }) .Reverse() .FirstOrDefault(x => x.CycleEdges.All(isRemovable)); if (sacrificialDependency == null) { graph.ValidateGraph(); // Should never get here in this situation, but throw an exception to satisfy code analysis warnings throw new NonAcyclicGraphException(); } // Remove the chosen graph edge(s) to break the cyclical dependency foreach (TEdge edge in sacrificialDependency.CycleEdges.ToArray()) { if (_logger.IsDebugEnabled) { _logger.Debug($"Edge '{edge.ToString()}' removed to prevent the following cycle: {string.Join(" --> ", cycle.Path.Select(x => x.ToString()))}"); } graph.RemoveEdge(edge); removedEdges.Add(edge); } bool IsCycleEdge(TEdge edge) => distinctPathVertices.Contains(edge.Source); } if (_logger.IsDebugEnabled) { _logger.Debug($@"The following edges were removed from the graph to prevent cycles: {string.Join(Environment.NewLine, removedEdges.Select(x => x.ToString()))}"); } return(removedEdges); }
public IEnumerable <TEdge> GetInEdges(TVertexId vertexId) => _graph.InEdges(vertexId).Select(FromVertexIdEdge);
/// <summary> /// Inserts the given vertex in the position of the given insert vertex. The insert vertex will /// be removed if it has no more inserts left. /// </summary> /// <param name="insertVertex">The vertex which will be replaced.</param> /// <param name="vertexToInsert">The new vertex.</param> /// <returns>A tuple containing the insert vertices that were place before and after the newly inserted vertex.</returns> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="insertVertex"/> is <see langword="null" />. /// </exception> /// <exception cref="UnknownScheduleVertexException"> /// Thrown if <paramref name="insertVertex"/> does not exist in the current schedule. /// </exception> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="vertexToInsert"/> is <see langword="null" />. /// </exception> /// <exception cref="CannotInsertExistingVertexException"> /// Thrown if <paramref name="vertexToInsert"/> already exists in the schedule. /// </exception> /// <exception cref="NoInsertsLeftOnVertexException"> /// Thrown if <paramref name="insertVertex"/> has no more inserts left. /// </exception> public Tuple <InsertVertex, InsertVertex> InsertIn( InsertVertex insertVertex, IScheduleVertex vertexToInsert) { { Lokad.Enforce.Argument(() => insertVertex); Lokad.Enforce.With <UnknownScheduleVertexException>( m_Schedule.ContainsVertex(insertVertex), Resources.Exceptions_Messages_UnknownScheduleVertex); Lokad.Enforce.Argument(() => vertexToInsert); Lokad.Enforce.With <CannotInsertExistingVertexException>( !m_Schedule.ContainsVertex(vertexToInsert), Resources.Exceptions_Messages_CannotInsertExistingVertex); Lokad.Enforce.With <NoInsertsLeftOnVertexException>( (insertVertex.RemainingInserts == -1) || (insertVertex.RemainingInserts > 0), Resources.Exceptions_Messages_NoInsertsLeftOnVertex); } // Find the inbound and outbound edges var inbound = from edge in m_Schedule.InEdges(insertVertex) select edge; var outbound = from edge in m_Schedule.OutEdges(insertVertex) select edge; // Add the new node m_Schedule.AddVertex(vertexToInsert); // Create two new insert vertices to be placed on either side of the new vertex var count = (insertVertex.RemainingInserts != -1) ? insertVertex.RemainingInserts - 1 : -1; InsertVertex inboundInsert = null; InsertVertex outboundInsert = null; if ((count == -1) || (count > 0)) { inboundInsert = new InsertVertex(m_Schedule.VertexCount, count); m_Schedule.AddVertex(inboundInsert); m_Schedule.AddEdge(new ScheduleEdge(inboundInsert, vertexToInsert, null)); outboundInsert = new InsertVertex(m_Schedule.VertexCount, count); m_Schedule.AddVertex(outboundInsert); m_Schedule.AddEdge(new ScheduleEdge(vertexToInsert, outboundInsert, null)); } // Reconnect all the edges var inboundTarget = inboundInsert ?? vertexToInsert; var outboundSource = outboundInsert ?? vertexToInsert; foreach (var inboundEdge in inbound) { m_Schedule.AddEdge(new ScheduleEdge(inboundEdge.Source, inboundTarget, inboundEdge.TraversingCondition)); } foreach (var outboundEdge in outbound) { m_Schedule.AddEdge(new ScheduleEdge(outboundSource, outboundEdge.Target, outboundEdge.TraversingCondition)); } // Lastly remove the current insert node, which also destroys all the edges that are // connected to it. m_Schedule.RemoveVertex(insertVertex); return(new Tuple <InsertVertex, InsertVertex>(inboundInsert, outboundInsert)); }
public void ReadGraph(TextReader reader) { var g = new BidirectionalGraph<MyType, IEdge<MyType>>(); try { var csv = new CsvHelper.CsvReader(reader); while (csv.Read()) { if (!csv.CurrentRecord.Any()) { continue; } var node = csv.CurrentRecord.First(); var edges = csv.CurrentRecord.Skip(1) .Where(x => !string.IsNullOrEmpty(x)) .Select(x => x.Trim()) .Where(x => !string.IsNullOrEmpty(x)); foreach (var edge in edges) { g.AddVerticesAndEdge(new Edge<MyType>(node, edge)); } } var dict = new Dictionary<int, HashSet<MyType>>(); HashSet<MyType> set; foreach (var v in g.Vertices) { var edgeCount = g.InEdges(v).Count(); if (!dict.TryGetValue(edgeCount, out set)) { set = new HashSet<MyType>(); dict.Add(edgeCount, set); } set.Add(v); } Graph = g; Summary = string.Join(Environment.NewLine, dict .OrderBy(kvp => kvp.Key) .Select(kvp => kvp.Key + ": " + string.Join(", ", kvp.Value))) + Environment.NewLine + Environment.NewLine + string.Join(Environment.NewLine, g.Vertices .Where(v => g.OutEdges(v).Count() != 3) .Select(v => v + ": " + g.OutEdges(v).Count())); //Summary = string.Join( // Environment.NewLine, // graph.Vertices // .OrderBy(x => graph.InEdges(x).Count()) // .Select(v => v + ": " + graph.InEdges(v).Count())); } catch (Exception e) { Summary = "Failed to read:" + Environment.NewLine + e; } }
private WordPair createNewGreenEdges(Word uWord, Word kWord, BidirectionalGraph <Word, Edge <Word> > graph) { Cache1.Clear(); List <SPath> paths = new List <SPath>(); foreach (var item in graph.OutEdges(uWord)) { SLink linkCU = new SLink(item.Target, uWord); linkCU.Exists = graph.ContainsEdge(uWord, item.Target); SLink linkCK = new SLink(item.Target, kWord); linkCK.Exists = graph.ContainsEdge(item.Target, kWord); SPath path = new SPath(linkCU, linkCK); paths.Add(path); Cache1.Add(item.Target.ID, true); } foreach (var item in graph.InEdges(kWord)) { if (Cache1.ContainsKey(item.Source.ID)) { continue; } SLink linkCK = new SLink(item.Source, kWord); linkCK.Exists = graph.ContainsEdge(item.Source, kWord); SLink linkCU = new SLink(item.Source, uWord); linkCU.Exists = graph.ContainsEdge(uWord, item.Source); SPath path = new SPath(linkCU, linkCK); paths.Add(path); } //calculate probability float pUK = 0; float pKU = 0; float probUK = 0; float probKU = 0; foreach (var item in paths) { if (!item.LinkCU.Exists || !item.LinkCK.Exists) //containing non-existance link { continue; } float PrCU = 0.0f; float PrKC = 0.0f; float PrCK = 0.0f; float PrUC = 0.0f; foreach (var downEdgeCU in graph.OutEdges(item.LinkCU.WordNonPivot)) //Loop through down-path from nonpivot1 to pivot { PrCU += 1.0f / LinkWeightCache[new SLink(downEdgeCU.Target, downEdgeCU.Source)]; //P(C|U) = P(C&U)/P(U) } foreach (var downEdgeCK in graph.OutEdges(item.LinkCK.WordPivot)) //Loop through down-path from pivot to nonpivot2 { PrKC += 1.0f / LinkWeightCache[new SLink(downEdgeCK.Source, downEdgeCK.Target)]; //P(K|C) = P(K&C)/P(C) } foreach (var upEdgeCK in graph.InEdges(item.LinkCK.WordNonPivot)) //Loop through up-path from nonpivot2 to pivot { PrCK += 1.0f / LinkWeightCache[new SLink(upEdgeCK.Source, upEdgeCK.Target)]; //P(C|K) = P(C&K)/P(K) } foreach (var upEdgeCU in graph.InEdges(item.LinkCU.WordPivot)) //Loop through up-path from pivot to nonpivot1 { PrUC += 1.0f / LinkWeightCache[new SLink(upEdgeCU.Target, upEdgeCU.Source)]; //P(U|C) = P(U&C)/P(C) } PrCU = 1.0f / PrCU; PrKC = 1.0f / PrKC; PrCK = 1.0f / PrCK; PrUC = 1.0f / PrUC; pUK += PrUC * PrCK; pKU += PrKC * PrCU; } probUK = pUK * pKU; WordPair pair = new WordPair(uWord, kWord); pair.Paths = paths; pair.Prob = (float)probUK; //set link weights foreach (var item in pair.Paths) { //CU if (!item.LinkCU.Exists) { float value = 0; if (LinkWeightCache.TryGetValue(item.LinkCU, out value)) { if (pair.Prob > value) { item.LinkCU.Pr = LinkWeightCache[item.LinkCU] = pair.Prob; } else { item.LinkCU.Pr = value; } } else { item.LinkCU.Pr = pair.Prob; LinkWeightCache.Add(item.LinkCU, pair.Prob); } } //CK if (!item.LinkCK.Exists) { float value = 0; if (LinkWeightCache.TryGetValue(item.LinkCK, out value)) { if (pair.Prob > value) { LinkWeightCache[item.LinkCK] = item.LinkCK.Pr = pair.Prob; } else { item.LinkCK.Pr = value; } } else { item.LinkCK.Pr = pair.Prob; LinkWeightCache.Add(item.LinkCK, pair.Prob); } } } return(pair); }
private WordPair createNewEdges(Word uWord, Word kWord, BidirectionalGraph <Word, Edge <Word> > semiCompleteGraph, BidirectionalGraph <Word, Edge <Word> > completeGraph)//, int uCount, int kCount) { Cache1.Clear(); List <SPath> paths = new List <SPath>(); WordPair pair = new WordPair(uWord, kWord); pair.Polysemy = 0f; foreach (var item in semiCompleteGraph.OutEdges(uWord)) // Using the updated graph with new edges { int inDegreePivot = (int)semiCompleteGraph.InDegree(item.Target); int outDegreePivot = (int)semiCompleteGraph.OutDegree(item.Target); int totalSenseEdge = (Math.Max(inDegreePivot, outDegreePivot) - 1) * (inDegreePivot + outDegreePivot); pair.Polysemy += totalSenseEdge; //Word pivot_sense = item.Target; //for (int sense = 1; sense <= totalSense; sense++) //{ //pivot_sense.Value = pivot_sense.Value + "_sense" + sense; SLink linkCU = new SLink(item.Target, uWord); linkCU.Exists = true;// semiCompleteGraph.ContainsEdge(uWord, pivot_sense); SLink linkCK = new SLink(item.Target, kWord); linkCK.Exists = semiCompleteGraph.ContainsEdge(item.Target, kWord); SPath path = new SPath(linkCU, linkCK); paths.Add(path); Cache1.Add(item.Target.ID, true); //} } foreach (var item in semiCompleteGraph.InEdges(kWord)) // Using the updated graph with new edges { if (Cache1.ContainsKey(item.Source.ID)) { continue; } int inDegreePivot = (int)semiCompleteGraph.InDegree(item.Source); int outDegreePivot = (int)semiCompleteGraph.OutDegree(item.Source); int totalSenseEdge = (Math.Max(inDegreePivot, outDegreePivot) - 1) * (inDegreePivot + outDegreePivot); pair.Polysemy += totalSenseEdge; SLink linkCK = new SLink(item.Source, kWord); linkCK.Exists = true;// semiCompleteGraph.ContainsEdge(item.Source, kWord); SLink linkCU = new SLink(item.Source, uWord); linkCU.Exists = semiCompleteGraph.ContainsEdge(uWord, item.Source); SPath path = new SPath(linkCU, linkCK); paths.Add(path); } //calculate probability //float couverage = Math.Min(uCount, kCount) / (float)Math.Max(uCount, kCount); float pUK = 0; float pKU = 0; float probUK = 0; float probKU = 0; //bool hasPolysemy = false; foreach (var item in paths) { //if (!item.LinkCU.Exists || !item.LinkCK.Exists) //containning non-existance link if (!item.LinkCU.Exists) { if (languageOption == 2) { completeGraph.AddEdge(new Edge <Word>(item.LinkCU.WordNonPivot, item.LinkCU.WordPivot)); } continue; } if (!item.LinkCK.Exists) { if (languageOption == 2) { completeGraph.AddEdge(new Edge <Word>(item.LinkCK.WordPivot, item.LinkCK.WordNonPivot)); } continue; } //if ((float)graph.InDegree(item.LinkCU.WordPivot) > 1 || (float)graph.OutDegree(item.LinkCK.WordPivot) > 1) // hasPolysemy = true; if (currentCycle == 1) { float PrCU = 1.0f / (float)semiCompleteGraph.OutDegree(item.LinkCU.WordNonPivot); //P(C|U) = P(C&U)/P(U) float PrKC = 1.0f / (float)semiCompleteGraph.OutDegree(item.LinkCK.WordPivot); //P(K|C) = P(K&C)/P(C) float PrCK = 1.0f / (float)semiCompleteGraph.InDegree(item.LinkCK.WordNonPivot); //P(C|K) = P(C&K)/P(K) float PrUC = 1.0f / (float)semiCompleteGraph.InDegree(item.LinkCU.WordPivot); //P(U|C) = P(U&C)/P(C) pKU += PrCU * PrKC; pUK += PrCK * PrUC; } else { float PrCU = 0.0f; float PrKC = 0.0f; float PrCK = 0.0f; float PrUC = 0.0f; foreach (var downEdgeCU in semiCompleteGraph.OutEdges(item.LinkCU.WordNonPivot)) //Loop through down-path from nonpivot1 to pivot { PrCU += 1.0f / LinkWeightCache[new SLink(downEdgeCU.Target, downEdgeCU.Source)]; //P(C|U) = P(C&U)/P(U) } foreach (var downEdgeCK in semiCompleteGraph.OutEdges(item.LinkCK.WordPivot)) //Loop through down-path from pivot to nonpivot2 { PrKC += 1.0f / LinkWeightCache[new SLink(downEdgeCK.Source, downEdgeCK.Target)]; //P(K|C) = P(K&C)/P(C) } foreach (var upEdgeCK in semiCompleteGraph.InEdges(item.LinkCK.WordNonPivot)) //Loop through up-path from nonpivot2 to pivot { PrCK += 1.0f / LinkWeightCache[new SLink(upEdgeCK.Target, upEdgeCK.Source)]; //P(C|K) = P(C&K)/P(K) } foreach (var upEdgeCU in semiCompleteGraph.InEdges(item.LinkCU.WordPivot)) //Loop through up-path from pivot to nonpivot1 { PrUC += 1.0f / LinkWeightCache[new SLink(upEdgeCU.Source, upEdgeCU.Target)]; //P(U|C) = P(U&C)/P(C) } PrCU = 1.0f / PrCU; PrKC = 1.0f / PrKC; PrCK = 1.0f / PrCK; PrUC = 1.0f / PrUC; pUK += PrUC * PrCK; pKU += PrKC * PrCU; } } probUK = pUK * pKU; //WordPair pair = new WordPair(uWord, kWord); //pair.HasMissingEdge = hasPolysemy; pair.Paths = paths; pair.Prob = (float)probUK; pair.Polysemy *= (1 - pair.Prob); //set link weights foreach (var item in pair.Paths) { //CU //float polysemyCost = 1 / ((float)graph.InDegree(item.LinkCU.WordPivot) * (float)graph.OutDegree(item.LinkCK.WordPivot)); if (item.LinkCU.Exists) { item.LinkCU.Pr = 1f; //polysemyCost; if (!LinkWeightCache.ContainsKey(item.LinkCU)) { LinkWeightCache.Add(item.LinkCU, item.LinkCU.Pr); } } else { //pair.HasMissingCUEdge = true; float value = 0; if (LinkWeightCache.TryGetValue(item.LinkCU, out value)) { if (pair.Prob > value) { item.LinkCU.Pr = LinkWeightCache[item.LinkCU] = pair.Prob; //polysemyCost * } else { item.LinkCU.Pr = value; } } else { item.LinkCU.Pr = pair.Prob; //polysemyCost * LinkWeightCache.Add(item.LinkCU, pair.Prob); } } //CK if (item.LinkCK.Exists) //false)// { item.LinkCK.Pr = 1f; //polysemyCost if (!LinkWeightCache.ContainsKey(item.LinkCK)) { LinkWeightCache.Add(item.LinkCK, item.LinkCK.Pr); } } else { float value = 0; if (LinkWeightCache.TryGetValue(item.LinkCK, out value)) { if (pair.Prob > value) { LinkWeightCache[item.LinkCK] = item.LinkCK.Pr = pair.Prob; //polysemyCost * } else { item.LinkCK.Pr = value; } } else { item.LinkCK.Pr = pair.Prob; //polysemyCost * LinkWeightCache.Add(item.LinkCK, pair.Prob); } } } return(pair); }
/// <summary> /// Traverses the schedule and applies an action to each vertex visited. /// </summary> /// <param name="start">The vertex where the traverse should be started.</param> /// <param name="vertexAction"> /// The action taken for each vertex that is encountered. The action is provided with the current vertex and /// a collection of all outbound, if <paramref name="traverseViaOutBoundVertices"/> is <see langword="true" />, /// or inbound vertices and the ID of the traversing condition. The function should return <see langword="false" /> /// to terminate the traverse. /// </param> /// <param name="traverseViaOutBoundVertices"> /// A flag indicating if the schedule should be traversed via the outbound edges of the vertices, or the inbound ones. /// </param> public void TraverseAllScheduleVertices( IScheduleVertex start, Func <IScheduleVertex, IEnumerable <Tuple <ScheduleElementId, IScheduleVertex> >, bool> vertexAction, bool traverseViaOutBoundVertices = true) { { Lokad.Enforce.Argument(() => start); Lokad.Enforce.With <UnknownScheduleVertexException>( m_Graph.ContainsVertex(start), Resources.Exceptions_Messages_UnknownScheduleVertex); Lokad.Enforce.Argument(() => vertexAction); } var nodeCounter = new List <IScheduleVertex>(); var uncheckedVertices = new Queue <IScheduleVertex>(); uncheckedVertices.Enqueue(start); while (uncheckedVertices.Count > 0) { var source = uncheckedVertices.Dequeue(); if (nodeCounter.Contains(source)) { continue; } nodeCounter.Add(source); var outEdges = traverseViaOutBoundVertices ? m_Graph.OutEdges(source) : m_Graph.InEdges(source); var traverseMap = from edge in outEdges select new Tuple <ScheduleElementId, IScheduleVertex>( edge.TraversingCondition, traverseViaOutBoundVertices ? edge.Target : edge.Source); var result = vertexAction(source, traverseMap); if (!result) { return; } foreach (var outEdge in outEdges) { uncheckedVertices.Enqueue(traverseViaOutBoundVertices ? outEdge.Target : outEdge.Source); } } }
private static List <List <string> > GetStraight(MatrixWithHeaders matrixWithHeaders) { Dictionary <object, IEnumerable <IEdge <object> > > vertexEdges = new Dictionary <object, IEnumerable <IEdge <object> > >(); BidirectionalGraph <object, IEdge <object> > graph = Graph.AdjacentyMatrixToGraph(matrixWithHeaders) as BidirectionalGraph <object, IEdge <object> >; List <List <string> > straight = new List <List <string> >(); EdgeList <string, Edge <string> > candidates = new EdgeList <string, Edge <string> >(); var matrix = matrixWithHeaders.Matrix; var headers = matrixWithHeaders.Headers; var vertexes = graph.Vertices; foreach (var item in vertexes) { var inEdges = graph.InEdges(item); var outEdges = graph.OutEdges(item); if (inEdges.Count() == 1 && outEdges.Count() == 1) { candidates.Add(new Edge <string>(inEdges.ElementAt(0).Source.ToString(), inEdges.ElementAt(0).Target.ToString())); candidates.Add(new Edge <string>(outEdges.ElementAt(0).Source.ToString(), outEdges.ElementAt(0).Target.ToString())); } } for (int x = candidates.Count() - 1; x > 0; x--) { if (candidates[x - 1].Source == candidates[x].Source && candidates[x - 1].Target == candidates[x].Target) { candidates.RemoveAt(x); } } for (int x = 0; x < candidates.Count; x++) { for (int y = x + 1; y < candidates.Count; y++) { IEdge <object> edge = null; graph.TryGetEdge(candidates[x].Source, candidates[y].Target, out edge); if (edge != null) { var existItems = candidates.Select(z => z.Source == edge.Source.ToString() && z.Target == edge.Target.ToString()).ToList(); bool exist = false; foreach (var item in existItems) { exist = exist || item; } if (exist == false) { List <string> tempList = new List <string>(); for (int z = x; z <= y; z++) { if (tempList.Contains(candidates[z].Source) == false) { tempList.Add(candidates[z].Source); } if (tempList.Contains(candidates[z].Target) == false) { tempList.Add(candidates[z].Target); } } straight.Add(tempList); } } } } return(straight); }
public IEnumerable <TEdge> InEdges(TVertex v) => _graph.InEdges(v);