예제 #1
0
        private void RemoveUnreachableBlocks()
        {
            var root = graph.Roots().Single(v => v.IsSpecialBlock);

            var reachableBlocks   = graph.ReachableBlocks(root);
            var unreachableBlocks = graph.Vertices.Except(reachableBlocks).ToList();

            foreach (var unreachableBlock in unreachableBlocks)
            {
                graph.RemoveVertex(unreachableBlock);
            }
        }
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="node"></param>
        protected void RemoveNode(NodeVertex node)
        {
            if (graph.ContainsVertex(node))
            {
                // TODO Need a better way to removing incoming edges
                var edgesToRemove = AssociatedObject.EdgesList.Values.Where(x => ((NodeEdge)x.Edge).Source == node || ((NodeEdge)x.Edge).Target == node).ToList();
                foreach (var control in edgesToRemove)
                {
                    var edge = (NodeEdge)control.Edge;
                    graph.RemoveEdge(edge);
                    AssociatedObject.RemoveEdge(edge);
                }

                // Disconnect control
                VertexControl vertexControl;
                if (AssociatedObject.VertexList.TryGetValue(node, out vertexControl))
                {
                    node.DisconnectControl(vertexControl);
                }

                // Then remove the vertex
                graph.RemoveVertex(node);
                AssociatedObject.RemoveVertex(node);
            }
        }
예제 #3
0
        void UpdateVectorsT()
        {
            if (this.CGraph.VertexCount == 0)
            {
                return;
            }

            BidirectionalGraph <Node, Edge> topoGraph = this.CGraph.Clone();

            while (topoGraph.VertexCount > 0)
            {
                Node current = topoGraph.Vertices.Where(item => topoGraph.InDegree(item) == 0).First();

                IEnumerable <Edge> outEdges = topoGraph.Edges.Where(item => item.Source.Equals(current));
                foreach (Edge outEdge in outEdges)
                {
                    Node succ      = outEdge.Target;
                    Node successor = this.CGraph.Vertices.Where(v => v.Equals(succ)).Single();
                    for (int i = 0; i < this.VcCount; i++)
                    {
                        //succ.VectorClock[i] = Math.Max(succ.VectorClock[i], current.VectorClock[i]);
                        successor.VectorClock[i] = Math.Max(successor.VectorClock[i], current.VectorClock[i]);
                    }
                }
                topoGraph.RemoveVertex(current);
            }
        }
예제 #4
0
        /// <summary>
        /// Removes the group that is related to the specified ID.
        /// </summary>
        /// <param name="group">The ID of the group that should be removed.</param>
        /// <returns>A task that indicates when the removal has taken place.</returns>
        public Task Remove(GroupCompositionId group)
        {
            {
                Debug.Assert(group != null, "The ID that should be removed should not be a null reference.");
                Debug.Assert(m_Groups.ContainsKey(group), "The ID should be known.");
            }

            m_Diagnostics.Log(
                LevelToLog.Trace,
                HostConstants.LogPrefix,
                string.Format(
                    CultureInfo.InvariantCulture,
                    Resources.ProxyCompositionLayer_LogMessage_RemovingGroup_WithId,
                    group));

            var remoteTask = m_Commands.Remove(group);

            return(remoteTask.ContinueWith(
                       t =>
            {
                lock (m_Lock)
                {
                    if (m_GroupConnections.ContainsVertex(group))
                    {
                        m_GroupConnections.RemoveVertex(group);
                    }

                    if (m_Groups.ContainsKey(group))
                    {
                        m_Groups.Remove(group);
                    }
                }
            }));
        }
        public RemoveVertexResult <TVertex, TEdge> RemoveVertex(TVertex vertex)
        {
            bool vertexWasRemoved;

            TEdge[] edgesOfRemovedVertex;

            lock (SyncRoot)
            {
                edgesOfRemovedVertex = Graph.GetAllEdges(vertex).ToArray();
                vertexWasRemoved     = Graph.RemoveVertex(vertex);
            }

            if (!vertexWasRemoved)
            {
                return(RemoveVertexResult <TVertex, TEdge> .Empty);
            }

            foreach (var edge in edgesOfRemovedVertex)
            {
                EdgeRemoved?.Invoke(edge);
            }

            VertexRemoved?.Invoke(vertex);

            return(new RemoveVertexResult <TVertex, TEdge>(vertex, edgesOfRemovedVertex));
        }
