当前位置:编程学习 > C#/ASP.NET >>

系统聚类法C#实现

以二维数组为例,用C#代码实现

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;

namespace fen
{
    public partial class Form1 : Form
    {
        DisjointSets ds;
        private int n;
        private int cc;
        private  const int MAX = int.MaxValue;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int v0 = 6;
            int[][] x = new int[v0][];
            x[0] = new int[] { 0, 3, 1, 2, 0 };
            x[1] = new int[] { 1, 3, 0, 1, 0 };
            x[2] = new int[] { 3, 3, 0, 0, 1 };
            x[3] = new int[] { 1, 1, 0, 2, 0 };
            x[4] = new int[] { 3, 2, 1, 2, 1 };
            x[5] = new int[] { 4, 1, 1, 1, 0 };

            double[,] res1 = Calc1(x);
           
            //输出
            this.label1.Text = "";
            for (int i = 0; i < v0; i++)
            {
                for (int j = 0; j < v0; j++)
                {
                    this.label1.Text += res1[j, i] + "          \t";
                }
                this.label1.Text += "\n";
            }
        }
       

        private double[,] Calc1(int[][] x)
        {
            int v = x.Length;
            double[,] res1 = new double[v, v];
            for (int i = 0; i < v - 1; i++)
            {
                for (int j = i+1; j < v; j++)
                {
                    res1[i, j] = GetResult(x[i], x[j]);
                }
            }
            return res1;
        }

        private double GetResult(int[] a, int[] b)
        {
            if (a.Length != b.Length)
            {
                return -1;
                throw new Exception("input data is error!");
                
            }
            double res = 0;
            for (int i = 0; i < a.Length; i++)
            {
                res += (a[i] - b[i]) * (a[i] - b[i]);
            }
            res = Math.Pow(res, 0.5);
            return res;
        }

        public void  cluster(double[][] r, int n, double dis)
        {
            // 寻找最小距离所在的行列
            int mx = 0;
            int my = 0;
            double temp = MAX;
          for (int i = 0; i < r.Length; i++) 
           { 
            for (int j = 0; j < r.Length; j++) 
             {
                 if (j > i)
                 {
                    if (temp > r[i][j])
                    {
                        temp = r[i][j];
                         mx = i;
                         my = j;
                    }
                    if (temp > dis)
                    {
                        return ;
                    }
                   // 将最小距离所在的行列实例聚类合并
                    ds.union(ds.find(mx), ds.find(my));  
                     double[] va = r[mx];
                     double[] vb = r[my];
                     double[] vc = new double[n];
                     double[] vd = new double[n];
                     for (int m = 0; m < n; m++)
                     {
                         double tm = Math.Min(va[m], vb[m]);
                           if (tm != 0)
                                 vc[i] = tm;
                            else
                                 vc[i] = MAX;
                                 vd[i] = MAX;

                     }
                     r[mx] = vc;
                     r[my] = vd;
                     for (int k = 0; k < n; k++)
                     { 
                         // 更新距离矩阵
                         r[k][mx] = vc[k];
                         r[k][my] = vd[k];
                     }
                     // 继续聚类,递归直至所有矩阵之间距离小于dis值
                      cluster(r, n, dis); 
                 }
             }
            
           }
        }
        public void cluster(double[][] r, int cnum)
        {
            while (cc > cnum)
            {
                // 继续聚类,循环直至聚类个数等于cnum
                int mx = 0, my = 0;
                double vmin = MAX;
                for (int i = 0; i < r.Length; i++)
                {
                    // 寻找最小距离所在的行列
                    for (int j = 0; j < r.Length; j++)
                    {
                        if (j > i)
                        {
                            if (vmin > r[i][j])
                            {
                                vmin = r[i][j];
                                mx = i;
                                my = j;
                            }
                        }
                    } 
                    //将最小距离所在的行列实例聚类合并
                    ds.union(ds.find(mx), ds.find(my));
                    double[] va = r[mx];
                    double[] vb = r[my];
                    double[] vc = new double[n];
                    double[] vd = new double[n];
                    for (int k = 0; k < r.Length; k++)
                    {
                       double tm = Math.Min(va[k], vb[k]);
                       if (tm != 0)
                           vc[k] = tm;
                       else
                           vc[k] = MAX;
                           vd[k] = MAX;
                   }
                    r[mx] = vc;
                    r[my] = vd;
                    for (int j = 0; j < r.Length; j++)
                    {
                        // 更新距离矩阵
                       r[j][mx] = vc[j];
                       r[j][my] = vd[j];
                    }
                     cc--;
                    
                }
                 
            }
           
        }

        //private void button2_Click(object sender, EventArgs e)
        //{
        //    double[,] res1 = Calc1(x);
        //    // double[,] res1 = cluster(r, n, dis);
        //}

       
    }
}




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace fen
{
    public class DisjointSets
    {
        private int[] s;
        public DisjointSets(int numElements)
        {
          s = new int[numElements];
            for (int i = 0; i < s.Length; i++)
                s[i] = -1;
        }
        public void union(int root1, int root2)
        {
            assertIsRoot(root1);
            assertIsRoot(root2);
            if (root1 == root2)
                throw new Exception("Union: root1 == root2 " + root1);

            if (s[root2] < s[root1])
                s[root1] = root2;
            else
            {
                if (s[root1] == s[root2])
                    s[root1]--;
                s[root2] = root1;
            }
        }
        public int find(int x)
        {
            assertIsItem(x);
            if (s[x] < 0)
                return x;
            else
                return s[x] = find(s[x]);
        }
        private void assertIsRoot(int root)
        {
            assertIsItem(root);
            if (s[root] >= 0)
                throw new Exception("Union: " + root + " not a root");
        }

        private void assertIsItem(int x)
        {
            if (x < 0 || x >= s.Length)
                throw new Exception("Disjoint sets: " + x + " not an item");
        } 





    }
}


 public void  cluster(double[][] r, int n, double dis)的方法我如何写能让WinFrom中Button调用 --------------------编程问答-------------------- 没人会吗? --------------------编程问答--------------------
--------------------编程问答-------------------- 找本C#的语法书看看。 --------------------编程问答-------------------- 在button的click事件中调用cluster函数 --------------------编程问答-------------------- 问一下,你这个cluster函数中的第一个参数的意义是什么?
补充:.NET技术 ,  .NET Framework
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,