AddConnectedNode() public method

public AddConnectedNode ( DendriteNode node ) : void
node DendriteNode
return void
Esempio n. 1
0
        private void PruningRec(DendriteNode node, DendriteNode parent, int nodeId)
        {
            if (node.Id == nodeId)
            {
                node.ConnectedNodes.Clear();
                node.AddConnectedNode(parent);
                return;
            }

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    PruningRec(next, node, nodeId);
                }
            }
        }
Esempio n. 2
0
        public void RelateSwcNode(Dendrite swc)
        {
            // addNodeToList(main_dendrite.root, null); の直前で-1を設定したかったけど
            // unassigned local variableで怒られた(´・ω・`)
            int currentSubDendriteIndex = -1;

            var nodeListImg   = new List <DendriteNode>();
            var node2subindex = new Dictionary <DendriteNode, int>();

            Action <DendriteNode, DendriteNode> addNodeToList = null;

            addNodeToList = (node, parent) =>
            {
                nodeListImg.Add(node);
                node2subindex.Add(node, currentSubDendriteIndex);

                foreach (var next in node.ConnectedNodes)
                {
                    if (next == parent)
                    {
                        continue;
                    }
                    addNodeToList(next, node);
                }
            };

            addNodeToList(main_dendrite.root, null);
            for (int i = 0; i < sub_dendrites.Count; i++)
            {
                currentSubDendriteIndex = i;
                addNodeToList(sub_dendrites[i].root, null);
            }

            foreach (var node in nodeListImg)
            {
                node.isConnected = false;
            }

            var img2swc         = new Dictionary <DendriteNode, DendriteNode>();
            var que             = new Queue <DendriteNode>();
            var removeCandidate = new HashSet <int>();

            Action <DendriteNode, DendriteNode> mapping = null;

            mapping = (node, parent) =>
            {
                Debug.Assert(nodeListImg.Count > 0);
                var pair = nodeListImg.First();
                foreach (var item in nodeListImg)
                {
                    if (node.EuclideanDistanceTo(item) < node.EuclideanDistanceTo(pair))
                    {
                        pair = item;
                    }
                }
                pair.isConnected = true;
                img2swc[pair]    = node;
                que.Enqueue(pair);

                Debug.Assert(node2subindex.ContainsKey(pair));
                if (node2subindex[pair] != -1)
                {
                    removeCandidate.Add(node2subindex[pair]);
                }

                foreach (var next in node.ConnectedNodes)
                {
                    if (next == parent)
                    {
                        continue;
                    }
                    mapping(next, node);
                }
            };
            mapping(swc.root, null);

            while (que.Count > 0)
            {
                var node = que.Dequeue();
                foreach (var next in node.ConnectedNodes)
                {
                    if (next.isConnected)
                    {
                        continue;
                    }
                    next.isConnected = true;
                    var newNode = new DendriteNode(-1, next.gx, next.gy, next.gz, next.Radius, -1);
                    Debug.Assert(img2swc.ContainsKey(node));
                    img2swc[node].AddConnectedNode(newNode);
                    newNode.AddConnectedNode(img2swc[node]);
                    que.Enqueue(next);
                    img2swc[next] = newNode;
                }
            }

            swc.ChangeRootNode(swc.root);
            main_dendrite = swc;

            int offset = 0;

            foreach (var item in removeCandidate.ToList().OrderBy(x => x))
            {
                sub_dendrites.RemoveAt(item + offset);
                sub_dendrites_volume.RemoveAt(item + offset);
                offset--;
            }
        }