예제 #6
0
 /// <summary>
 /// Retourne True si outil est supprimé du circuit
 /// </summary>
 /// <param name="outil"></param>
 /// <returns></returns>
 public bool DeleteComponent(Outils outil)
 {
     if (Circuit.ContainsVertex(outil))// Si outil figure dans le circuit
     {
         //Mettre à jour les entrées des outils auxquelles l'outil était connecté
         foreach (var sortie in outil.getListesorties())
         {
             sortie.getSortie().ForEach((outstruct) => { outstruct.GetEntree().setRelated(false); });
         }
         //Mettre à jour les sorties des outils auxquelles l'outil était connecté
         foreach (var edge in Circuit.InEdges(outil))
         {
             foreach (var sortie in edge.Source.getListesorties())
             {
                 sortie.DeleteOustruct(outil);
             }
         }
         Circuit.ClearEdges(outil);
         Circuit.RemoveVertex(outil);
         return(true);
     }
     else
     {
         return(false);
     }
 }
        public void Repro13160()
        {
            // create a new graph			
            var graph = new BidirectionalGraph<int, SEquatableEdge<int>>(false);

            // adding vertices		    
            for (int i = 0; i < 3; ++i)
                for(int j = 0;j<3;++j)
                    graph.AddVertex(i * 3 + j);

            // adding Width edges			    
            for (int i = 0; i < 3; ++i)
                for(int j = 0; j < 2;++j)
                graph.AddEdge(new SEquatableEdge<int>(i * 3 +j, i * 3 + j + 1));

            // adding Length edges			    
            for (int i = 0; i < 2; ++i)
                for(int j = 0; j < 3;++j)
                graph.AddEdge(new SEquatableEdge<int>(i * 3 + j, (i+1) * 3 + j));

            // create cross edges 
            foreach (var e in graph.Edges)
                graph.AddEdge(new SEquatableEdge<int>(e.Target, e.Source));

            // breaking graph apart
            for (int i = 0; i < 3; ++i)
                for (int j = 0; j < 3; ++j)
                    if (i == 1)
                        graph.RemoveVertex(i * 3 + j);

            var target = new CyclePoppingRandomTreeAlgorithm<int, SEquatableEdge<int>>(graph);
            target.Compute(2);
            foreach(var kv in target.Successors)
                Console.WriteLine("{0}: {1}", kv.Key, kv.Value);
        }
            /// <summary>
            /// Applies the changes in the current change to the given history object.
            /// </summary>
            /// <param name="historyObject">The object to which the changes should be applied.</param>
            /// <exception cref="ArgumentNullException">
            ///     Thrown if <paramref name="historyObject"/> is <see langword="null" />.
            /// </exception>
            public void ApplyTo(BidirectionalGraph <TVertex, TEdge> historyObject)
            {
                {
                    Lokad.Enforce.Argument(() => historyObject);
                }

                historyObject.RemoveVertex(m_Vertex);
            }
        public void Repro13160()
        {
            // create a new graph
            var graph = new BidirectionalGraph <int, SEquatableEdge <int> >(false);

            // adding vertices
            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    graph.AddVertex(i * 3 + j);
                }
            }

            // adding Width edges
            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 2; ++j)
                {
                    graph.AddEdge(new SEquatableEdge <int>(i * 3 + j, i * 3 + j + 1));
                }
            }

            // adding Length edges
            for (int i = 0; i < 2; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    graph.AddEdge(new SEquatableEdge <int>(i * 3 + j, (i + 1) * 3 + j));
                }
            }

            // create cross edges
            foreach (var e in graph.Edges)
            {
                graph.AddEdge(new SEquatableEdge <int>(e.Target, e.Source));
            }

            // breaking graph apart
            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    if (i == 1)
                    {
                        graph.RemoveVertex(i * 3 + j);
                    }
                }
            }

            var target = new CyclePoppingRandomTreeAlgorithm <int, SEquatableEdge <int> >(graph);

            target.Compute(2);
            foreach (var kv in target.Successors)
            {
                Console.WriteLine("{0}: {1}", kv.Key, kv.Value);
            }
        }
