最近在看knn算法,顺便敲敲代码。

  王小明,他的长辈肯定有姓王的,彭河村村头不就有家王姓人家吗,可能就是那家的小孩,一个走丢的小孩就成功的回家了。

规则

  1. 每次移动一个盘子
  2. 任何时候大盘子在下面,小盘子在上面

 

  命名规范就如同给人起名一样,从名字中传达出一些信息,比如作用域、类型,能够起到见名知义的作用,在开发的时候,有个良好的命名规范能够提升不少的开发效率。特别是团队开发的时候,每个人的命名规范不同,在调用或维护的时候,还要花时间来揣摩作者创建类或字段的意图。

方法

假设共n个盘子

  • 当n=1时:
    1. 直接把A上的一个盘子移动到C上(A->C)
  • 当n=2时:
    1. 把小盘子从A放到B上(A->B)这里开始采用参数,rsc源地址=A,dst目的地址=B
    2. 把大盘子从A放到C上( A->C)rsc=A, dst=C
    3. 把小盘子从B放到C上(B->C)rsc=B, dst=C
  • 当n=3时:
    1. 把A上的两个盘子,通过C移动到B上去,
      调用递归实现(A-C->B)rsc=A, trans中转=C, dst=B
    2. 把A上剩下的一个最大盘子移动到C上(A->C)rsc=A, dst=C
    3. 把B上两个盘子,借助于A,挪到C上去, 调用递归(B-A->C)rsc=B,
      trans=A, dst=C
  • 当n=n时:

    1. 把A上的n-1个盘子,借助于C,移动到B上去,调用递归(A-C->B)rsc=A,
      trans=C, dst=B

    2. 把A上的最大一个盘子,移动到C上(A->C)rsc=A, dst=C

    3. 把B上n-1个盘子,借助于A,移动到C上,
      调用递归(B-A->C)rsc=B, trans=A, dst=C

每次都是先将其他圆盘移到辅助柱子上,再将最底下的移到C,然后再把原先柱子作为辅助柱子,重复

  knn属于数据挖掘的分类算法。基本思想是在距离空间里,如果一个样本的最接近的k个邻居里,绝大多数属于某个类别,则该样本也属于这个类别。俗话叫,“随大流”。

  • 命名空间:使用格式<Company>.<Compinent>,如,Weimei.Study,这样规范主要是为了在引用了第三方库的时候防止命名空间重名,造成编码是的混淆;
  • 类、接口、方法及属性:使用Pascal命名规则,如,GetDescript;
  • 变量:使用Camel命名规则,如,personCount;
  • 常量:全部大写,单词之间用下划线“_”隔开,如,GROW_UP_AGE。

    namespace Weimei.Study
    {
    
      class Person 
        {
            public const int GROW_UP_AGE = 18;
            private string _name;
            public string Name;
            { 
                 get{ return _name;}
                 set{ _name = value;}
            }
            public int Age { get; set; }
        }
    
        interface IPersonService
        {
            string GetDescript();
        }
    }
    

     

代码实现

