GetEdgeNodes() public method

public GetEdgeNodes ( ) : List
return List
Example #1
0
        private void OutputSubDendrite()
        {
            DendriteIO io = new DendriteIO();

            string rawFilename = Path.GetFileNameWithoutExtension(param.ofname);
            string dirname     = Path.Combine(Path.GetDirectoryName(param.ofname), rawFilename + "-sub");

            if (Directory.Exists(dirname))
            {
                Directory.Delete(dirname, true);
            }

            Directory.CreateDirectory(dirname);

            // 出力するファイル名の末尾の桁数
            // ファイル名は0オリジンにするので .Count - 1 にしている
            int digit = (NotMergedSubDendritesIdx.Count - 1).ToString().Length;
            // 出力するファイル名の末尾のID
            int sub_dendrite_id = 0;

            // 独立して存在している(他のノードに併合されていない)側枝ノードを、体積降順で並べ替える
            var orderByVolume = NotMergedSubDendritesIdx.OrderByDescending(x => sub_dendrites_volume[x]);

            foreach (int sub_index in orderByVolume)
            {
                Dendrite             sdendrite = sub_dendrites[sub_index];
                IList <DendriteNode> edge      = sdendrite.GetEdgeNodes();
                sdendrite.ChangeRootNode(edge[0]);

                string filename = CreateFileNameForSubDendriteIO(dirname, digit, sub_dendrite_id);
                string path     = Path.Combine(dirname, filename);
                io.SaveToSWC(path, sdendrite);
                sub_dendrite_id++;

                if (param.outputVTK)
                {
                    string vtkFilename = Path.ChangeExtension(filename, "vtk");
                    string vtkPath     = Path.Combine(dirname, vtkFilename);
                    VtkWriter.SaveToVTKLegacy(vtkPath, sdendrite);
                }
            }
        }
Example #2
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());
                }
            }
        }
Example #3
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());
        }