예제 #10
0
        public void Repro13160()
        {
            // Create a new graph
            var graph = new BidirectionalGraph <int, SEquatableEdge <int> >(false);

            // Adding vertices
            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    graph.AddVertex(i * 3 + j);
                }
            }

            // Adding Width edges
            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 2; ++j)
                {
                    graph.AddEdge(
                        new SEquatableEdge <int>(i * 3 + j, i * 3 + j + 1));
                }
            }

            // Adding Length edges
            for (int i = 0; i < 2; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    graph.AddEdge(
                        new SEquatableEdge <int>(i * 3 + j, (i + 1) * 3 + j));
                }
            }

            // Create cross edges
            foreach (SEquatableEdge <int> edge in graph.Edges)
            {
                graph.AddEdge(new SEquatableEdge <int>(edge.Target, edge.Source));
            }

            // Breaking graph apart
            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    if (i == 1)
                    {
                        graph.RemoveVertex(i * 3 + j);
                    }
                }
            }

            var target = new CyclePoppingRandomTreeAlgorithm <int, SEquatableEdge <int> >(graph);

            target.Compute(2);
        }
예제 #11
0
        public void NextStep()
        {
            _steps.Push(_graph.Clone());

            var v = _graph.Vertices.First();

            _graph.RemoveVertex(v);
            ShowResults();

            if (!_graph.Vertices.Any())
            {
                _hasFinished = true;
            }
        }
예제 #12
0
        public void RemoveNode(Node node)
        {
            Argument.NotNull(node, nameof(node));

            lock (_graph)
            {
                if (_graph.RemoveVertex(node))
                {
                    _graph.RemoveEdgeIf(link => link.Source == node || link.Target == node);
                    OnGraphChanged();
                    node.Parent = null;
                }
            }
        }
예제 #13
0
        private void TriggersOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
        {
            if (!Dispatcher.CheckAccess())
            {
                Dispatcher.Invoke(() => TriggersOnCollectionChanged(sender, args));
                return;
            }

            if (args.NewItems != null)
            {
                foreach (var item in args.NewItems)
                {
                    _graph.AddVertex(item);
                }
            }
            if (args.OldItems != null)
            {
                foreach (var item in args.OldItems)
                {
                    _graph.RemoveVertex(item);
                }
            }
            CreateVertices();
        }
예제 #14
0
        private void OnRemoveVertexClick(object sender, RoutedEventArgs args)
        {
            if (_graph is null || _graph.VertexCount < 1)
            {
                return;
            }

            var random = new Random(DateTime.Now.Millisecond);

            for (int i = 0; i < 10 && _graph.VertexCount > 1; ++i)
            {
                int index = random.Next(_graph.VertexCount);
                _graph.RemoveVertex(_graph.Vertices.ElementAt(index));
            }
        }
