/// <summary>
        /// Disconnects the two groups.
        /// </summary>
        /// <remarks>
        /// This method assumes that two groups will only be connected via one import - export relation. This
        /// method will remove all connections from the exporting group to the importing group.
        /// </remarks>
        /// <param name="importingGroup">The ID of the group that owns the import.</param>
        /// <param name="exportingGroup">The ID of the group that owns the export.</param>
        /// <returns>A task which indicates when the disconnection has taken place.</returns>
        public Task Disconnect(GroupCompositionId importingGroup, GroupCompositionId exportingGroup)
        {
            {
                Debug.Assert(importingGroup != null, "The ID of the importing group should not be a null reference.");
                Debug.Assert(exportingGroup != null, "The ID of the exporting group should not be a null reference.");
            }

            m_Diagnostics.Log(
                LevelToLog.Trace,
                HostConstants.LogPrefix,
                string.Format(
                    CultureInfo.InvariantCulture,
                    Resources.ProxyCompositionLayer_LogMessage_DisconnectingGroups_WithImportAndExport,
                    importingGroup,
                    exportingGroup));

            var remoteTask = m_Commands.Disconnect(importingGroup, exportingGroup);

            return(remoteTask.ContinueWith(
                       t =>
            {
                m_GroupConnections.RemoveInEdgeIf(importingGroup, edge => edge.Source.Equals(exportingGroup));
            }));
        }
Esempio n. 2
0
        public void removeEdgeIfTest()
        {
            var graph = new BidirectionalGraph <int, IEdge <int> >();

            graph.AddVertex(1);
            graph.AddVertex(2);
            graph.AddVertex(3);
            graph.AddEdge(new EquatableEdge <int>(1, 2));
            graph.AddEdge(new EquatableEdge <int>(2, 3));
            graph.AddEdge(new EquatableEdge <int>(2, 1));
            graph.RemoveOutEdgeIf(2, (edge) => edge.Target == 1);
            Assert.IsTrue(graph.ContainsEdge(1, 2));
            Assert.IsFalse(graph.ContainsEdge(2, 1));
            Assert.IsTrue(graph.ContainsEdge(2, 3));
            graph.RemoveInEdgeIf(2, (edge) => edge.Source == 1);
            Assert.IsTrue(graph.ContainsEdge(2, 3));
            Assert.IsFalse(graph.ContainsEdge(1, 2));
        }
Esempio n. 3
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);
        }
Esempio n. 4
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);
        }