【C】【吐血整理】你们要的C语言实例大全-综合应用篇

目录

实例94 用C语言实现遗传算法

实例95 人工神经网络的C语言实现

实例96 K_均值算法

实例97 ISODATA算法

实例98 快速傅立叶变换

实例99 求解野人与传教士问题

实例100 简单专家系统


实例94 用C语言实现遗传算法

ga.c

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>#define SUM 20            //总共的染色体数量
#define MAXloop 1200       //最大循环次数
#define error 0.01        //若两次最优值之差小于此数则认为结果没有改变
#define crossp 0.7        //交叉概率
#define mp 0.04           //变异概率struct gen                //定义染色体结构
{int info;        float suitability;
};
struct gen gen_group[SUM];//定义一个含有20个染色体的组
struct gen gen_new[SUM];  struct gen gen_result;    //记录最优的染色体
int result_unchange_time; //记录在error前提下最优值为改变的循环次数struct log                //形成链表,记录每次循环所产生的最优的适应度
{float suitability;struct log *next;
}llog,*head,*end;
int log_num;              //链表长度void initiate();
void evaluation(int flag);
void cross();
void selection();
int  record();
void mutation();
void showresult(int);int   randsign(float p);
int   randbit(int i,int j);
int   randnum();
int   convertionD2B(float x);
float convertionB2D(int x);
int   createmask(int a);void main()
{int i,flag;flag=0;initiate();evaluation( 0 );for( i = 0 ; i < MAXloop ; i++ ){cross();evaluation( 1 );selection();if( record() == 1 ){flag = 1;break;}mutation();}showresult( flag );
}void initiate()
{int i , stime; long ltime;ltime=time(NULL);stime=(unsigned)ltime/2;srand(stime);for( i = 0 ; i < SUM ; i++ ){gen_group[i].info = randnum();        }gen_result.suitability=1000;result_unchange_time=0;head=end=(struct log *)malloc(sizeof(llog));if(head==NULL){printf("\n内存不够!\n");exit(0);}end->next = NULL;log_num = 1;
}void evaluation(int flag)
{int i,j;struct gen *genp;int gentinfo;float gentsuitability;float x;if( flag == 0 )genp = gen_group;else genp = gen_new;for(i = 0 ; i < SUM ; i++)//计算各染色体对应的表达式值{x = convertionB2D( genp[i].info );genp[i].suitability = x*(x*(x*(x*(x*(x-10)-26)+344)+193)-1846)-1680;}for(i = 0 ; i < SUM - 1 ; i++)//按表达式的值进行排序,{for(j = i + 1 ; j < SUM ; j++){if( genp[i].suitability > genp[j].suitability ){gentinfo = genp[i].info;genp[i].info = genp[j].info;genp[j].info = gentinfo;gentsuitability = genp[i].suitability;genp[i].suitability = genp[j].suitability;genp[j].suitability = gentsuitability;      }}}
}void cross()
{int i , j , k ;int mask1 , mask2;int a[SUM];for(i = 0 ; i < SUM ; i++)  a[i] = 0;k = 0;for(i = 0 ; i < SUM ; i++){if( a[i] == 0){for( ; ; )//随机找到一组未进行过交叉的染色体与a[i]交叉{j = randbit(i + 1 , SUM - 1);if( a[j] == 0)   break;}if(randsign(crossp) == 1){mask1 = createmask(randbit(0 , 14));mask2 = ~mask1;gen_new[k].info = (gen_group[i].info) & mask1 + (gen_group[j].info) & mask2;gen_new[k+1].info=(gen_group[i].info) & mask2 + (gen_group[j].info) & mask1;k = k + 2;}else {gen_new[k].info=gen_group[i].info;gen_new[k+1].info=gen_group[j].info;k=k+2;}a[i] = a[j] = 1;}}
}void selection()
{int i , j , k;j = 0;i = SUM/2-1;if(gen_group[i].suitability < gen_new[i].suitability){for(j = 1 ; j < SUM / 2 ; j++){if(gen_group[i+j].suitability > gen_new[i-j].suitability)break;}}elseif(gen_group[i].suitability>gen_new[i].suitability){for(j=-1;j>-SUM/2;j--){if(gen_group[i+j].suitability<=gen_new[i-j].suitability)break;}}for(k=j;k<SUM/2+1;k++){gen_group[i+k].info = gen_new[i-k].info;gen_group[i+k].suitability = gen_new[i-k].suitability;}
}int record()
{float x;   struct log *r;r=(struct log *)malloc(sizeof(llog));if(r==NULL){printf("\n内存不够!\n");exit(0);}r->next = NULL;end->suitability = gen_group[0].suitability;end->next = r;end = r;log_num++;x = gen_result.suitability - gen_group[0].suitability;if(x < 0)x = -x;if(x < error){result_unchange_time++;if(result_unchange_time >= 20)return 1;}else{gen_result.info = gen_group[0].info;gen_result.suitability = gen_group[0].suitability;result_unchange_time=0;}return 0;
}void mutation()
{int i , j , m;float x;float gmp;int gentinfo;float gentsuitability;gmp = 1 - pow(1 - mp , 11);//在基因变异概率为mp时整条染色体的变异概率for(i = 0 ; i < SUM ; i++){if(randsign(gmp) == 1){j = randbit(0 , 14);m = 1 << j;gen_group[i].info = gen_group[i].info^m;x = convertionB2D(gen_group[i].info);gen_group[i].suitability = x*(x*(x*(x*(x*(x-10)-26)+344)+193)-1846)-1680;}}for(i = 0 ; i < SUM - 1 ; i++){for(j = i + 1 ; j < SUM ; j++){if(gen_group[i].suitability > gen_group[j].suitability){gentinfo = gen_group[i].info;gen_group[i].info = gen_group[j].info;gen_group[j].info = gentinfo;gentsuitability = gen_group[i].suitability;gen_group[i].suitability = gen_group[j].suitability;gen_group[j].suitability = gentsuitability;}}}
}void showresult(int flag)//显示搜索结果并释放内存
{int i , j;struct log *logprint,*logfree;FILE *logf;if(flag == 0)printf("已到最大搜索次数,搜索失败!");else {printf("当取值%f时表达式达到最小值为%f\n",convertionB2D(gen_result.info),gen_result.suitability);printf("收敛过程记录于文件log.txt");if((logf = fopen("log.txt" , "w+")) == NULL){printf("Cannot create/open file");exit(1);}logprint=head;for(i = 0 ; i < log_num ; i = i + 5)//对收敛过程进行显示{for(j = 0 ; (j < 5) & ((i + j) < log_num-1) ; j++){fprintf(logf , "%20f" , logprint->suitability);logprint=logprint->next;               }fprintf(logf,"\n\n");}}for(i = 0 ; i< log_num ; i++)//释放内存{logfree=head;head=head->next;free(logfree);fclose(logf);}getchar();
}int randsign(float p)//按概率p返回1
{if(rand() > (p * 32768))return 0;else return 1;
}
int randbit(int i, int j)//产生在i与j之间的一个随机数
{int a , l;l = j - i + 1;a = i + rand() * l / 32768;return a;
}
int randnum()
{int x;x = rand() / 2;return x;
}
float convertionB2D(int x)
{float y;y = x;y = (y - 8192) / 1000;return y;}
int convertionD2B(float x)
{int g;g = (x * 1000) + 8192;return g;
}
int createmask(int a)
{int mask;mask=(1 << (a + 1)) - 1;return mask;
}

实例95 人工神经网络的C语言实现

BP.C

#include "math.h"
#include "time.h"
#include "stdio.h"
#include "stdlib.h"
#define Ni 1
#define Nm 4
#define No 1
#define L 100
#define Enom 0.02
#define loopmax 100000
#define e 2.71828
double E;
double a,u,n;
double W1[Ni][Nm],D1[Ni][Nm],W2[Nm][No],D2[Nm][No];
double D22[Nm][No],D11[Ni][No];
double a1[Ni][Nm],a2[Nm][No];
double Pi[L][Ni],Pm[L][Nm],Po[L][No],T[L][No];
double Xm[L][Nm],Xo[L][No];
double Qm[L][Nm],Qo[L][No];
void proceed();
void proceedR();
void forQ();
void amend();
void initiate();
double newa(double a,double D);
double cal(double d);
double vcal(double d);
main()
{long int i;int flag;char choice;for(;;){flag=0;initiate();for(i=0;;i++){proceed();if( E < Enom ){ flag=1;break;}if( i >= loopmax){flag = -1;break;}if(i%2500==0)printf("第%10d轮误差:%20f,学习速率:%10f\n",i,E,a1[0][0]);forQ();amend();}if(flag>0)proceedR();else printf("训练失败!\n");for(;;){choice=getchar();printf("是否继续?(Y/N)\n");choice=getchar();choice=toupper(choice);if(choice=='Y')break;if(choice=='N')exit(0);}}
}
void initiate()
{int i,j;int random;double x;double step;int stime; long ltime;ltime=time(NULL);stime=(unsigned)ltime/2;srand(stime);a=0.02;u=1;n=1;printf("本程序将用BP神经网络拟合函数:Y=sin(X)\n\n");for( i=0; i<Nm; i++){for( j=0; j<Ni; j++){random=rand()%100-50;x=random;x=x/100;W1[j][i]=x;D11[j][i]=0;D1[j][i]=0;a1[j][i]=0.01;}for( j=0; j<No; j++){random=rand()%100-50;x=random;x=x/100;W2[i][j]=x;D22[i][j]=0;D2[i][j]=0;a2[i][j]=0.01;}}step=1.0/L;for(i=0;i<L;i++){x=i;Pi[i][0]=x*step;T[i][0]=sin(Pi[i][0]);}printf("初始化成功!\n\n下面将对神经网络进行训练请稍候。\n");
}
void proceed()
{int i, j, k;E=0 ;for( i=0; i<L; i++ ){for( j=0; j<Nm; j++ ){Pm[i][j] = 0;for( k=0; k<Ni; k++ ){Pm[i][j] = Pi[i][k] * W1[k][j] + Pm[i][j];}Xm[i][j] = cal( Pm[i][j] );}for( j=0; j<No; j++){Po[i][j] = 0;for( k=0; k<Nm; k++){Po[i][j] = Xm[i][k] * W2[k][j] + Po[i][j];}Xo[i][j] = cal( Po[i][j] );E = E + ( Xo[i][j] - T[i][j] ) * ( Xo[i][j] - T[i][j] ) / 2;}}
}
void forQ()
{int i,j,k;for( i=0; i<L; i++ ){for( j=0; j<No; j++){Qo[i][j] = ( T[i][j] - Xo[i][j] )* vcal( Xo[i][j] );}for(j=0; j<Nm; j++){Qm[i][j]=0;for( k=0; k<No; k++){Qm[i][j] = Qo[i][k] * W2[j][k] + Qm[i][j];}Qm[i][j] = Qm[i][j] * vcal( Xm[i][j] );}}
}
void amend()
{int i,j,k;double D;for( i=0; i<Nm; i++){for( j=0; j<Ni; j++){D1[j][i]=0;}for( j=0; j<No; j++){D2[i][j]=0;}}for( i=0; i<Ni; i++){for( j=0; j<Nm; j++){for( k=0; k<L; k++){D1[i][j] = Qm[k][j] * Pi[k][i] + D1[i][j];}D = D1[i][j] * D11[i][j]  ;//为D11付初值a1[i][j] = newa( a1[i][j] , D );  // a 付初值W1[i][j] = W1[i][j] + a1[i][j] * ( n * D1[i][j] + ( 1 - n ) * D11[i][j] );D11[i][j] = D1[i][j];}}for( i=0; i<Nm; i++){for( j=0; j<No; j++){for( k=0; k<L; k++){D2[i][j] = Qo[k][j] * Xm[k][i] + D2[i][j];}D = D2[i][j] * D22[i][j]  ;//为D11付初值a2[i][j] = newa( a2[i][j] , D ); W2[i][j] = W2[i][j] + a2[i][j] * ( n * D2[i][j] + ( 1 - n ) * D22[i][j] );D22[i][j] = D2[i][j];}}
}void proceedR()
{int i, j;float x;double input,output;char choice;for(;;){for(;;){printf("在此输入需要计算的值(0,1):\n");scanf("%f",&x);input=(double)x;if((input>=0)&(input<=1))break;          printf("注意输入值应介于0、1之间!\n");for(;;){choice=getchar();printf("是否继续?(Y/N)\n");choice=getchar();choice=toupper(choice);if(choice=='Y')break;if(choice=='N')exit(0);            }}for(i=0;i<Nm;i++){Pm[0][i]=0;for( j=0; j<Ni; j++ ){Pm[0][i] =  input* W1[j][i]+Pm[0][i] ;}Xm[0][i] = cal( Pm[0][i] );}for( i=0; i<No; i++){Po[0][i] = 0;for( j=0; j<Nm; j++){Po[0][i] = Xm[0][j] * W2[j][i]+Po[0][i];}}output=cal( Po[0][0] );printf("输入值为%20f对应的结果为%f\n",input,output);printf("输入值为%20f对应的正常结果为%f\n",input,sin(input));for(;;){choice=getchar();printf("是否继续?(Y/N)\n");choice=getchar();choice=toupper(choice);if(choice=='Y')break;if(choice=='N')exit(0);          }}
}double newa(double a, double D)
{if( D > 0 ){{if(a<=0.04)a = a * 2;else a=0.08;}}elseif ( D < 0){if(a>=0.02){a = a / 2;}else a=0.01;}return a;
}
double cal(double d)
{d =  - (d * u);                                //              chushihua d = exp( d );d = 1 / ( 1 + d );return d;
}
double vcal(double d)
{return u * d * ( 1 - d );
}
trust100@ubuntu:~/test/clanguage$ ./a.out
本程序将用BP神经网络拟合函数:Y=sin(X)初始化成功!下面将对神经网络进行训练请稍候。
第         0轮误差:            3.182817,学习速率:  0.010000
第      2500轮误差:            3.182817,学习速率:  0.010000
第      5000轮误差:            3.182817,学习速率:  0.010000
第      7500轮误差:            3.182817,学习速率:  0.010000
第     10000轮误差:            3.182817,学习速率:  0.010000
第     12500轮误差:            3.182817,学习速率:  0.010000
第     15000轮误差:            3.182817,学习速率:  0.010000
第     17500轮误差:            3.182817,学习速率:  0.010000
第     20000轮误差:            3.182817,学习速率:  0.010000
第     22500轮误差:            3.182817,学习速率:  0.010000
第     25000轮误差:            3.182817,学习速率:  0.010000
第     27500轮误差:            3.182817,学习速率:  0.010000
第     30000轮误差:            3.182817,学习速率:  0.010000
第     32500轮误差:            3.182817,学习速率:  0.010000
第     35000轮误差:            3.182817,学习速率:  0.010000
第     37500轮误差:            3.182817,学习速率:  0.010000
第     40000轮误差:            3.182817,学习速率:  0.010000
第     42500轮误差:            3.182817,学习速率:  0.010000
第     45000轮误差:            3.182817,学习速率:  0.010000
第     47500轮误差:            3.182817,学习速率:  0.010000
第     50000轮误差:            3.182817,学习速率:  0.010000
第     52500轮误差:            3.182817,学习速率:  0.010000
第     55000轮误差:            3.182817,学习速率:  0.010000
第     57500轮误差:            3.182817,学习速率:  0.010000
第     60000轮误差:            3.182817,学习速率:  0.010000
第     62500轮误差:            3.182817,学习速率:  0.010000
第     65000轮误差:            3.182817,学习速率:  0.010000
第     67500轮误差:            3.182817,学习速率:  0.010000
第     70000轮误差:            3.182817,学习速率:  0.010000
第     72500轮误差:            3.182817,学习速率:  0.010000
第     75000轮误差:            3.182817,学习速率:  0.010000
第     77500轮误差:            3.182817,学习速率:  0.010000
第     80000轮误差:            3.182817,学习速率:  0.010000
第     82500轮误差:            3.182817,学习速率:  0.010000
第     85000轮误差:            3.182817,学习速率:  0.010000
第     87500轮误差:            3.182817,学习速率:  0.010000
第     90000轮误差:            3.182817,学习速率:  0.010000
第     92500轮误差:            3.182817,学习速率:  0.010000
第     95000轮误差:            3.182817,学习速率:  0.010000
第     97500轮误差:            3.182817,学习速率:  0.010000
训练失败!

实例96 K_均值算法

k_algorithm.c

#include  <stdio.h>#include  <stdlib.h>#include  <string.h>#include  <math.h>int  vectornum;int  vectorsize;float  * datafield;float  * tempcenter;struct  GROUP{float  * center;//聚类中心坐标int  groupsize;//聚类包含的样本个数} g ,  * group;int  K;//聚类中心个数void  initiate ();//读入数据,初始化聚类中心,参数设定默认值int  allocate ();//将模式样本分配给最近的聚类void  showresult ();//显示分类结果float  distance (float  * x , float  * y);//计算两个向量间的欧氏距离float  data (int i , int j);//从datafield中读取指定位置的值float  * vector (int i);//从datafield中读取指定的样本向量void  write (int i , int j , float data);//向datafield中指定位置写入值void  main (){int  i;initiate ();for (i = 1 ; i < 50 ; i++){showresult ();if (allocate () == 1)break;}   showresult ();free (datafield);free (tempcenter);for (i = 0 ; i < K ; i++)free (group[i].center);}void  initiate (){int  i , j , size;float  d;FILE  * df;K = 2;if ((df = fopen ("data.txt" , "r")) == NULL){printf ("Cannot open file\n");exit (1);}fscanf (df , "%5d" , &vectornum);fscanf (df , "%5d" , &vectorsize);size = vectornum * (vectorsize + 1);datafield = (float *) calloc (size , sizeof (d));tempcenter = (float *) calloc (vectorsize , sizeof (d));for (i = 0 ; i < vectornum ; i++){for (j = 0 ; j < vectorsize ; j++){fscanf (df , "%10f" , &d);write (i , j + 1 , d);}write (i , 0 , -1);}if (feof (df)) printf (" File read error! ");fclose (df);   printf ("请输入聚类数:\n");scanf ("%d" , &K);group = (struct GROUP *) calloc (K , sizeof (g));   for (i = 0 ; i < K ; i++){group[i].center = (float*) calloc ((vectorsize) , sizeof (d));group[i].groupsize = 0;}for (i = 0 ; i < K ; i++){for (j = 0 ; j < vectorsize ; j++){*(group[i].center + j) = data (i , j + 1);}}}int  allocate(){int  i , j , k , flag , index;float  D , D1 , sum; for (i = 0 ; i < K ; i++){group[i].groupsize = 0;}for (i = 0 ; i < vectornum ; i++)//按距离分配到各聚类域{D = distance (group[0].center , vector(i));k = 0;for(j = 1 ; j < K ; j++){D1 = distance (group[j].center , vector(i));if(D > D1){k = j;D = D1;}}write (i , 0 , (float) k);       group[k].groupsize++;}flag = 1;for (index = 0 ; index < K ; index++)//计算新的聚类中心{for (j = 0 ; j < vectorsize ; j++)tempcenter[j] = 0.0;sum = (float) group[index].groupsize;for (i = 0 ; i < vectornum ; i++){if (index == (int) data (i , 0))for (j = 0 ; j < vectorsize ; j++)tempcenter[j] += data (i , j + 1) / sum;}for (j = 0 ; j < vectorsize ; j++){if ( tempcenter[j] != group[index].center[j]){group[index].center[j] = tempcenter[j];flag = 0;}}}return flag;  }void  showresult(){int  i , j , k;for (i = 0 ; i < K ; i++){ printf ("\n第%3d组聚类中心坐标为:" , i + 1);for (j = 0 ; j < vectorsize ; j++)printf (" %10f " , group[i].center[j]);printf (" \n聚类包含的样本点的坐标为:\n ");for (j = 0 ; j < vectornum ; j++){if (data (j , 0) == i){for (k = 0 ; k < vectorsize ; k++){printf (" %10f " , data (j , k + 1));}printf (" \n ");}} }printf (" \n ");}float  data (int i , int j){return *(datafield + i * (vectorsize + 1) + j);}void  write (int i , int j , float data){*(datafield + i * (vectorsize + 1) + j) = data;}float  * vector (int i){ return datafield + i * (vectorsize + 1) + 1;}float  distance (float  * x , float  * y)
{int  i;float  z;for (i = 0 , z = 0 ; i < vectorsize ; i++)z = z + ((* (x + i)) - (* (y + i)))*((* (x + i))-(* (y + i)));return (float) sqrt (z);}

数据文件 data.txt

    8    2  0.000000  0.000000  1.000000  1.000000  2.000000  2.000000  4.000000  3.000000  5.000000  3.000000  4.000000  4.000000  5.000000  4.000000  6.000000  5.000000       end

运行

 trust100@ubuntu:~/test/clanguage$ ./a.out
请输入聚类数:
10第  1组聚类中心坐标为:   0.000000    0.000000
聚类包含的样本点的坐标为:第  2组聚类中心坐标为:   1.000000    1.000000
聚类包含的样本点的坐标为:第  3组聚类中心坐标为:   2.000000    2.000000
聚类包含的样本点的坐标为:第  4组聚类中心坐标为:   4.000000    3.000000
聚类包含的样本点的坐标为:第  5组聚类中心坐标为:   5.000000    3.000000
聚类包含的样本点的坐标为:第  6组聚类中心坐标为:   4.000000    4.000000
聚类包含的样本点的坐标为:第  7组聚类中心坐标为:   5.000000    4.000000
聚类包含的样本点的坐标为:第  8组聚类中心坐标为:   6.000000    5.000000
聚类包含的样本点的坐标为:第  9组聚类中心坐标为:   0.000000    0.000000
聚类包含的样本点的坐标为:第 10组聚类中心坐标为:   0.000000    0.000000
聚类包含的样本点的坐标为:第  1组聚类中心坐标为:   0.000000    0.000000
聚类包含的样本点的坐标为:0.000000    0.000000  第  2组聚类中心坐标为:   1.000000    1.000000
聚类包含的样本点的坐标为:1.000000    1.000000  第  3组聚类中心坐标为:   2.000000    2.000000
聚类包含的样本点的坐标为:2.000000    2.000000  第  4组聚类中心坐标为:   4.000000    3.000000
聚类包含的样本点的坐标为:4.000000    3.000000  第  5组聚类中心坐标为:   5.000000    3.000000
聚类包含的样本点的坐标为:5.000000    3.000000  第  6组聚类中心坐标为:   4.000000    4.000000
聚类包含的样本点的坐标为:4.000000    4.000000  第  7组聚类中心坐标为:   5.000000    4.000000
聚类包含的样本点的坐标为:5.000000    4.000000  第  8组聚类中心坐标为:   6.000000    5.000000
聚类包含的样本点的坐标为:6.000000    5.000000  第  9组聚类中心坐标为:   0.000000    0.000000
聚类包含的样本点的坐标为:第 10组聚类中心坐标为:   0.000000    0.000000
聚类包含的样本点的坐标为:第  1组聚类中心坐标为:   0.000000    0.000000
聚类包含的样本点的坐标为:0.000000    0.000000  第  2组聚类中心坐标为:   1.000000    1.000000
聚类包含的样本点的坐标为:1.000000    1.000000  第  3组聚类中心坐标为:   2.000000    2.000000
聚类包含的样本点的坐标为:2.000000    2.000000  第  4组聚类中心坐标为:   4.000000    3.000000
聚类包含的样本点的坐标为:4.000000    3.000000  第  5组聚类中心坐标为:   5.000000    3.000000
聚类包含的样本点的坐标为:5.000000    3.000000  第  6组聚类中心坐标为:   4.000000    4.000000
聚类包含的样本点的坐标为:4.000000    4.000000  第  7组聚类中心坐标为:   5.000000    4.000000
聚类包含的样本点的坐标为:5.000000    4.000000  第  8组聚类中心坐标为:   6.000000    5.000000
聚类包含的样本点的坐标为:6.000000    5.000000  第  9组聚类中心坐标为:   0.000000    0.000000
聚类包含的样本点的坐标为:第 10组聚类中心坐标为:   0.000000    0.000000
聚类包含的样本点的坐标为:

实例97 ISODATA算法

isogroup.c

#include  <stdio.h>
#include  <stdlib.h>
#include  <string.h>
#include  <math.h>
float  * datafield;
int  vectornum;
int  vectorsize;
struct  GROUP
{float  * center;float  D;float  variance;int  groupsize;int  flag;//代表这个数组单元是否被占用
};
struct  GROUP  group[100];
int  maxindex;//最大聚类号
int  groupnum;
struct  CCD//记录各聚类中心的距离
{float  dst;int  g1 , g2;//聚类编号
}ccd  ,  * ccdhead;
float  Dst;void  write (int i , int j , float data);//
float  data (int i , int j);//
float  * vector (int  i);//void  initiate ();//
void  input ();//
void  allocate ();//将模式样本分配给最近的聚类
void  converge ();//
void  diverge ();//
void  renum ();//重新分配聚类号
void  showresult ();float  distance (float  * x , float  * y);
void  split (int i , int j);//
void  insert (int i , int j , float D);int  K;//预期的聚类中心数目
int  Nmin;//每一聚类中最少的样本数目,即如少于此数就不作为一个孤立的聚类
float  Ds;//一个聚类域中样本距离分布的标准差
float  Dm;//两个聚类中心之间的最小距离,如小于此数,两个聚类进行合并
int  L;//在于此迭代运算中可以合并的聚类中心的最多对数
int  I;//迭代运算的次数序号void  main ()
{int  i;initiate ();//读入数据,初始化聚类中心,参数设定默认值for (i = 1 ; ; i++){input ();//显示、修改参数allocate ();//完成第2-6步if (i == I){Dm = 0;converge ();break;}if (groupnum <= K / 2)  diverge ();else {if ((groupnum >= K * 2) | ( i % 2 == 0))converge ();else diverge ();}        renum ();       }showresult ();free (datafield);free (ccdhead);for (i = 0 ; i < 100 ; i++)free (group[i].center);
}
void  initiate ()
{int  i , j , size;FILE  * df;char  s[10];float  d;K = 2;Nmin = 1;Ds = 1;Dm = 4;L = 1;I = 5;maxindex = groupnum = 1;if ((df = fopen("data.txt" , "r")) == NULL){printf ("Cannot open file\n");exit (1);}fscanf (df , "%5d" , &vectornum);fscanf (df , "%5d" , &vectorsize);size = vectornum * (vectorsize + 1);datafield = (float *) malloc (size * sizeof (float));for (i = 0 ; i < vectornum ; i++){for (j = 0 ; j < vectorsize ; j++){fscanf (df , "%10f" , &d);write (i , j + 1 , d);}write (i , 0 , -1);}fscanf (df , "%10s" , s);if (strcmp (s , "end") != 0){printf ("\n程序初始化失败!");exit (1);}fclose (df);for (i = 0 ; i < 100 ; i++){group[i].flag = 0;group[i].center = (float *) malloc ((vectorsize) * sizeof (float));group[i].groupsize = 0;group[i].variance = 0;group[i].D = 0;}for (i = 0 ; i < groupnum ; i++){for (j = 0 ; j < vectorsize ; j++){* (group[i].center + j) = data(i , j + 1);///}group[i].flag = 1;}
}
void  input ()
{char  choice;printf ("\n\n现用的参数取值:\n");printf ("K = %d\n,Nmin=%d\n,Ds=%f\n,Dm=%f\n,L=%d\n,I=%d\n",K,Nmin,Ds,Dm,L,I);showresult();printf ("是否需要进行修改?(Y/N)\n");scanf("%s" , & choice);choice = toupper (choice);if (choice == 'Y'){printf ("\n请输入预期的聚类中心数目:");scanf ("%d" , &K);printf ("\n请输入每一聚类域中最少样本数:");scanf ("%d" , &Nmin);printf ("\n请输入一个聚类域中样本距离分布的标准差:");scanf ("%f" , &Ds);printf("\n请输入两聚类中心之间的最小距离:");scanf ("%f" , &Dm);printf ("\n请输入一次迭代运算中可以合并的聚类中心的最多数目:");scanf ("%d" , &L);printf ("\n请输入最大迭代次数:");scanf ("%d" , &I);}
}
void  allocate ()
{int  i , j , k , num , index;float  D , D1 , sum;for (i = 0 ; i < 100 ; i++)//为各聚类中心值清零{group[i].D = 0;group[i].groupsize = 0;group[i].variance = 0;}for (i=0 ; i < vectornum ; i++)//按距离分配到各聚类域{D = distance (group[0].center , vector (i));k = 0;for (j = 1 ; j < groupnum ; j++){D1 = distance (group[j].center , vector (i));if (D > D1){k = j;D = D1;}}write (i , 0 , (float) k);        group[k].groupsize++;}num = groupnum;for (i = 0 ; i < num ; i++)//当聚类中样本个数小于规定值时撤销聚类{if (group[i].groupsize < Nmin){group[i].flag = 0;group[i].groupsize = 0;for (j = 0 ; j < vectornum ; j++){if (data (j , 0) == i){write (j , 0 , -1.0);}}groupnum--;}}    for (i = 0 ; i < 100 ; i++)//为各聚类中心值清零{for (j = 0 ; j < vectorsize ; j++)* (group[i].center + j) = 0;}for (i = 0 ; i < vectornum ; i++)//计算新的聚类中心{index = (int) data (i , 0);if (index != -1){sum = (float) group[index].groupsize;for (j = 0 ; j < vectorsize ; j++){* (group[index].center + j) = * (group[index].center + j) + data(i , j + 1) / sum;}}}for (i = 0 ; i < vectornum ; i++)//计算各样点到聚类中心距离{index = (int) data (i , 0);if (index != -1){sum = (float) group[index].groupsize;D = distance (group[index].center , vector (i));group[index].D = group[index].D + D / sum;}}Dst = 0;for (i = 0 ; i < maxindex ; i++){if (group[i].flag != 0)Dst = Dst + group[i].D;}    Dst = Dst / groupnum;
}
void  diverge ()
{float  newvar , oldvar , center;int  i , j , k , l , flag;flag = 0;for (i = 0 ; i < maxindex ; i++){if (group[i].flag != 0){oldvar = 0;//标准差for (j = 0 , l = 0 ; j < vectorsize ; j++){//计算同一聚类域中各分量对应的标准差中的最大值        newvar = 0;center = * (group[i].center + j);for (k = 0 ; k < vectornum ; k++){if (data (k , 0) == i)newvar = newvar +(center - data(k , j+1))*(center - data(k , j+1));}if (newvar > oldvar){oldvar = newvar;l = j;}}group[i].variance = (float) sqrt( oldvar / group[i].groupsize);if (group[i].variance > Ds){if ((groupnum <= K/2) | ((group[i].D > Dst) & (group[i].groupsize > 2 * (Nmin + 1)))){split (i , l);flag = 1;   }}}}if (flag == 0)converge ();
}
void  split (int i , int j)
{int  k , l;k = maxindex;group[k].flag = 1;for (l = 0 ; l < vectorsize ; l++){* (group[k].center + l) = (* (group[i].center + l));}* (group[k].center + j) = (* (group[k].center + j) + group[i].variance);* (group[i].center + j) = (* (group[i].center + j) - group[i].variance);           maxindex++;groupnum++;
}
void  converge ()
{   int  i , j , k , h , l;float  D , c1 , c2 , n1 , n2;ccdhead = (struct CCD *) malloc (sizeof (ccd) * L);for (i = 0 , k = 0 ; i < maxindex - 1 ; i++){if (group[i].flag != 0){for (j = i + 1 ; j < maxindex ; j++){if (group[j].flag != 0){D = distance (group[i].center , group[j].center);if (D < Dm){if (k < L){(ccdhead + k)->dst = D;(ccdhead + k)->g1 = i;(ccdhead + k)->g2 = j;k++;}else{insert (i,j,D);                          }break;}}}}}        for (h = 0 ; h < k ;h++){i = (ccdhead + h)->g1;j = (ccdhead + h)->g2;n1 = (float) group[i].groupsize;n2 = (float) group[j].groupsize;for (l = 0 ; l < vectorsize ; l++){c1 = (* (group[i].center + l));c2 = (* (group[j].center + l));* (group[i].center + l) = (n1 * c1 + n2 * c2) / (n1 + n2);}group[i].groupsize = (int) (n1 + n2);for (l = 0 ; l < vectornum ; l++)if (data(l , 0) == j)write (l , 0 , (float) i);group[j].flag = 0;group[j].groupsize = 0;groupnum--;}
}
void  insert (int i , int j , float D)
{int  h , l;for (h = 0 ; h < L ; h++){if (D < (ccdhead + h)->dst){for (l = L - 1 ; l > h ; l--){(ccdhead + l)->dst = (ccdhead + l - 1)->dst;(ccdhead + l)->g1 = (ccdhead + l - 1)->g1;(ccdhead + l)->g2 = (ccdhead + l - 1)->g2;}(ccdhead + h)->dst = D;(ccdhead + h)->g1 = i;(ccdhead + h)->g2 = j;}}
}void  renum ()
{int  i , j , k;for (i = 0 ; i < maxindex - 1 ; i++){if (group[i].flag == 0){for (j = maxindex ; j > i ; j--){if (group[j].flag == 1){group[i].flag = 1;group[j].flag = 0;                  for (k = 0 ; k < vectorsize ; k++){* (group[i].center + k) = (* (group[j].center + k));* (group[j].center + k) = 0;}}}}}maxindex = groupnum;
}void  showresult ()
{int  i , j , k , l;for (j = 1 , i = 0 ; i < maxindex ; i++){if (group[i].flag != 0){printf ("第%3d组聚类中心坐标为:" , j ++);for (k = 0 ; k < vectorsize ; k++)printf (" %10f " , *(group[i].center + k));printf (" \n聚类包含的样本点的坐标为:\n ");for (k = 0 ; k < vectornum ; k++){if (data(k , 0) == i){for (l = 0 ; l < vectorsize ; l++){printf (" %10f " , data(k , l + 1));}printf (" \n ");}}}}
}
float  data (int i , int j)
{return  * (datafield + i * (vectorsize + 1) + j);
}
void  write (int i , int j , float data)
{* (datafield + i * (vectorsize + 1) + j) = data;
}
float  * vector (int i)
{ return  datafield + i * (vectorsize + 1) + 1;
}
float  distance (float  * x , float  * y)
{int  i;float  z;for (i = 0 , z = 0 ; i < vectorsize ; i++)z = z + ((* (x + i)) - (* (y + i))) * ((* (x + i))-(* (y + i)));return  (float) sqrt(z);
}

运行

trust100@ubuntu:~/test/clanguage$ ./a.out 现用的参数取值:
K = 2
,Nmin=1
,Ds=1.000000
,Dm=4.000000
,L=1
,I=5
第  1组聚类中心坐标为:   0.000000    0.000000
聚类包含的样本点的坐标为:是否需要进行修改?(Y/N)
N现用的参数取值:
K = 2
,Nmin=1
,Ds=1.000000
,Dm=4.000000
,L=1
,I=5
第  1组聚类中心坐标为:   1.378910    2.750000
聚类包含的样本点的坐标为:0.000000    0.000000  1.000000    1.000000  2.000000    2.000000  4.000000    3.000000  5.000000    3.000000  4.000000    4.000000  5.000000    4.000000  6.000000    5.000000  第  2组聚类中心坐标为:   5.371090    2.750000
聚类包含的样本点的坐标为:是否需要进行修改?(Y/N)
N现用的参数取值:
K = 2
,Nmin=1
,Ds=1.000000
,Dm=4.000000
,L=1
,I=5
第  1组聚类中心坐标为:   1.000000    1.000000
聚类包含的样本点的坐标为:0.000000    0.000000  1.000000    1.000000  2.000000    2.000000  第  2组聚类中心坐标为:   4.800000    3.800000
聚类包含的样本点的坐标为:4.000000    3.000000  5.000000    3.000000  4.000000    4.000000  5.000000    4.000000  6.000000    5.000000  是否需要进行修改?(Y/N)
N现用的参数取值:
K = 2
,Nmin=1
,Ds=1.000000
,Dm=4.000000
,L=1
,I=5
第  1组聚类中心坐标为:   1.000000    1.000000
聚类包含的样本点的坐标为:0.000000    0.000000  1.000000    1.000000  2.000000    2.000000  第  2组聚类中心坐标为:   4.800000    3.800000
聚类包含的样本点的坐标为:4.000000    3.000000  5.000000    3.000000  4.000000    4.000000  5.000000    4.000000  6.000000    5.000000  是否需要进行修改?(Y/N)
N现用的参数取值:
K = 2
,Nmin=1
,Ds=1.000000
,Dm=4.000000
,L=1
,I=5
第  1组聚类中心坐标为:   1.000000    1.000000
聚类包含的样本点的坐标为:0.000000    0.000000  1.000000    1.000000  2.000000    2.000000  第  2组聚类中心坐标为:   4.800000    3.800000
聚类包含的样本点的坐标为:4.000000    3.000000  5.000000    3.000000  4.000000    4.000000  5.000000    4.000000  6.000000    5.000000  是否需要进行修改?(Y/N)
N
第  1组聚类中心坐标为:   1.000000    1.000000
聚类包含的样本点的坐标为:0.000000    0.000000  1.000000    1.000000  2.000000    2.000000  第  2组聚类中心坐标为:   4.800000    3.800000
聚类包含的样本点的坐标为:4.000000    3.000000  5.000000    3.000000  4.000000    4.000000  5.000000    4.000000  6.000000    5.000000

实例98 快速傅立叶变换

fft.c

#include  <stdio.h>#include  <stdlib.h>#include  <math.h>#define  PI  3.14159265358979323846struct  COMPLEX{float  re;float  im;} cplx , * Hfield , * S , * R , * w;int  n , m;int  ln , lm;void  initiate ();void  dfft ();void  rdfft ();void  showresult ();void  fft (int l , int k);int  reverse (int t , int k);void  W (int l);int  loop (int l);void  conjugate ();void  add (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z);void  sub (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z);void  mul (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z);struct  COMPLEX  * Hread(int i , int j);void  Hwrite (int i , int j , struct  COMPLEX x);void  main (){initiate ();printf("\n原始数据:\n");showresult();getchar ();dfft ();printf("\n快速复利叶变换后的结果:\n");showresult ();getchar ();rdfft ();printf("\n快速复利叶逆变换后的结果:\n");showresult ();getchar ();free (Hfield);
}void  initiate (){//程序初始化操作,包括分配内存、读入要处理的数据、进行显示等FILE  * df;df = fopen ("data.txt" , "r");fscanf (df , "%5d" , &n);fscanf (df , "%5d" , &m);if ((ln = loop (n)) == -1){printf (" 列数不是2的整数次幂 ");exit (1);}if ((lm = loop (m)) == -1){printf (" 行数不是2的整数次幂 ");exit (1);}Hfield = (struct  COMPLEX *) malloc (n * m * sizeof (cplx));if (fread (Hfield , sizeof (cplx) , m * n , df) != (unsigned) (m * n)){if (feof (df)) printf (" Premature end of file ");else printf (" File read error ");}fclose (df);}void  dfft (){//进行二维快速复利叶变换int  i , j;  int  l , k;l = n;k = ln;w = (struct  COMPLEX *) calloc (l , sizeof (cplx));R = (struct  COMPLEX *) calloc (l , sizeof (cplx));S = (struct  COMPLEX *) calloc (l , sizeof(cplx));W (l);for ( i = 0 ; i < m ; i++ ){//按行进行快速复利叶变换for (j = 0 ; j < n ; j++){          S[j].re = Hread (i , j)->re;S[j].im = Hread (i , j)->im;}fft(l , k);for (j = 0 ; j < n ; j++)Hwrite (i , j , R[j]);}free (R);free (S);free (w);l = m;k = lm;w = (struct  COMPLEX *) calloc (l , sizeof (cplx));R = (struct  COMPLEX *) calloc (l , sizeof (cplx));S = (struct  COMPLEX *) calloc (l , sizeof (cplx));W (l);for (i = 0 ; i < n ; i++){//按列进行快速复利叶变换for(j = 0 ; j < m ; j++){S[j].re = Hread(j , i)->re;S[j].im = Hread(j , i)->im;}fft(l , k);for (j = 0 ; j < m ; j++)Hwrite (j , i , R[j]);}free (R);free (S);free (w);}void  rdfft (){conjugate ();dfft ();conjugate ();}void  showresult (){int  i , j;for (i = 0 ; i < m ; i++){printf ( " \n第%d行\n " , i);for (j = 0 ; j < n ; j++){if (j % 4 == 0) printf (" \n ");printf(" (%5.2f,%5.2fi) " , Hread (i , j)->re , Hread (i , j)->im);}}}void  fft (int l , int k){int  i , j , s , nv , t;float  c;struct  COMPLEX  mp , r;nv = l;c = (float) l;c = pow (c , 0.5);for (i = 0 ; i < k ; i++){for (t = 0 ; t < l ; t += nv){for (j = 0 ; j < nv / 2 ; j++){s = (t + j) >> (k - i -1);s = reverse(s , k);r.re = S[t + j].re;r.im = S[t + j].im;mul (&w[s] , &S[t + j + nv / 2] , &mp);/讲解传递结构指针和结构本身的区别add (&r , &mp , &S[t + j]);sub (&r , &mp , &S[t + j + nv / 2]);                }}nv = nv >> 1;      }for (i = 0 ; i < l ; i++){j = reverse(i , k);R[j].re = S[i].re / c;R[j].im = S[i].im / c;}}int  reverse (int t , int k){int  i , x , y;y = 0;for (i = 0 ; i < k ; i++){x = t & 1;t = t >> 1;y = (y << 1) + x;      }return y;
}void  W (int l){int i;float c , a;c = (float) l;c = 2 * PI / c;for (i = 0 ; i < l ; i++){      a = (float) i;w[i].re = (float) cos(a * c);w[i].im = -(float) sin(a * c);}}int  loop (int l){//检验输入数据是否为2的整数次幂,如果是返回用2进制表示时的位数int  i , m;if (l != 0){for (i = 1 ; i < 32 ; i++){m = l >> i;if (m == 0)break;}if (l == (1 << (i - 1)))return i - 1;}return -1;}void  conjugate (){//求复数矩阵的共轭矩阵int  i , j;for (i = 0 ; i < m ; i++){for (j = 0 ; j < n ; j++){Hread (i , j)->im *= -1;}}}struct  COMPLEX  * Hread (int i , int j){//按读矩阵方式返回Hfield中指定位置的指针return (Hfield + i * n + j);}void  Hwrite (int i , int j , struct  COMPLEX x)
{//按写矩阵方式将复数结构x写到指定的Hfield位置上(Hfield + i * n + j)->re = x.re;(Hfield + i * n + j)->im = x.im;}void  add (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z){//定义复数加法z->re = x->re + y->re;z->im = x->im + y->im; }void  sub (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z){//定义复数减法z->re = x->re - y->re;z->im = x->im - y->im;}void  mul (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z){//定义复数乘法z->re = (x->re) * (y->re) - (x->im) * (y->im);z->im = (x->im) * (y->re) + (x->re) * (y->im);}

data.txt

    8    4              €?       @      @@      €@      燖      繞      郂  €?      €?  €?  €?   @  €?  @@  €?  €@  €?  燖  €?  繞  €?  郂   @       @  €?   @   @   @  @@   @  €@   @  燖   @  繞   @  郂  @@      @@  €?  @@   @  @@  @@  @@  €@  @@  燖  @@  繞  @@  郂

运行

trust100@ubuntu:~/test/clanguage$ ./a.out 原始数据:第0行( 0.00, 0.00i)  ( 0.00, 1.00i)  ( 0.00, 2.00i)  ( 0.00, 3.00i)  ( 0.00, 4.00i)  ( 0.00, 5.00i)  ( 0.00, 6.00i)  ( 0.00, 7.00i)
第1行( 1.00, 0.00i)  ( 1.00, 1.00i)  ( 1.00, 2.00i)  ( 1.00, 3.00i)  ( 1.00, 4.00i)  ( 1.00, 5.00i)  ( 1.00, 6.00i)  ( 1.00, 7.00i)
第2行( 2.00, 0.00i)  ( 2.00, 1.00i)  ( 2.00, 2.00i)  ( 2.00, 3.00i)  ( 2.00, 4.00i)  ( 2.00, 5.00i)  ( 2.00, 6.00i)  ( 2.00, 7.00i)
第3行( 3.00, 0.00i)  ( 3.00, 1.00i)  ( 3.00, 2.00i)  ( 3.00, 3.00i)  ( 3.00, 4.00i)  ( 3.00, 5.00i)  ( 3.00, 6.00i)  ( 3.00, 7.00i) 快速复利叶变换后的结果:第0行( 8.49,19.80i)  (-6.83,-2.83i)  (-2.83,-2.83i)  (-1.17,-2.83i)  ( 0.00,-2.83i)  ( 1.17,-2.83i)  ( 2.83,-2.83i)  ( 6.83,-2.83i)
第1行(-2.83, 2.83i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)
第2行(-2.83, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)
第3行(-2.83,-2.83i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i)  ( 0.00, 0.00i) 快速复利叶逆变换后的结果:第0行( 0.00, 0.00i)  ( 0.00, 1.00i)  ( 0.00, 2.00i)  (-0.00, 3.00i)  ( 0.00, 4.00i)  (-0.00, 5.00i)  ( 0.00, 6.00i)  ( 0.00, 7.00i)
第1行( 1.00, 0.00i)  ( 1.00, 1.00i)  ( 1.00, 2.00i)  ( 1.00, 3.00i)  ( 1.00, 4.00i)  ( 1.00, 5.00i)  ( 1.00, 6.00i)  ( 1.00, 7.00i)
第2行( 2.00, 0.00i)  ( 2.00, 1.00i)  ( 2.00, 2.00i)  ( 2.00, 3.00i)  ( 2.00, 4.00i)  ( 2.00, 5.00i)  ( 2.00, 6.00i)  ( 2.00, 7.00i)
第3行( 3.00, 0.00i)  ( 3.00, 1.00i)  ( 3.00, 2.00i)  ( 3.00, 3.00i)  ( 3.00, 4.00i)  ( 3.00, 5.00i)  ( 3.00, 6.00i)  ( 3.00, 7.00i)

实例99 求解野人与传教士问题

AI.C

#include <stdio.h>
#include <stdlib.h>
#define maxloop 100    //最大层数,对于不同的扩展方法自动调整取值
#define pristnum 3
#define slavenum 3
struct SPQ
{int sr,pr;             //船运行一个来回后河右岸的野人、传教士的人数 int sl,pl;             //船运行一个来回后河左岸的野人、传教士的人数 int ssr,spr;           //回来(由左向右时)船上的人数int sst,spt;           //去时(由右向左时)船上的人数int loop;               //本结点所在的层数                 struct SPQ *upnode ,*nextnode;//本结点的父结点和同层的下一个结点的地址
}spq;
int loopnum;//记录总的扩展次数
int openednum;//记录已扩展节点个数
int unopenednum;//记录待扩展节点个数
int resultnum;
struct SPQ *opened;
struct SPQ *oend;
struct SPQ *unopened;
struct SPQ *uend;
struct SPQ *result;
void initiate();
void releasemem();
void showresult();
void addtoopened(struct SPQ *ntx);
int search();
void goon();
int stretch(struct SPQ* ntx);
void recorder();
void main()
{int flag;       //标记扩展是否成功 for( ; ; ){initiate();flag = search ();if(flag == 1){recorder();releasemem();showresult();goon();}else{printf("无法找到符合条件的解");releasemem();goon();}}
}
void initiate()
{int x;char choice;uend = unopened = (struct SPQ*)malloc(sizeof(spq));if(uend==NULL){printf("\n内存不够!\n");exit(0);}unopenednum=1;openednum=0;unopened -> upnode = unopened;       //保存父结点的地址以成链表unopened -> nextnode = unopened;unopened -> sr = slavenum;unopened -> pr = pristnum;unopened -> sl = 0;unopened -> pl = 0;unopened -> sst = 0;unopened -> spt = 0;unopened -> ssr = 0;unopened -> spr = 0;unopened -> loop = 0;printf("题目:设有n个传教士和m个野人来到河边,打算乘一只船从右岸到左岸去。\n");printf("该船的负载能力为两人。在任何时候,如果野人人数超过传教士人数,野人\n");printf("就会把传教士吃掉。他们怎样才能用这条船安全的把所有人都渡过河去?\n");printf("\n默认的n、m值皆为3\n");for(;;){printf("\n是否修改?(Y/N)");scanf("%s",&choice);choice=toupper(choice);if(choice=='Y'){          printf("\n请输入传教士人数");for(;;){scanf("%d",&x);if(x>0)  {unopened -> pr = x;break;}else printf("\n输入值应大于0!\n请重新输入");}printf("\n请输入野人人数");for(;;){scanf("%d",&x);if(x>0){unopened -> sr = x;break;}else printf("\n输入值应大于0!\n请重新输入");}   break;}if(choice=='N')break;}}
int search()
{int flag;struct SPQ *ntx;               //提供将要扩展的结点的指针for( ; ; ){ntx = unopened;        //从待扩展链表中提取最前面的一个if(ntx->loop == maxloop)return 0; addtoopened(ntx);       //将ntx加入已扩展链表,并将这个节点从待扩展链表中去掉flag = stretch(ntx);    //对ntx进行扩展,返回-1,0,1if(flag == 1)return 1;      }
}
int stretch(struct SPQ *ntx)
{int fsr , fpr ; //在右岸上的人数int fsl , fpl ; //在左岸上的人数int  sst , spt ; //出发时在船上的人数int ssr , spr ; //返回时船上的人数struct SPQ *newnode;for (sst = 0 ; sst <=  2 ; sst++) //讨论不同的可能性并判断是否符合条件{fsr = ntx -> sr;fpr = ntx -> pr;fsl = ntx -> sl;fpl = ntx -> pl;if ((sst <=  fsr) && (( 2 - sst) <=  fpr))//满足人数限制{spt = 2 - sst;fsr = fsr - sst;fpr = fpr - spt;if((fpr ==  0) && (fsr ==  0))//搜索成功{ newnode = (struct SPQ*) malloc (sizeof(spq));if(newnode==NULL){printf("\n内存不够!\n");exit(0);}newnode -> upnode = ntx;       //保存父结点的地址以成链表newnode -> nextnode = NULL;newnode -> sr = 0;newnode -> pr = 0;newnode -> sl = opened -> sr;newnode -> pl = opened -> pr;newnode -> sst = sst;newnode -> spt = spt;newnode -> ssr = 0;newnode -> spr = 0;newnode -> loop = ntx -> loop + 1;oend -> nextnode = newnode;oend = newnode;openednum++;return 1;}   else if ((fpr - fsr) * fpr >= 0) //判断是否满足传教士人数必须大于或等于野人人数{fsl = fsl + sst;fpl = fpl + spt;for (ssr = 0 ; ssr <= 1 ; ssr++)                  //返回{int ffsl , ffpl;if ((ssr <= fsl) && ((1 - ssr) <= fpl)){spr = 1 - ssr;ffsl = fsl - ssr;ffpl = fpl - spr;if ((ffpl - ffsl) * ffpl >= 0){  //若符合条件则分配内存并付值 int  ffsr , ffpr;ffsr = fsr + ssr;ffpr = fpr + spr;                                                 newnode = (struct SPQ*) malloc (sizeof(spq));if(newnode==NULL){printf("\n内存不够!\n");exit(0);}newnode -> upnode = ntx;       //保存父结点的地址以成链表newnode -> sr = ffsr;newnode -> pr = ffpr;newnode -> sl = ffsl;newnode -> pl = ffpl;newnode -> sst = sst;newnode -> spt = spt;newnode -> ssr = ssr;newnode -> spr = spr;newnode -> loop = ntx -> loop + 1;uend -> nextnode = newnode;uend = newnode;unopenednum++;                              }}}}}} return 0;
}
void addtoopened(struct SPQ *ntx)
{unopened = unopened -> nextnode;unopenednum--;if (openednum == 0 )oend = opened = ntx;oend -> nextnode = ntx;oend = ntx;openednum++;
}
void recorder()
{int i , loop;struct SPQ *newnode;struct SPQ *ntx;loop = oend -> loop;ntx = oend;resultnum = 0;for( i = 0 ; i <= loop ; i++ ){newnode = (struct SPQ*) malloc (sizeof(spq));if(newnode==NULL){printf("\n内存不够!\n");exit(0);}newnode -> sr = ntx -> sr;newnode -> pr = ntx -> pr;newnode -> sl = ntx -> sl;newnode -> pl = ntx -> pl;newnode -> sst = ntx -> sst;newnode -> spt = ntx -> spt;newnode -> ssr = ntx -> ssr;newnode -> spr = ntx -> spr;newnode -> nextnode = NULL;ntx = ntx -> upnode;              if(i == 0)result = newnode;newnode -> nextnode = result;result = newnode;resultnum++;}
}
void releasemem()
{int i;struct SPQ* nodefree;for ( i = 1 ; i < openednum ; i++ ){nodefree = opened;opened = opened -> nextnode;free(nodefree);}for ( i = 0 ; i < unopenednum ; i++ ){nodefree = unopened;unopened = unopened -> nextnode;free(nodefree);}
}
void showresult()
{int i;int fsr , fpr ; //在右岸上的人数int fsl , fpl ; //在左岸上的人数struct SPQ* nodefree;printf("%d个传教士",result -> pr);printf("%d个野人",result -> sr);printf("%d个传教士",result -> pl);printf("%d个野人",result -> sl);for ( i = 1 ; i < resultnum ; i++ ){nodefree = result;result = result -> nextnode;free(nodefree);printf("\n\n\t左岸人数 船上人数及方向 右岸人数\n");printf("第%d轮\n",i);fpl = result -> pl - result -> spt + result -> spr;fpr = result -> pr - result -> spr;fsl = result -> sl - result -> sst + result -> ssr;fsr = result -> sr - result -> ssr;printf("传教士%8d%8d\t<-\t%8d\n",fpl,result -> spt,fpr);printf("野  人%8d%8d\t<-\t%8d\n",fsl,result -> sst,fsr);printf("传教士%8d%8d\t->\t%8d\n",result -> pl,result -> spr,result -> pr - result -> spr);printf("野  人%8d%8d\t->\t%8d\n",result -> sl,result -> ssr,result -> sr - result -> ssr);}printf("\n全体传教士和野人全部到达对岸");free(result);
}
void goon()
{char choice;for(;;){printf("是否继续?(Y/N)\n");scanf ("%s" , &choice);choice=toupper(choice);if(choice=='Y')break;if(choice=='N')exit(0);}
}

运行

trust100@ubuntu:~/test/clanguage$ ./a.out
题目:设有n个传教士和m个野人来到河边,打算乘一只船从右岸到左岸去。
该船的负载能力为两人。在任何时候,如果野人人数超过传教士人数,野人
就会把传教士吃掉。他们怎样才能用这条船安全的把所有人都渡过河去?默认的n、m值皆为3是否修改?(Y/N)N
3个传教士3个野人0个传教士0个野人左岸人数 船上人数及方向 右岸人数
第1轮
传教士       0       1 <-          2
野  人       0       1    <-          2
传教士       0       1 ->          2
野  人       1       0    ->          2左岸人数 船上人数及方向 右岸人数
第2轮
传教士       0       1 <-          2
野  人       1       1    <-          1
传教士       0       1 ->          2
野  人       2       0    ->          1左岸人数 船上人数及方向 右岸人数
第3轮
传教士       0       2 <-          1
野  人       2       0    <-          1
传教士       2       0 ->          1
野  人       1       1    ->          1左岸人数 船上人数及方向 右岸人数
第4轮
传教士       2       1 <-          0
野  人       1       1    <-          1
传教士       2       1 ->          0
野  人       2       0    ->          1左岸人数 船上人数及方向 右岸人数
第5轮
传教士       2       1 <-          0
野  人       2       1    <-          0
传教士       3       0 ->          0
野  人       3       0    ->          0全体传教士和野人全部到达对岸是否继续?(Y/N)
Y
题目:设有n个传教士和m个野人来到河边,打算乘一只船从右岸到左岸去。
该船的负载能力为两人。在任何时候,如果野人人数超过传教士人数,野人
就会把传教士吃掉。他们怎样才能用这条船安全的把所有人都渡过河去?默认的n、m值皆为3是否修改?(Y/N)N
3个传教士3个野人0个传教士0个野人左岸人数 船上人数及方向 右岸人数
第1轮
传教士       0       1 <-          2
野  人       0       1    <-          2
传教士       0       1 ->          2
野  人       1       0    ->          2左岸人数 船上人数及方向 右岸人数
第2轮
传教士       0       1 <-          2
野  人       1       1    <-          1
传教士       0       1 ->          2
野  人       2       0    ->          1左岸人数 船上人数及方向 右岸人数
第3轮
传教士       0       2 <-          1
野  人       2       0    <-          1
传教士       2       0 ->          1
野  人       1       1    ->          1左岸人数 船上人数及方向 右岸人数
第4轮
传教士       2       1 <-          0
野  人       1       1    <-          1
传教士       2       1 ->          0
野  人       2       0    ->          1左岸人数 船上人数及方向 右岸人数
第5轮
传教士       2       1 <-          0
野  人       2       1    <-          0
传教士       3       0 ->          0
野  人       3       0    ->          0

实例100 简单专家系统

classify.c

#include <stdio.h>#include <stdlib.h>#include <string.h>struct SUBLINK{int index;struct SUBLINK *next;}sublink;struct NODE{char feature[20];int upnnum;struct SUBLINK *upnode;int fullfill;int type;int state;int sonnum;struct SUBLINK *sonnode;}node;#define MAXNUM 1000struct NODE *nodelink[MAXNUM];int nodenum;void initiate();void quarry();void modify();int extend(struct NODE *ntx);int showfault() ;void store();void main(){int flag;initiate();for(;;){printf("\n\t请选择操作:\n\n\t1、查询;\n\n\t2、添加新知识;\n\n\t3、退出程序.\n\n\t");scanf("%d",&flag);switch(flag){case 1:quarry();break;case 2:modify();break;case 3:store();default:printf("\n输入错误,请重新输入\n");}}}void initiate()//初始化{int i , j;char s[10];FILE *kf;struct NODE *newnode;struct SUBLINK *newlink , *oldlink;if((kf = fopen("knowledgestore.txt" , "r")) == NULL){printf("Cannot create/open file");exit(1);}fscanf(kf , "%5d" , &nodenum);for(i=0 ; i < nodenum ; i++){newnode = (struct NODE*)malloc (sizeof(node));if(newnode == NULL){printf("\n内存不够!\n");exit(0);}fscanf(kf , "%20s" , newnode->feature);fscanf(kf , "%5d" , &newnode->upnnum);for(j=0 ; j<newnode->upnnum ; j++){newlink = (struct SUBLINK*) malloc (sizeof(sublink));if(newlink == NULL){printf("\n内存不够!\n");exit(0);}fscanf(kf , "%5d" , &newlink->index);if(j == 0)newnode->upnode = oldlink = newlink;newlink->next = NULL;oldlink->next = newlink;oldlink = newlink;}newnode->fullfill = 0;newnode->state = 0;fscanf(kf , "%5d" , &newnode->type);fscanf(kf , "%5d" , &newnode->sonnum);for(j=0 ; j < newnode->sonnum ; j++){newlink = (struct SUBLINK*)malloc(sizeof(sublink));if(newlink == NULL){printf("\n内存不够!\n");exit(0);}fscanf(kf , "%5d" , &newlink->index);if(j == 0)newnode->sonnode = oldlink = newlink;newlink->next = NULL;oldlink->next = newlink;oldlink = newlink;}nodelink[i] = newnode;   }fscanf(kf , "%10s" , s);if(strcmp(s , "end") != 0){printf("\n程序初始化失败!");exit(0);}    }void quarry(){struct NODE *ntx;char feature[100];int i , flag;for(;;){flag = 0;printf("\n请输入动物的特征:");scanf("%s" , feature);for(i = 0 ; i < nodenum ; i++){ntx = nodelink[i];if(strstr(feature,ntx->feature) != NULL){ntx->state = 1;flag = extend(ntx);               }}      if(flag >= 1){for(i = 0 ; i < nodenum ; i++){nodelink[i]->fullfill = 0;nodelink[i]->state = 0;                }break;}if(flag == 0)if(showfault() == 0)break;}}int extend(struct NODE *ntx){int i , index;int flag;struct NODE *nextone;struct SUBLINK *son;if(ntx->sonnum == 0){printf("\n结果为%20s\n" , ntx->feature);return 1;}son = ntx->sonnode;flag = 0;for(i = 0 ; i < (ntx->sonnum) ; i++){index = son->index;nextone = nodelink[index];if(nextone->type == 0)//或节点{if(nextone->state != 1){nextone->state = 1;printf("\n表明具有%20s特征" , nextone->feature);flag += extend(nextone);}}else{nextone->fullfill++;if(nextone->fullfill == nextone->upnnum){nextone->state = 1;printf("\n表明具有%20s特征" , nextone->feature);flag =+ extend(nextone);}}son = son->next;}return flag;}void modify(){int i ;char choice , feature[100];struct NODE *ntx , *newnode;struct SUBLINK *endl , *newl;newnode = (struct NODE*)malloc(sizeof(node));if(newnode == NULL){printf("\n内存不够!\n");exit(0);}newnode->sonnum = 0;newnode->upnnum = 0;newnode->fullfill = 0;printf("\n请输入新特征\n");scanf("%s",newnode->feature);printf("新特征类型:\n与节点(1),或节点(0)");scanf("%d" , &newnode->type);newnode->state = 0;newnode->fullfill = 0;for(;;){printf("\n是否为叶节点?(Y/N)\n");scanf("%s" , &choice);choice = toupper(choice);if(choice == 'N'){printf("\n请输入新特征描述的对象\n");scanf("%s" , feature);for(i = 0 ; i < nodenum ; i++){ntx = nodelink[i];if(strstr(feature,ntx->feature) != NULL){newl = (struct SUBLINK*) malloc (sizeof(sublink));if(newl == NULL){printf("\n内存不够!\n");exit(0);}if(newnode->sonnum == 0)newnode->sonnode = endl = newl;newl->index = i;endl->next = newl;endl = newl;newl->next = NULL;newnode->sonnum++;/将信息写入子节点newl = (struct SUBLINK*) malloc (sizeof(sublink));if(newl == NULL){printf("\n内存不够!\n");exit(0);}if(ntx->upnnum == 0)ntx->upnode = endl = newl;newl->index = nodenum;newl->next = ntx->upnode;ntx->upnode = newl;ntx->upnnum++;}}break;}if(choice == 'Y')break;}for(;;){printf("\n是否为顶点?(Y/N)\n");scanf("%s" , &choice);choice = toupper(choice);if(choice == 'N'){        printf("\n请输入对新对象的描述\n");scanf("%s" , feature);for(i = 0 ; i < nodenum ; i++){ntx = nodelink[i];if(strstr(feature , ntx->feature)!=NULL){            newl = (struct SUBLINK*) malloc (sizeof(sublink));if(newl == NULL){printf("\n内存不够!\n");exit(0);}if(newnode->upnnum == 0)newnode->upnode = endl = newl;newl->index = i;endl->next = newl;endl = newl;newl->next = NULL;newnode->upnnum++;///将信息写入父节点newl = (struct SUBLINK*) malloc (sizeof(sublink));if(newl == NULL){printf("\n内存不够!\n");exit(0);}if(ntx->sonnum == 0)ntx->sonnode = endl = newl;newl->index = nodenum;newl->next = ntx->sonnode;ntx->sonnode = newl;ntx->sonnum++;}}break;}if(choice == 'Y')break;} nodelink[nodenum] = newnode;nodenum++;}void store(){int i , j;   char s[10];FILE *kf;struct NODE *writenode;struct SUBLINK *newlink , *oldlink;if((kf = fopen("knowledgestore.txt" , "w")) == NULL){printf("Cannot create/open file");exit(1);}fprintf(kf , "%5d" , nodenum);for(i = 0 ; i < nodenum ; i++){writenode = nodelink[i];fprintf(kf , "%20s" , writenode->feature);fprintf(kf , "%5d" , writenode->upnnum);newlink = writenode->upnode;for(j = 0 ; j < writenode->upnnum ; j++){fprintf(kf , "%5d" , newlink->index);oldlink = newlink;newlink = newlink->next;free(oldlink);}fprintf(kf , "%5d" , writenode->type);fprintf(kf , "%5d" , writenode->sonnum);newlink = writenode->sonnode;for(j = 0 ; j < writenode->sonnum ; j++){fprintf(kf , "%5d" , newlink->index);oldlink = newlink;newlink = newlink->next;free(oldlink);}free(writenode);}strcpy(s , "end");fprintf(kf , "%10s" , s);fclose(kf);exit(0);}int showfault(){char choice;for(;;){printf("是否继续?(Y/N)\n");scanf("%s" , &choice);while(choice == '10');choice = toupper(choice);if(choice == 'Y')return 1;if(choice == 'N')exit(0);}  }

【C】【吐血整理】你们要的C语言实例大全-综合应用篇相关推荐

  1. 单片机c语言参考文献最新,[2018年最新整理]10个单片机C语言实例.doc

    [2018年最新整理]10个单片机C语言实例 经典单片机实验帮你成功 1. 闪烁灯 1. 实验任务 如图4.1.1 所示:在P1.0 端口上接一个发光二极管L1,使L1 在不停地一亮一 灭,一亮一灭的 ...

  2. c 语言实例大全,c语言实例大全

    c语言实例 /* Note:Your choice is C IDE */1 输出字母C的图案 #include "stdio.h" #include "conio.h& ...

  3. r语言各形状编号_190+张图片!吐血整理!搞定R语言基础绘图全部知识点

    转自:生信宝典|Bio_Data,不一样的生信学习平台 原文链接:ggplot2高效实用指南 (可视化脚本.工具.套路.配色) 作者:严涛 浙江大学作物遗传育种在读研究生(生物信息学方向)伪码农,R语 ...

  4. 吐血整理————当代程序员必备的神器大全

    目录 程序员生产力工具大全 在我认识的所有程序员里,几乎每个人都有专属于自己的常用工具和相关资源. 所以,今天就给大家奉上数十款程序员硬核工具,另外还有一些在线开发辅助工具.在线画图工具.在线转换工具 ...

  5. 【吐血整理】年度盘点 | 2019年Java面试题汇总篇——附答案

    在这岁月更替辞旧迎新的时刻,老王盘点了一下自己 2019 年发布的所有文章,意外的发现关于「Java面试」的主题文章,竟然发布了 52 篇,几乎是全年每周一篇面试文章的节奏,当然其中有不少的面试题来源 ...

  6. c语言基础编程题山东科技大学,C语言练习题〔山东科技大学吐血整理〕.doc

    C语言练习题[山东科技大学吐血整理] 数学11-1 C语言平时训练题 1.算术基本运算 Description 计算两整数x和y(0 Input 输入只有一行. Output 输出为多行,按顺序每行输 ...

  7. [转]《吐血整理》系列-顶级程序员工具集

    你知道的越多,你不知道的越多 点赞再看,养成习惯 GitHub上已经开源 https://github.com/JavaFamily 有一线大厂面试点脑图.个人联系方式,欢迎Star和指教 前言 这期 ...

  8. 吐血整理!顶级程序员的百宝箱来咯!| 原力计划

    作者 | 敖丶丙 责编 | Elle 出品 | CSDN 博客 你知道的越多,你不知道的越多 因为读者很多还是学生,还有很多应届生,对一个需求的研发流程都不是很熟悉,还有可能对于以后自己需要使用到的工 ...

  9. 【计算机视觉算法岗面经】“吐血”整理:2019秋招资料

    相关链接:[计算机视觉算法岗面经]"吐血"整理:2019秋招面经 //2018/09/27 兵荒马乱.浩浩荡荡的秋招终于差不多要结束了. 秋招这段时间真是感慨很多,一时得意一时失意 ...

  10. python基础教程第三版豆瓣-数据结构与算法必读书单吐血整理推荐【附网盘链接】...

    前言:技术书阅读方法论 一.速读一遍(最好在1~2天内完成) 人的大脑记忆力有限,在一天内快速看完一本书会在大脑里留下深刻印象,对于之后复习以及总结都会有特别好的作用. 对于每一章的知识,先阅读标题, ...

最新文章

  1. java struts2标签库 常用标签
  2. qt定时器是阻塞的吗_吊打面试官 | 面试官:TCP真的可靠吗
  3. python线程卡死问题解决_python while True造成未响应或卡顿的解决方法
  4. 提交mysql代码_MySQL源码之两阶段提交
  5. centos 使用 beyond compare 对比工具
  6. network中的请求信息,headers中的每一项分别是什么意义?
  7. golang学习之旅(1)
  8. java变量,初始化快,构造函数的执行顺序
  9. 学习共享--产品思维
  10. Caused by: java.sql.SQLException: Unable to open a test connection to the given database报错无法打开到给定数据库
  11. jQuery Hello世界
  12. 【To Do】LeetCode 28. Implement strStr() 和KMP算法
  13. VS2003编译winSDK7.1中的DirectShow
  14. SolidWorks2021导出带材质的OBJ文件
  15. AAAI2021联邦学习论文集
  16. Android百大框架排行榜
  17. HTML5页面元素figure与figcaption标记的应用
  18. 孙鑫《VC++深入详解》完整版PDF 下载
  19. c++空指针的定义-0L
  20. eclipse mac下常用快捷键

热门文章

  1. Linux 下的 QQ 使用方案
  2. 计算机系统后门程序,一种远程控制的后门程序在互联网出现
  3. 【感恩节的小礼物】yagmail给家人朋友来一份含有温情的关心和推送吧~Python3自动发送暖心内容邮件。
  4. acceleration transducer
  5. Ubuntu的下载安装教程--本人亲测
  6. 视频: 老罗演讲问答集锦
  7. ArcMap制作TPK文件
  8. 武钢四中2021高考成绩查询,武汉市钢城四中怎么样 钢城四中介绍
  9. python与excel教程_Python对Excel操作教程
  10. 单例模式(Singleton)分析