예제 #15
0
        /// <summary>
        /// Removes all the plugins related to the given plugin files.
        /// </summary>
        /// <param name="deletedFiles">The collection of plugin file paths that were removed.</param>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="deletedFiles"/> is <see langword="null" />.
        /// </exception>
        public void RemovePlugins(IEnumerable <string> deletedFiles)
        {
            {
                Lokad.Enforce.Argument(() => deletedFiles);
            }

            lock (m_Lock)
            {
                var filesToDelete = m_PluginFiles
                                    .Join(
                    deletedFiles,
                    pluginFile => pluginFile.Path,
                    filePath => filePath,
                    (pluginFile, filePath) => pluginFile)
                                    .ToList();
                foreach (var file in filesToDelete)
                {
                    m_PluginFiles.Remove(file);
                }

                var groupsToDelete = m_Groups
                                     .Join(
                    filesToDelete,
                    p => p.Value.Item2,
                    file => file,
                    (pair, file) => pair.Key)
                                     .ToList();
                foreach (var group in groupsToDelete)
                {
                    m_Groups.Remove(group);
                }

                var typesToDelete = m_Parts
                                    .Join(
                    filesToDelete,
                    p => p.Value.Item2,
                    file => file,
                    (pair, file) => pair.Key)
                                    .ToList();
                foreach (var type in typesToDelete)
                {
                    m_Parts.Remove(type);
                    m_Types.Remove(type);
                    m_TypeGraph.RemoveVertex(type);
                }
            }
        }
        private void Reset_Click(object sender, RoutedEventArgs e)
        {
            for (int i = 1; i < this.nbVirtex; i++)
            {
                g.RemoveVertex(i.ToString());
            }


            nbVirtex      = 1;
            nbVirtexAdded = 1;
            //addedVir.Clear();
            addedVir = new List <int>();
            addedVir.Add(0);
            addV.IsEnabled  = false;
            nbVir.IsEnabled = true;
            Rem.IsEnabled   = false;
            add.IsEnabled   = false;
        }
예제 #17
0
        private void RemoveVertex_Click(object sender, RoutedEventArgs e)
        {
            if (graph == null)
            {
                return;
            }

            if (graph.VertexCount < 1)
            {
                return;
            }
            var rnd = new Random(DateTime.Now.Millisecond);

            for (int i = 0; i < 10 && graph.VertexCount > 1; i++)
            {
                graph.RemoveVertex(graph.Vertices.ElementAt(rnd.Next(graph.VertexCount)));
            }
        }
        public void Repro13160()
        {
            // Create a new graph
            var graph = new BidirectionalGraph <int, Edge <int> >(false);

            // Adding vertices
            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    graph.AddVertex(i * 3 + j);
                }
            }

            // Adding Width edges
            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 2; ++j)
                {
                    graph.AddEdge(
                        new Edge <int>(i * 3 + j, i * 3 + j + 1));
                }
            }

            // Adding Length edges
            for (int i = 0; i < 2; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    graph.AddEdge(
                        new Edge <int>(i * 3 + j, (i + 1) * 3 + j));
                }
            }

            // Create cross edges
            foreach (Edge <int> edge in graph.Edges)
            {
                graph.AddEdge(new Edge <int>(edge.Target, edge.Source));
            }

            // Breaking graph apart
            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    if (i == 1)
                    {
                        graph.RemoveVertex(i * 3 + j);
                    }
                }
            }

            var randomChain = new Random(123456);
            var chain       = new NormalizedMarkovEdgeChain <int, Edge <int> >
            {
                Rand = randomChain
            };
            var randomAlgorithm = new Random(123456);
            var algorithm       = new CyclePoppingRandomTreeAlgorithm <int, Edge <int> >(graph, chain)
            {
                Rand = randomAlgorithm
            };

            Assert.DoesNotThrow(() => algorithm.Compute(2));
            // Successors is not a spanning tree...
        }