Esempio n. 3
0
        public void ConnectSubDendritesToOtherSubDendrites()
        {
            var nodelist = new Dictionary <int, List <DendriteNode> >();

            foreach (int index in NotMergedSubDendritesIdx)
            {
                List <DendriteNode> node = sub_dendrites[index].GetEdgeNodeAndBranchNodes();
                nodelist.Add(index, node);
            }

            DendriteNode masterNode = null;
            DendriteNode slaveNode  = null;

            var cache = new Dictionary <Tuple2, NodeIndexer>();

            while (true)
            {
                // masterとslaveの距離をあらかじめ計算しておいて配列に保存し、ソートしておくことで
                // 高速に計算できるが、需要がないようなので後回しにする。
                // 配列に保存するのは距離がdistanceThreashold以下のものだけにしないとメモリが足りないと思います。
                // Masterがどこかのノードに吸収されるかもしれないので、
                // UnionFind木で管理しておきましょう

                int    masterIndex = 0;
                int    slaveIndex  = 0;
                double min         = Double.MaxValue;

                foreach (int master in NotMergedSubDendritesIdx)
                {
                    for (int master2 = 0; master2 < nodelist[master].Count; master2++)
                    {
                        var dictKey = new Tuple2(master, master2);
                        if (cache.ContainsKey(dictKey) == false || nodelist[cache[dictKey].ClusterIdx].Count == 0)
                        {
                            foreach (int slave in NotMergedSubDendritesIdx)
                            {
                                if (master == slave)
                                {
                                    continue;
                                }
                                for (int slave2 = 0; slave2 < nodelist[slave].Count; slave2++)
                                {
                                    double tmpdist = nodelist[master][master2].EuclideanDistanceTo(nodelist[slave][slave2]);

                                    // キャッシュがなかった場合は新しく追加
                                    if (cache.ContainsKey(dictKey) == false)
                                    {
                                        cache.Add(dictKey, new NodeIndexer(tmpdist, slave, slave2));
                                    }
                                    // キャッシュしていたノードが他のノードに併合されたパターン
                                    else if (nodelist[cache[dictKey].ClusterIdx].Count == 0)
                                    {
                                        cache[dictKey] = new NodeIndexer(tmpdist, slave, slave2);
                                    }
                                    // 再探索時に、キャッシュしていたノードよりも近いノードを見つけた場合には、キャッシュしている値を変更する
                                    else if (cache[dictKey].Norm >= tmpdist)
                                    {
                                        cache[dictKey] = new NodeIndexer(tmpdist, slave, slave2);
                                    }

                                    if (min >= tmpdist)
                                    {
                                        min         = tmpdist;
                                        masterNode  = nodelist[slave][slave2];
                                        slaveNode   = nodelist[master][master2];
                                        masterIndex = master;
                                        slaveIndex  = slave;
                                    }
                                }
                            }
                        }
                        // キャッシュが存在した場合はそれを利用
                        else
                        {
                            NodeIndexer nodeIndex = cache[dictKey];
                            double      tmpdist   = nodeIndex.Norm;
                            int         slave     = nodeIndex.ClusterIdx;
                            int         slave2    = nodeIndex.NodeIdx;
                            if (min >= tmpdist)
                            {
                                min         = tmpdist;
                                masterNode  = nodelist[slave][slave2];
                                slaveNode   = nodelist[master][master2];
                                masterIndex = master;
                                slaveIndex  = slave;
                            }
                        }
                    }
                }

                if (min <= param.distanceThreshold)
                {
                    //連結ノードにお互いを追加
                    masterNode.AddConnectedNode(slaveNode);
                    slaveNode.AddConnectedNode(masterNode);

                    //連結したサブノードリストはメインノードリストに吸収
                    nodelist[masterIndex].AddRange(nodelist[slaveIndex]);

                    //サブを消去
                    nodelist[slaveIndex].Clear();

                    // マージされた
                    NotMergedSubDendritesIdx.Remove(slaveIndex);
                    sub_dendrites_volume[masterIndex] += sub_dendrites_volume[slaveIndex];
                    sub_dendrites_volume[slaveIndex]   = 0;
                }
                else
                {
                    break;
                }
            }

            foreach (int index in NotMergedSubDendritesIdx)
            {
                if (nodelist[index].Count > 0)
                {
                    Dendrite node = sub_dendrites[index];
                    var      edge = node.GetEdgeNodes();
                    node.ChangeRootNode(edge.Last());
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// SubDendriteを距離閾値に従ってMainDendriteに接続
        /// </summary>
        public void ConnectSubDendritesToMainDendrite()
        {
            // nodelist[0]		: main
            // nodelist[1:]     : sub
            List <List <DendriteNode> > nodelist = new List <List <DendriteNode> >();

            //メインクラスタの分岐,端点ノードを取得
            List <DendriteNode> pnode = main_dendrite.GetEdgeNodeAndBranchNodes();

            nodelist.Add(pnode);

            NotMergedSubDendritesIdx = new HashSet <int>();

            for (int i = 0; i < sub_dendrites.Count; i++)
            {
                //サブクラスタの分岐,端点ノードを取得
                List <DendriteNode> node = sub_dendrites[i].GetEdgeNodeAndBranchNodes();

                nodelist.Add(node);
                NotMergedSubDendritesIdx.Add(i);
            }

            var Q = new SkewHeap <NodeRelation>();

            for (int i = 0; i < nodelist[0].Count; i++)
            {
                for (int j = 1; j < nodelist.Count; j++)
                {
                    double normMin = double.MaxValue;
                    int    argMin  = -1;
                    for (int k = 0; k < nodelist[j].Count; k++)
                    {
                        double d = nodelist[0][i].EuclideanDistanceTo(nodelist[j][k]);
                        if (d <= normMin)
                        {
                            normMin = d;
                            argMin  = k;
                        }
                    }

                    if (argMin != -1 && normMin <= param.distanceThreshold)
                    {
                        Q.Push(new NodeRelation(normMin, i, j, argMin));
                    }
                }
            }

            while (true)
            {
                NodeRelation rel = null;
                while (Q.Empty() == false)
                {
                    rel = Q.Pop();
                    if (nodelist[rel.SlaveClusterIdx].Count > 0)
                    {
                        break;
                    }
                }

                if (Q.Empty())
                {
                    break;
                }

                DendriteNode parent = nodelist[0][rel.MasterNodeIdx];
                DendriteNode cand   = nodelist[rel.SlaveClusterIdx][rel.SlaveNodeIdx];

                //連結ノードにお互いを追加
                cand.AddConnectedNode(parent);
                parent.AddConnectedNode(cand);

                int mainNodeSizePrev = nodelist[0].Count;

                //連結したサブノードリストはメインノードリストに吸収
                nodelist[0].AddRange(nodelist[rel.SlaveClusterIdx]);

                //サブを消去
                nodelist[rel.SlaveClusterIdx].Clear();

                // マージされた
                NotMergedSubDendritesIdx.Remove(rel.SlaveClusterIdx - 1);

                // 吸収されたサブノードから、吸収されていないサブノードまでの距離を算出
                for (int i = mainNodeSizePrev; i < nodelist[0].Count; i++)
                {
                    for (int j = 1; j < nodelist.Count; j++)
                    {
                        double normMin = double.MaxValue;
                        int    argMin  = -1;
                        for (int k = 0; k < nodelist[j].Count; k++)
                        {
                            double d = nodelist[0][i].EuclideanDistanceTo(nodelist[j][k]);
                            if (d <= normMin)
                            {
                                normMin = d;
                                argMin  = k;
                            }
                        }

                        if (argMin != -1 && normMin <= param.distanceThreshold)
                        {
                            Q.Push(new NodeRelation(normMin, i, j, argMin));
                        }
                    }
                }
            }

            main_dendrite.ChangeRootNode(main_dendrite.root);
            pnode = main_dendrite.GetEdgeNodes();
            // どうしてFirstでなくてLastなのかよく分からない
            main_dendrite.ChangeRootNode(pnode.Last());
        }
Esempio n. 5
0
        private void PruningRec(DendriteNode node, DendriteNode parent, int nodeId) {
            if (node.Id == nodeId)
            {
                node.ConnectedNodes.Clear();
                node.AddConnectedNode(parent);
                return;
            }

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    PruningRec(next, node, nodeId);
                }
            }
        }