def move(n, a, b, c):
'''
汉诺塔的递归实现
n:代表几个盘子
a:代表第一个塔,rsc
b:代表第二个塔,trans
c:代表第三个塔, dst
'''
    if n == 1:
        print(a, '=>', c)
    else:
        move(n-1, a, c, b)
        print(a, '=>', c)
        move(n-1, b, a, c)

  简单来说,KNN可以看成:有那么一堆你已经知道分类的数据,然后当一个新的数据进入的时候,就开始跟训练里的每个点求距离,然后挑出离这个数据最近的K个点,看看这K个点属于什么类型,然后用少数服从多数的原则,给新数据归类。

 

  该算法的示意图,简单明了:

  使用前缀或后缀作为标识,区分不同的职能或类型:

  图片 1

  • 接口:使用字母”I“作为前缀;
  • 静态变量:使用“s_”作为前缀;
  • 实体变量:使用“m_”作为前缀;
  • 成员变量:使用“_”作为前缀。

    namespace Weimei.Study
    {
        class Program
        {
            static void Main(string[] args)
            {
                Person m_person = new Person();
                m_person.Name = "王小明";
                m_person.Age = 12;
                IPersonService m_ps = new PersonService(m_person);
                string result = m_ps.GetDescript();
    
                Console.WriteLine(result);
                Console.ReadLine();
            }
        }
    
        class Person
        {
            public const int GROW_UP_AGE = 18;//成年年龄
            private string _name;
            public string Name
            { 
                 get{ return _name;}
                 set{ _name = value;}
            }
            public int Age { get; set; }
        }
    
        interface IPersonService
        {
            string GetDescript();
        }
    
        class PersonService : IPersonService
        {
            Person _m_person;
    
            public PersonService(Person m_person) 
            {
                _m_person = m_person;
            }
            public string GetDescript()
            {
                string desc = "未成年";
                if (_m_person.Age >= Person.GROW_UP_AGE) 
                {
                    desc = "已成年";
                }
    
                return _m_person.Name + desc;
            }
        }
    }
    

     注意事项:

  • 在起名字时,不要随意起,比如变量int
    a,其他人要知道这个变量是干什么用的还要看下面的代码。如果变量使用来计数的,则应起名为xxCount;

  • 创建类时不要与内置类名相同,以免混淆;
  • 适当使用前缀和后缀,反之会适得其反。

    下面的算法步骤取自于百度文库(文库是一个好东西),代码是参照这个思路实现的:

 

   图片 2

 

  code:

  1 #include<stdio.h>
  2 #include<math.h>
  3 #include<stdlib.h>
  4 
  5 #define K 3 //近邻数k
  6 typedef float type;
  7 
  8 //动态创建二维数组
  9 type **createarray(int n,int m)
 10 {
 11     int i;
 12     type **array;
 13     array=(type **)malloc(n*sizeof(type *));
 14     array[0]=(type *)malloc(n*m*sizeof(type));
 15     for(i=1;i<n;i++) array[i]=array[i-1]+m;
 16     return array;
 17 }
 18 //读取数据,要求首行格式为 N=数据量,D=维数
 19 void loaddata(int *n,int *d,type ***array,type ***karray)
 20 {
 21     int i,j;
 22     FILE *fp;
 23     if((fp=fopen("data.txt","r"))==NULL)    fprintf(stderr,"can not open data.txt!\n");
 24     if(fscanf(fp,"N=%d,D=%d",n,d)!=2)    fprintf(stderr,"reading error!\n");
 25     *array=createarray(*n,*d);
 26     *karray=createarray(2,K);
 27 
 28     for(i=0;i<*n;i++)
 29         for(j=0;j<*d;j++)
 30             fscanf(fp,"%f",&(*array)[i][j]);    //读取数据
 31 
 32     for(i=0;i<2;i++)
 33         for(j=0;j<K;j++)
 34             (*karray)[i][j]=9999.0;    //默认的最大值
 35     if(fclose(fp))    fprintf(stderr,"can not close data.txt");
 36 }
 37 //计算欧氏距离
 38 type computedistance(int n,type *avector,type *bvector)
 39 {
 40     int i;
 41     type dist=0.0;
 42     for(i=0;i<n;i++)
 43         dist+=pow(avector[i]-bvector[i],2);
 44     return sqrt(dist);
 45 }
 46 //冒泡排序
 47 void bublesort(int n,type **a,int choice)
 48 {
 49     int i,j;
 50     type k;
 51     for(j=0;j<n;j++)
 52         for(i=0;i<n-j-1;i++){
 53             if(0==choice){
 54                 if(a[0][i]>a[0][i+1]){
 55                     k=a[0][i];
 56                     a[0][i]=a[0][i+1];
 57                     a[0][i+1]=k;
 58                     k=a[1][i];
 59                     a[1][i]=a[1][i+1];
 60                     a[1][i+1]=k;
 61                 }
 62             }
 63             else if(1==choice){
 64                 if(a[1][i]>a[1][i+1]){
 65                     k=a[0][i];
 66                     a[0][i]=a[0][i+1];
 67                     a[0][i+1]=k;
 68                     k=a[1][i];
 69                     a[1][i]=a[1][i+1];
 70                     a[1][i+1]=k;
 71                 }
 72             }
 73         }
 74 }
 75 //统计有序表中的元素个数
 76 type orderedlist(int n,type *list)
 77 {
 78     int i,count=1,maxcount=1;
 79     type value;
 80     for(i=0;i<(n-1);i++) {
 81         if(list[i]!=list[i+1]) {
 82             //printf("count of %d is value %d\n",list[i],count);
 83             if(count>maxcount){
 84                 maxcount=count;
 85                 value=list[i];
 86                 count=1;
 87             }
 88         }
 89         else
 90             count++;
 91     }
 92     if(count>maxcount){
 93             maxcount=count;
 94             value=list[n-1];
 95     }
 96     //printf("value %f has a Maxcount:%d\n",value,maxcount);
 97     return value;
 98 }
 99 