예제 #19
0
        /// <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));
        }
        private bool TryRemoveDummyEdge(InternalActivityEdge edge)
        {
            bool edgeRemoved = false;

            // If this is a single edge out or a single edge in - it adds no information to the graph and can be merged.
            var outDegree = arrowGraph.OutDegree(edge.Source);
            var inDegree  = arrowGraph.InDegree(edge.Target);

            // Remove the vertex which has no other edges connected to it
            if (outDegree == 1)
            {
                IEnumerable <InternalActivityEdge> allIncoming;
                if (!arrowGraph.TryGetInEdges(edge.Source, out allIncoming))
                {
                    allIncoming = new List <InternalActivityEdge>();
                }

                bool abortMerge = WillParallelEdgesBeCreated(allIncoming, null, edge.Target);

                if (!abortMerge)
                {
                    // Add the edges with the new source vertex
                    // And remove the old edges
                    foreach (var incomingEdge in allIncoming.ToList())
                    {
                        arrowGraph.AddEdge(new InternalActivityEdge(incomingEdge.Source, edge.Target, incomingEdge.IsCritical, incomingEdge.ActivityId));
                        arrowGraph.RemoveEdge(incomingEdge);
                    }

                    // Remove the edge which is no longer needed
                    arrowGraph.RemoveEdge(edge);

                    // Now remove the vertex which is no longer needed
                    arrowGraph.RemoveVertex(edge.Source);

                    edgeRemoved = true;
                }
            }
            else if (inDegree == 1)
            {
                IEnumerable <InternalActivityEdge> allOutgoing;
                if (!arrowGraph.TryGetOutEdges(edge.Target, out allOutgoing))
                {
                    allOutgoing = new List <InternalActivityEdge>();
                }

                bool abortMerge = WillParallelEdgesBeCreated(allOutgoing, edge.Source, null);

                if (!abortMerge)
                {
                    // Add the edges with the new source vertex
                    // And remove the old edges
                    foreach (var outgoingEdge in allOutgoing.ToList())
                    {
                        arrowGraph.AddEdge(new InternalActivityEdge(edge.Source, outgoingEdge.Target, outgoingEdge.IsCritical, outgoingEdge.ActivityId));
                        arrowGraph.RemoveEdge(outgoingEdge);
                    }

                    // Remove the edge which is no longer needed
                    arrowGraph.RemoveEdge(edge);

                    // Now remove the vertex which is no longer needed
                    arrowGraph.RemoveVertex(edge.Target);

                    edgeRemoved = true;
                }
            }


            return(edgeRemoved);
        }
