using System;
using System.Windows.Forms;
using KarstIModel;
namespace KarstModel
{
/// <summary>
/// FfuzzyIdentify 模糊模型识别。
/// </summary>
public class FuzzyIdentify1:KarstIModel.IModel
{
//以下定义需要输入的变量
private double[,] standSource ;//样本数据+标志列(原始数据)
private double[,] identitySource ;//待识别数据(原始数据)
private CheckedListBox.CheckedIndexCollection preTreatment;//数据预处理,多选
项:标准差变换和极差变换
private long mothodID; //求贴近度方法代号,0:格贴近度,1:海明贴近度,2:欧氏
贴近度,3:最大最小贴近度,4:算术平均最小贴近度
//以下定义程序自己要用的数据
private double[,] stylebook;//样本数据(已做预处理)
private double[,] identity;//待识别数据(已做预处理)
private double[,] standard;//标准模型数据(按类别标志对样本数据求平均得)
private Collection1D standardList=new Collection1D();//标准模型的类别标志集合(
元素是int型);
private int intRow;//样本数据+待识别数据的总行数
private int intCol;//样本数据和待识别数据的总列数
private int intS;//标准模型的个数
private double[,] dts;//贴近度数组intRow2*intS
private int intRow1;//已知样本个数
private int intRow2;//待定样本个数
private int[] GoeID; //地理元素编号
private int[] sign;
private double[] xc;
private double[] sc;
private bool hasPara=false;
public FuzzyIdentify1()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
#region IModel 成员
public void run()
{
if(!hasPara) return;
sign=new int[intRow2];
xc=new double[intCol-1];
sc=new double[intCol-1];
double dt=0;
for(int i=0;i<intRow2;i++)
{
for(int j=0;j<intS;j++)
{
for(int k=0;k<intCol-1;k++)
{
xc[k]=identity[i,k];
sc[k]=standard[j,k];
}
switch(mothodID)
{
case (long)0:dt=MM1(xc,sc);break;
case (long)1:dt=MM2(xc,sc);break;
case (long)2:dt=MM3(xc,sc);break;
case (long)3:dt=MM4(xc,sc);break;
case (long)4:dt=MM5(xc,sc);break;
}
dts[i,j]=(int)((dt+0.0005)*1000)/1000.0;
}
double dl=0;
for(int j=0;j<intS;j++)
{
if(dts[i,j]>dl)
{ dl=dts[i,j];
sign[i]=(int)standardList[j];
}
}
}
}
public bool setParameters(System.Collections.Hashtable para)
{
try
{
GoeID=(int [])para["GoeID"];
standSource=(double [,])para["standSource"];
identitySource=(double [,])para["identitySource"];
preTreatment=(CheckedListBox.CheckedIndexCollection)para
["preTreatment"];
mothodID=(long)para["mothodID"];
intRow1=standSource.GetUpperBound(0)+1;//已知样本个数
intRow2=identitySource.GetUpperBound(0)+1;//待定样本个数
intRow=intRow1+intRow2;//已知样本个数+待定样本个数
if(standSource.GetUpperBound(1)==identitySource.GetUpperBound
(1))
intCol=standSource.GetUpperBound(1)+1;
else
{
System.Windows.Forms.MessageBox.Show("标准模型数据和待
识别模型数据的列数不一致!");
return false;
}
//建立标准模型的类别标志集合
for(int i=0;i<intRow1;i++)
{
if (standardList.IndexOf((int)standSource[i,intCol-
1])<0)
standardList.Add((int)standSource[i,intCol-
1]);
}
intS=standardList.Count;//标准模型个数
dts=new double[intRow2,intS];
SetStylebookAndIdentity();//设置样本数据和待识别数据
SetStandard();//设置标准模型数据
hasPara=true;
return true;
}
catch
{
return false;
}
}
public System.Collections.Hashtable GetParameters()
{
// TODO: 添加 FuzzyIdentify.GetParameters 实现
return null;
}
public System.Collections.Hashtable GetResult()
{
// TODO: 添加 FuzzyIdentify.GetResult 实现
return null;
}
public System.Data.DataTable GetResultAsTable()
{return null;}
public string GetResultAsString()
{
string result="----贴近度----\n";
result=result+"共有"+intS+"标准模型\n";
for(int i=0;i<intS;i++)
{
for(int j=0;j<intCol-1;j++)
result=result+standard[i,j]+" ";
result=result+"\n";
}
result=result+"共有"+intRow2+"待定模型\n";
for(int i=0;i<intRow2;i++)
{
for(int j=0;j<intCol-1;j++)
result=result+identity[i,j]+" ";
result=result+"\n";
}
for(int i=0;i<intS;i++)
result=result+"标准"+Convert.ToString(i+1)+" ";
result=result+"最大编号\n";
for(int i=0;i<intRow2;i++)
{
for(int j=0;j<intS;j++)
result=result+Convert.ToString(dts[i,j])+" ";
result=result+Convert.ToString(sign[i])+"\n";
}
return result;
}
public string GetKeywords()
{
// TODO: 添加 FuzzyIdentify.GetKeywords 实现
return null;
}
public string GetDiscription()
{
// TODO: 添加 FuzzyIdentify.GetDiscription 实现
return null;
}
public string GetSubjects()
{
// TODO: 添加 FuzzyIdentify.GetSubjects 实现
return null;
}
public IModel[] GetChildren()
{
// TODO: 添加 FuzzyIdentify.GetChildren 实现
return null;
}
public ParaData[] GetParaData()
{
ParaData[] ans=new ParaData[4];
ans[0]=new ParaData(-1,"standSource","标准数据样本+标志列(原始数
据)",2,"double","标准数据+标志列(原始数据)","");
ans[1]=new ParaData(-1,"identitySource","待识别数据(原始数
据)",2,"double","待识别数据(原始数据)","");
ans[2]=new ParaData(-1,"preTreatment","数据预处理(多选项)",4,"int","
数据预处理(多选项)","标准差变换,极差变换");
ans[3]=new ParaData(-1,"mothodID","求贴近度方法",3,"int","求贴近度方法
","格贴近度,海明贴近度,欧氏贴近度,最大最小贴近度,算术平均最小贴近度");
return ans;
}
public ModelData GetModelData()
{
ModelData ans=new ModelData();
ans.name="FuzzyIdentify1";
ans.realName="模糊模型识别(常规)";
ans.useMethod="按向导输入参数后运行即可";
ans.uses="模糊模型识别(常规)";
ans.filename="model.dll";
ans.description="模糊模型识别(常规)";
ans.keyWords="模糊模型识别(常规)";
ans.classes=3;
return ans;
}
#endregion
//设置样本数据和待识别数据
private void SetStylebookAndIdentity()
{
double[,] xx=new double[intRow,intCol-1];//全部原始数据,标准数据+待识
别数据,以做标准化
stylebook=new double[intRow1,intCol-1];//样本数据
identity=new double[intRow2,intCol-1];//待识别数据
for(int i=0;i<intRow1;i++)
for(int j=0;j<intCol-1;j++)
xx[i,j]=standSource[i,j];
for(int i=0;i<intRow2;i++)
for(int j=0;j<intCol-1;j++)
xx[intRow1+i,j]=identitySource[i,j];
if(preTreatment.Count>0)
{
if(preTreatment.Contains(0)) Standardization(xx);
if(preTreatment.Contains(1)) Difference(xx);
}
for(int i=0;i<intRow1;i++)
for(int j=0;j<intCol-1;j++)
stylebook[i,j]=xx[i,j];
for(int i=0;i<intRow2;i++)
for(int j=0;j<intCol-1;j++)
identity[i,j]=xx[intRow1+i,j];
}
//设置标准模型数据
private void SetStandard()
{
standard=new double[intS,intCol-1];
for(int i=0;i<intS;i++)
{
int aRow=0;
for(int j=0;j<intRow1;j++)
{
if((int)standSource[j,intCol-1]==(int)standardList[i])
{
aRow=aRow+1;
for(int k=0;k<intCol-1;k++)
standard[i,k]=standard[i,k]+stylebook
[j,k];
}
}
for(int k=0;k<intCol-1;k++)
standard[i,k]=standard[i,k]/aRow;
}
}
/// <summary>
/// 数据的标准差变换
/// x:原始数据,执行后保存变换后的数据
/// </summary>
private void Standardization(double[,] x)
{
int M,N,i,j;
double ave,s;
N=x.GetUpperBound(0)+1;//x的行数,
M=x.GetUpperBound(1)+1;//x的列数
for(j=0;j<M;j++)
{
ave=0;
for(i=0;i<N;i++)
ave=ave+x[i,j];
ave=ave/N;
s=0;
for(i=0;i<N;i++)
s=s+(x[i,j]-ave)*(x[i,j]-ave);
s=Math.Sqrt(s/N);
if(s==0) s=1;
for(i=0;i<N;i++)
x[i,j]=(x[i,j]-ave)/s;
}
}
/// <summary>
/// 数据的极差变换
/// x:原始数据,执行后保存变换后的数据
/// </summary>
/// <param name="x"></param>
private void Difference( double[,] x)
{
int M,N,i,j;
double xMax,xMin,d;
N=x.GetUpperBound(0)+1;//x的行数,
M=x.GetUpperBound(1)+1;//x的列数
for(j=0;j<M;j++)
{
xMax = -100000000;
xMin = 100000000;
for(i=0;i<N;i++)
{
if (x[i,j] > xMax)
xMax = x[i,j];
if (x[i,j] < xMin)
xMin = x[i,j];
}
d = xMax - xMin; //D是极差
if(d==0) d=1;
for(i=0;i<N;i++)
x[i,j] = (x[i,j] - xMin) / d;// '极差标准化变换
}
}
/// <summary>
/// 格贴近度,返回值为a与b的格贴近度
/// a:待定样本,M为元素或指标数;
/// b:标准模型,M为元素或指标数
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
private double MM1(double[] a,double[] b)
{
int M,i;
double dm1,dm2,dc1,dc2,c;
M=a.GetUpperBound(0)+1;
dm1=0;
dm2=0;
for(i=0;i<M;i++)
{
if(a[i]<b[i]) dc1=a[i]; else dc1=b[i];
if(a[i]>b[i]) dc2=a[i]; else dc2=b[i];
if(dc1>dm1)dm1=dc1;
if(dc2<dm2)dm2=dc2;
}
c=(dm1+(1-dm2))/2;
return c;
}
/// <summary>
/// 海明贴近度,返回值为a与b的格贴近度
/// a:待定样本,M为元素或指标数;
/// b:标准模型,M为元素或指标数
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
private double MM2(double[] a,double[] b)
{
int M,i;
double d,c;
M=a.GetUpperBound(0)+1;
d=0;
for(i=0;i<M;i++)
{
d=d+Math.Abs(a[i]-b[i]);
}
c=1-d/M;
return c;
}
/// <summary>
/// 欧氏贴近度,返回值为a与b的格贴近度
/// a:待定样本,M为元素或指标数;
/// b:标准模型,M为元素或指标数
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
private double MM3(double[] a,double[] b)
{
int M,i;
double d,c;
M=a.GetUpperBound(0)+1;
d=0;
for(i=0;i<M;i++)
{
d=d+(a[i]-b[i])*(a[i]-b[i]);
}
c=1-Math.Sqrt(d/M);
return c;
}
/// <summary>
/// 最大最小贴近度,返回值为a与b的格贴近度
/// a:待定样本,M为元素或指标数;
/// b:标准模型,M为元素或指标数
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
private double MM4(double[] a,double[] b)
{
int M,i;
double dMin=0,dMax=0,dc1,dc2,c;
M=a.GetUpperBound(0)+1;
for(i=0;i<M;i++)
{
if(a[i]<b[i]) dc1=a[i]; else dc1=b[i];
if(a[i]>b[i]) dc2=a[i]; else dc2=b[i];
dMin=dMin+dc1;
dMax=dMax+dc2;
}
c=dMin/dMax;
return c;
}
/// <summary>
/// 算术平均最小贴近度,返回值为a与b的格贴近度
/// a:待定样本,M为元素或指标数;
/// b:标准模型,M为元素或指标数
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
private double MM5(double[] a,double[] b)
{
int M,i;
double dMin=0,dc1,dc2,dc=0,c;
M=a.GetUpperBound(0)+1;
for(i=0;i<M;i++)
{
if(a[i]<b[i]) dc1=a[i]; else dc1=b[i];
dMin=dMin+dc1;
dc2=a[i]+b[i];
dc=dc+dc2;
}
c=2*dMin/dc;
return c;
}
}
}
浙公网安备 33010602011771号