100 int main()
101 {
102     int i,j,k;
103     int D,N;    //维度,数据量
104     type **array=NULL;  //数据数组
105     type **karray=NULL; //  K近邻点的距离及其标签
106     type *testdata; //测试数据
107     type dist,maxdist;
108 
109     loaddata(&N,&D,&array,&karray);
110     testdata=(type *)malloc((D-1)*sizeof(type));
111     printf("input test data containing %d numbers:\n",D-1);
112     for(i=0;i<(D-1);i++)    scanf("%f",&testdata[i]);
113 
114     while(1){
115     for(i=0;i<K;i++){
116         if(K>N) exit(-1);
117         karray[0][i]=computedistance(D-1,testdata,array[i]);
118         karray[1][i]=array[i][D-1];
119         //printf("first karray:%6.2f  %6.0f\n",karray[0][i],karray[1][i]);
120     }
121 
122     bublesort(K,karray,0);
123     //for(i=0;i<K;i++)    printf("after bublesort in first karray:%6.2f  %6.0f\n",karray[0][i],karray[1][i]);
124     maxdist=karray[0][K-1]; //初始化k近邻数组的距离最大值
125 
126     for(i=K;i<N;i++){
127         dist=computedistance(D-1,testdata,array[i]);
128         if(dist<maxdist)
129             for(j=0;j<K;j++){
130                 if(dist<karray[0][j]){
131                     for(k=K-1;k>j;k--){ //j后元素复制到后一位,为插入做准备
132                         karray[0][k]=karray[0][k-1];
133                         karray[1][k]=karray[1][k-1];
134                     }
135                     karray[0][j]=dist;  //插入到j位置
136                     karray[1][j]=array[i][D-1];
137                     //printf("i:%d  karray:%6.2f %6.0f\n",i,karray[0][j],karray[1][j]);
138                     break;  //不比较karray后续元素
139                 }
140             }
141         maxdist=karray[0][K-1];
142         //printf("i:%d  maxdist:%6.2f\n",i,maxdist);
143     }
144     //for(i=0;i<K;i++)    printf("karray:%6.2f  %6.0f\n",karray[0][i],karray[1][i]);
145     bublesort(K,karray,1);
146     //for(i=0;i<K;i++)    printf("after bublesort in karray:%6.2f  %6.0f\n",karray[0][i],karray[1][i]);
147     printf("\nThe data has a tag: %.0f\n\n",orderedlist(K,karray[1]));
148 
149     printf("input test data containing %d numbers:\n",D-1);
150     for(i=0;i<(D-1);i++)    scanf("%f",&testdata[i]);
151     }
152     return 0;
153 }

发表评论

电子邮件地址不会被公开。 必填项已用*标注