예제 #21
0
        public IBidirectionalGraph <Cluster <T>, ClusterEdge <T> > GenerateClusters(IEnumerable <T> dataObjects)
        {
            var tree     = new BidirectionalGraph <Cluster <T>, ClusterEdge <T> >(false);
            var clusters = new List <Cluster <T> >();

            foreach (T dataObject in dataObjects)
            {
                var cluster = new Cluster <T>(dataObject)
                {
                    Description = dataObject.ToString()
                };
                clusters.Add(cluster);
                tree.AddVertex(cluster);
            }
            var distances = new Dictionary <UnorderedTuple <Cluster <T>, Cluster <T> >, double>();
            var heights   = new Dictionary <Cluster <T>, double>();

            for (int i = 0; i < clusters.Count; i++)
            {
                for (int j = i + 1; j < clusters.Count; j++)
                {
                    double distance = _getDistance(clusters[i].DataObjects.First(), clusters[j].DataObjects.First());
                    if (double.IsNaN(distance) || double.IsInfinity(distance) || distance < 0)
                    {
                        throw new ArgumentException("Invalid distance between data objects.", "dataObjects");
                    }
                    distances[UnorderedTuple.Create(clusters[i], clusters[j])] = distance;
                }
                heights[clusters[i]] = 0;
            }

            while (clusters.Count >= 2)
            {
                int    minI = 0, minJ = 0;
                double minDist = double.MaxValue;
                for (int i = 0; i < clusters.Count; i++)
                {
                    for (int j = i + 1; j < clusters.Count; j++)
                    {
                        double dist = distances[UnorderedTuple.Create(clusters[i], clusters[j])];
                        if (dist < minDist)
                        {
                            minDist = dist;
                            minI    = i;
                            minJ    = j;
                        }
                    }
                }

                Cluster <T> iCluster = clusters[minI];
                Cluster <T> jCluster = clusters[minJ];
                distances.Remove(UnorderedTuple.Create(iCluster, jCluster));

                var uCluster = new Cluster <T>();
                tree.AddVertex(uCluster);

                double height = minDist / 2;
                heights[uCluster] = height;

                int    iCount = tree.GetAllDataObjects(iCluster).Count();
                double iLen   = height - heights[iCluster];
                if (iLen <= 0 && !tree.IsOutEdgesEmpty(iCluster))
                {
                    foreach (ClusterEdge <T> edge in tree.OutEdges(iCluster))
                    {
                        tree.AddEdge(new ClusterEdge <T>(uCluster, edge.Target, edge.Length));
                    }
                    tree.RemoveVertex(iCluster);
                }
                else
                {
                    tree.RemoveInEdgeIf(iCluster, edge => true);
                    tree.AddEdge(new ClusterEdge <T>(uCluster, iCluster, Math.Max(iLen, 0)));
                }

                int    jCount = tree.GetAllDataObjects(jCluster).Count();
                double jLen   = height - heights[jCluster];
                if (jLen <= 0 && !tree.IsOutEdgesEmpty(jCluster))
                {
                    foreach (ClusterEdge <T> edge in tree.OutEdges(jCluster))
                    {
                        tree.AddEdge(new ClusterEdge <T>(uCluster, edge.Target, edge.Length));
                    }
                    tree.RemoveVertex(jCluster);
                }
                else
                {
                    tree.RemoveInEdgeIf(jCluster, edge => true);
                    tree.AddEdge(new ClusterEdge <T>(uCluster, jCluster, Math.Max(jLen, 0)));
                }

                double iWeight = (double)iCount / (iCount + jCount);
                double jWeight = (double)jCount / (iCount + jCount);
                foreach (Cluster <T> kCluster in clusters.Where(c => c != iCluster && c != jCluster))
                {
                    UnorderedTuple <Cluster <T>, Cluster <T> > kiKey = UnorderedTuple.Create(kCluster, iCluster);
                    UnorderedTuple <Cluster <T>, Cluster <T> > kjKey = UnorderedTuple.Create(kCluster, jCluster);
                    distances[UnorderedTuple.Create(uCluster, kCluster)] = (iWeight * distances[kiKey]) + (jWeight * distances[kjKey]);
                    distances.Remove(kiKey);
                    distances.Remove(kjKey);
                }
                clusters.RemoveAt(minJ);
                clusters.RemoveAt(minI);
                clusters.Add(uCluster);
            }

            return(tree);
        }
