Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is my own re-implementation of Topological sorting, the idea is based on <a href="http://tawani.blogspot.com/2009/02/topological-sorting-and-cyclic.html" rel="noreferrer">http://tawani.blogspot.com/2009/02/topological-sorting-and-cyclic.html</a> (The ported Java source code consumes too much memory, checking 50k objects costs 50k*50k*4 = 10GB which is unacceptable. In addition, it still has Java coding convention some places)</p> <pre><code>using System.Collections.Generic; using System.Diagnostics; namespace Modules { /// &lt;summary&gt; /// Provides fast-algorithm and low-memory usage to sort objects based on their dependencies. /// &lt;/summary&gt; /// &lt;remarks&gt; /// Definition: http://en.wikipedia.org/wiki/Topological_sorting /// Source code credited to: http://tawani.blogspot.com/2009/02/topological-sorting-and-cyclic.html /// Original Java source code: http://www.java2s.com/Code/Java/Collections-Data-Structure/Topologicalsorting.htm /// &lt;/remarks&gt; /// &lt;author&gt;ThangTran&lt;/author&gt; /// &lt;history&gt; /// 2012.03.21 - ThangTran: rewritten based on &lt;see cref="TopologicalSorter"/&gt;. /// &lt;/history&gt; public class DependencySorter&lt;T&gt; { //************************************************** // // Private members // //************************************************** #region Private members /// &lt;summary&gt; /// Gets the dependency matrix used by this instance. /// &lt;/summary&gt; private readonly Dictionary&lt;T, Dictionary&lt;T, object&gt;&gt; _matrix = new Dictionary&lt;T, Dictionary&lt;T, object&gt;&gt;(); #endregion //************************************************** // // Public methods // //************************************************** #region Public methods /// &lt;summary&gt; /// Adds a list of objects that will be sorted. /// &lt;/summary&gt; public void AddObjects(params T[] objects) { // --- Begin parameters checking code ----------------------------- Debug.Assert(objects != null); Debug.Assert(objects.Length &gt; 0); // --- End parameters checking code ------------------------------- // add to matrix foreach (T obj in objects) { // add to dictionary _matrix.Add(obj, new Dictionary&lt;T, object&gt;()); } } /// &lt;summary&gt; /// Sets dependencies of given object. /// This means &lt;paramref name="obj"/&gt; depends on these &lt;paramref name="dependsOnObjects"/&gt; to run. /// Please make sure objects given in the &lt;paramref name="obj"/&gt; and &lt;paramref name="dependsOnObjects"/&gt; are added first. /// &lt;/summary&gt; public void SetDependencies(T obj, params T[] dependsOnObjects) { // --- Begin parameters checking code ----------------------------- Debug.Assert(dependsOnObjects != null); // --- End parameters checking code ------------------------------- // set dependencies Dictionary&lt;T, object&gt; dependencies = _matrix[obj]; dependencies.Clear(); // for each depended objects, add to dependencies foreach (T dependsOnObject in dependsOnObjects) { dependencies.Add(dependsOnObject, null); } } /// &lt;summary&gt; /// Sorts objects based on this dependencies. /// Note: because of the nature of algorithm and memory usage efficiency, this method can be used only one time. /// &lt;/summary&gt; public T[] Sort() { // prepare result List&lt;T&gt; result = new List&lt;T&gt;(_matrix.Count); // while there are still object to get while (_matrix.Count &gt; 0) { // get an independent object T independentObject; if (!this.GetIndependentObject(out independentObject)) { // circular dependency found throw new CircularReferenceException(); } // add to result result.Add(independentObject); // delete processed object this.DeleteObject(independentObject); } // return result return result.ToArray(); } #endregion //************************************************** // // Private methods // //************************************************** #region Private methods /// &lt;summary&gt; /// Returns independent object or returns NULL if no independent object is found. /// &lt;/summary&gt; private bool GetIndependentObject(out T result) { // for each object foreach (KeyValuePair&lt;T, Dictionary&lt;T, object&gt;&gt; pair in _matrix) { // if the object contains any dependency if (pair.Value.Count &gt; 0) { // has dependency, skip it continue; } // found result = pair.Key; return true; } // not found result = default(T); return false; } /// &lt;summary&gt; /// Deletes given object from the matrix. /// &lt;/summary&gt; private void DeleteObject(T obj) { // delete object from matrix _matrix.Remove(obj); // for each object, remove the dependency reference foreach (KeyValuePair&lt;T, Dictionary&lt;T, object&gt;&gt; pair in _matrix) { // if current object depends on deleting object pair.Value.Remove(obj); } } #endregion } /// &lt;summary&gt; /// Represents a circular reference exception when sorting dependency objects. /// &lt;/summary&gt; public class CircularReferenceException : Exception { /// &lt;summary&gt; /// Initializes a new instance of the &lt;see cref="CircularReferenceException"/&gt; class. /// &lt;/summary&gt; public CircularReferenceException() : base("Circular reference found.") { } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload