Beispiel #1
0
        private async Task Recluster(List <ClusterNode> nodes, Dictionary <ClusterNode, List <IClusterableMatch> > extendedClusters, List <IClusterableMatch> immediateFamily, Dictionary <int, IClusterableMatch> matchesByIndex, ConcurrentDictionary <int, float[]> matrix)
        {
            _progressData.Reset($"Reclustering {extendedClusters.Count} primary clusters", extendedClusters.Count);

            var primaryClustersTasks = extendedClusters
                                       .Where(kvp => kvp.Value.Count > 0)
                                       .Select(async kvp =>
            {
                var nodeToRecluster    = kvp.Key;
                var additionalMatches  = kvp.Value;
                var leafNodesByIndex   = nodeToRecluster.GetOrderedLeafNodes().ToDictionary(leafNode => leafNode.Index);
                var clusterableMatches = leafNodesByIndex.Keys.Select(index => matchesByIndex[index]).Concat(additionalMatches).ToList();

                var maxIndex = additionalMatches.Max(match => match.Coords.Max());
                _matrixBuilder.ExtendMatrix(matrix, additionalMatches, maxIndex);

                var reclusteredNodes = await ClusterAsync(clusterableMatches, immediateFamily, clusterableMatches.Max(match => match.Index), matrix, ProgressData.SuppressProgress).ConfigureAwait(false);

                if (reclusteredNodes.Count == 0)
                {
                    _progressData.Increment();
                    return(nodeToRecluster);
                }
                var reclusteredNode = reclusteredNodes.First();
                foreach (var reclusteredLeafNode in reclusteredNode.GetOrderedLeafNodes())
                {
                    if (leafNodesByIndex.TryGetValue(reclusteredLeafNode.Index, out var originalLeafNode))
                    {
                        reclusteredLeafNode.Parent.ReplaceChild(reclusteredLeafNode, originalLeafNode);
                    }
                }
                if (nodeToRecluster.Parent != null)
                {
                    nodeToRecluster.Parent.ReplaceChild(nodeToRecluster, reclusteredNode);
                }
                else
                {
                    nodes.Remove(nodeToRecluster);
                    nodes.Add(reclusteredNode);
                }
                _progressData.Increment();
                return(reclusteredNode);
            });
            var primaryClusters = await Task.WhenAll(primaryClustersTasks);

            _progressData.Reset();
        }
Beispiel #2
0
        private async Task Recluster(ICollection <ClusterNode> nodes, Dictionary <Node, List <IClusterableMatch> > extendedClusters, List <IClusterableMatch> immediateFamily, IReadOnlyDictionary <int, IClusterableMatch> matchesByIndex, ConcurrentDictionary <int, float[]> matrix)
        {
            _progressData.Reset($"Reclustering {extendedClusters.Count} primary clusters", extendedClusters.Count);

            var primaryClustersTaskData = extendedClusters
                                          .Where(kvp => kvp.Value.Count > 0)
                                          .Select(kvp =>
            {
                var nodeToRecluster    = kvp.Key;
                var additionalMatches  = kvp.Value;
                var leafNodesByIndex   = nodeToRecluster.GetOrderedLeafNodes().ToDictionary(leafNode => leafNode.Index);
                var clusterableMatches = leafNodesByIndex.Keys.Select(index => matchesByIndex[index]).Concat(additionalMatches).ToList();
                return(new
                {
                    NodeToRecluster = nodeToRecluster,
                    AdditionalMatches = additionalMatches,
                    LeafNodesByIndex = leafNodesByIndex,
                    ClusterableMatches = clusterableMatches,
                });
            }).ToList();

            var additionalMatchesDistinct = primaryClustersTaskData.SelectMany(data => data.AdditionalMatches).Distinct().ToList();
            var maxIndex = additionalMatchesDistinct.SelectMany(match => match.Coords).DefaultIfEmpty(-1).Max();

            if (maxIndex < 0)
            {
                _progressData.Reset();
                return;
            }

            _matrixBuilder.ExtendMatrix(matrix, additionalMatchesDistinct, maxIndex);

            var primaryClustersTasks = primaryClustersTaskData
                                       .Select(async data =>
            {
                var reclusteredNodes = await ClusterAsync(data.ClusterableMatches, immediateFamily, matrix, ProgressData.SuppressProgress).ConfigureAwait(false);

                if (reclusteredNodes.Count == 0)
                {
                    _progressData.Increment();
                    return(data.NodeToRecluster);
                }
                var nodeToReclusterParent = data.NodeToRecluster.Parent;
                var reclusteredNode       = reclusteredNodes.First();
                foreach (var reclusteredLeafNode in reclusteredNode.GetOrderedLeafNodes())
                {
                    if (data.LeafNodesByIndex.TryGetValue(reclusteredLeafNode.Index, out var originalLeafNode))
                    {
                        reclusteredLeafNode.Parent.ReplaceChild(reclusteredLeafNode, originalLeafNode);
                    }
                }
                if (nodeToReclusterParent != null)
                {
                    nodeToReclusterParent.ReplaceChild(data.NodeToRecluster, reclusteredNode);
                }
                else
                {
                    if (data.NodeToRecluster is ClusterNode clusterNode)
                    {
                        nodes.Remove(clusterNode);
                    }
                    nodes.Add(reclusteredNode);
                }
                _progressData.Increment();
                return(reclusteredNode);
            });
            await Task.WhenAll(primaryClustersTasks);

            _progressData.Reset();
        }