예제 #22
0
        public IUndirectedGraph <Cluster <T>, ClusterEdge <T> > GenerateClusters(IEnumerable <T> dataObjects)
        {
            var tree     = new BidirectionalGraph <Cluster <T>, ClusterEdge <T> >(false);
            var clusters = new List <Cluster <T> >();

            foreach (T dataObject in dataObjects)
            {
                var cluster = new Cluster <T>(dataObject)
                {
                    Description = dataObject.ToString()
                };
                clusters.Add(cluster);
                tree.AddVertex(cluster);
            }
            var distances = new Dictionary <UnorderedTuple <Cluster <T>, Cluster <T> >, double>();

            for (int i = 0; i < clusters.Count; i++)
            {
                for (int j = i + 1; j < clusters.Count; j++)
                {
                    double distance = _getDistance(clusters[i].DataObjects.First(), clusters[j].DataObjects.First());
                    if (double.IsNaN(distance) || double.IsInfinity(distance) || distance < 0)
                    {
                        throw new ArgumentException("Invalid distance between data objects.", "dataObjects");
                    }
                    distances[UnorderedTuple.Create(clusters[i], clusters[j])] = distance;
                }
            }

            while (clusters.Count > 2)
            {
                Dictionary <Cluster <T>, double> r = clusters.ToDictionary(c => c, c => clusters.Where(oc => oc != c).Sum(oc => distances[UnorderedTuple.Create(c, oc)] / (clusters.Count - 2)));
                int    minI = 0, minJ = 0;
                double minDist = 0, minQ = double.MaxValue;
                for (int i = 0; i < clusters.Count; i++)
                {
                    for (int j = i + 1; j < clusters.Count; j++)
                    {
                        double dist = distances[UnorderedTuple.Create(clusters[i], clusters[j])];
                        double q    = dist - r[clusters[i]] - r[clusters[j]];
                        if (q < minQ)
                        {
                            minQ    = q;
                            minDist = dist;
                            minI    = i;
                            minJ    = j;
                        }
                    }
                }

                Cluster <T> iCluster = clusters[minI];
                Cluster <T> jCluster = clusters[minJ];
                distances.Remove(UnorderedTuple.Create(iCluster, jCluster));

                var uCluster = new Cluster <T>();
                tree.AddVertex(uCluster);

                double iLen = (minDist / 2) + ((r[iCluster] - r[jCluster]) / 2);
                if (iLen <= 0 && !tree.IsOutEdgesEmpty(iCluster))
                {
                    foreach (ClusterEdge <T> edge in tree.OutEdges(iCluster))
                    {
                        tree.AddEdge(new ClusterEdge <T>(uCluster, edge.Target, edge.Length));
                    }
                    tree.RemoveVertex(iCluster);
                }
                else
                {
                    tree.RemoveInEdgeIf(iCluster, edge => true);
                    tree.AddEdge(new ClusterEdge <T>(uCluster, iCluster, Math.Max(iLen, 0)));
                }
                double jLen = minDist - iLen;
                if (jLen <= 0 && !tree.IsOutEdgesEmpty(jCluster))
                {
                    foreach (ClusterEdge <T> edge in tree.OutEdges(jCluster))
                    {
                        tree.AddEdge(new ClusterEdge <T>(uCluster, edge.Target, edge.Length));
                    }
                    tree.RemoveVertex(jCluster);
                }
                else
                {
                    tree.RemoveInEdgeIf(jCluster, edge => true);
                    tree.AddEdge(new ClusterEdge <T>(uCluster, jCluster, Math.Max(jLen, 0)));
                }

                foreach (Cluster <T> kCluster in clusters.Where(c => c != iCluster && c != jCluster))
                {
                    UnorderedTuple <Cluster <T>, Cluster <T> > kiKey = UnorderedTuple.Create(kCluster, iCluster);
                    UnorderedTuple <Cluster <T>, Cluster <T> > kjKey = UnorderedTuple.Create(kCluster, jCluster);
                    distances[UnorderedTuple.Create(kCluster, uCluster)] = (distances[kiKey] + distances[kjKey] - minDist) / 2;
                    distances.Remove(kiKey);
                    distances.Remove(kjKey);
                }
                clusters.RemoveAt(minJ);
                clusters.RemoveAt(minI);
                clusters.Add(uCluster);
            }

            if (clusters.Count == 2)
            {
                tree.AddEdge(new ClusterEdge <T>(clusters[1], clusters[0], distances[UnorderedTuple.Create(clusters[0], clusters[1])]));
                clusters.RemoveAt(0);
            }

            var unrootedTree = new UndirectedGraph <Cluster <T>, ClusterEdge <T> >(false);

            unrootedTree.AddVertexRange(tree.Vertices);
            unrootedTree.AddEdgeRange(tree.Edges);
            return(unrootedTree);
        }
예제 #23
0
 private void ClearGraph()
 {
     _root?.PostOrderTreeTraversal((parent, child) => _graph.RemoveVertex(child.ToString()));
 }
예제 #24
0
 public void RemoveNode(string nodeID)
 {
     graph.RemoveVertex(nodeID);
 }