蚁群算法源代码.docx
《蚁群算法源代码.docx》由会员分享,可在线阅读,更多相关《蚁群算法源代码.docx(19页珍藏版)》请在冰豆网上搜索。
蚁群算法源代码
基本思想:
基于LF算法的改进,将蚂蚁的拾起和放下策略用蚂蚁周围数据的信息熵的改变来判断,基于的事实为“包含聚类的子空间的信息熵比不包含聚类的信息熵小”。
form1.cs文件:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Text;
usingSystem.Windows.Forms;
usingSystem.Data.OleDb;
usingSystem.Diagnostics;
namespaceAntClust
{
publicpartialclassForm1:
Form
{
publicForm1()
{
InitializeComponent();
}
inttMax=30000;//最外层迭代次数
intantC=50;//蚂蚁数
intgridN=30;//网格维数,gridN*gridN
intatrCount=4;//数据对象属性个数
ListnodeAll=newList();//所有节点集合
ListantAll=newList();//所有蚂蚁集合
ListdataObjAll=newList();//所有数据对象集合
privatevoidForm1_Load(objectsender,EventArgse)
{
}
privatevoidbutton1_Click(objectsender,EventArgse)
{
//从数据库读取数据
StringconnectionString="Provider=Microsoft.Jet.OLEDB.4.0;DataSource=data.mdb";
OleDbConnectionconnection=newOleDbConnection(connectionString);
OleDbDataAdapterad=newOleDbDataAdapter("select*fromIris",connection);
DataSetds=newDataSet();
ad.Fill(ds);
//生成节点
for(inti=0;i{
for(intj=0;j{
nodeAll.Add(newNode(i,j));
}
}
//生成蚂蚁
for(inti=0;i{
antAll.Add(newAnt());
}
//生成数据对象
atrCount=ds.Tables[0].Columns.Count-1;
for(inti=0;i{
Single[]datatemp=newSingle[atrCount];
for(intj=0;j{
datatemp[j]=Convert.ToSingle(ds.Tables[0].Rows[i][j1].ToString());
}
dataObjAll.Add(newdataObj(ds.Tables[0].Rows[i]["ID"].ToString(),datatemp));
}
//初始化数据对象和蚂蚁的位置
initPosition();
//主体迭代
Cacu();
//输出结果
for(inti=0;i{
Debug.Write(dataObjAll[i].myID.ToString()",");
Debug.Write(dataObjAll[i].NodePosition.Px.ToString()",");
Debug.Write(dataObjAll[i].NodePosition.Py.ToString()",");
Debug.WriteLine("");
}
MessageBox.Show("请查看结果!
");
}
privatevoidinitPosition()
{
//初始化数据对象的位置
Randomrd=newRandom();
for(inti=0;i{
inttempP=(int)(rd.NextDouble()*nodeAll.Count);
dataObjAll[i].NodePosition=nodeAll[tempP];
nodeAll[tempP].datalst.Add(dataObjAll[i]);
}
//初始化蚂蚁的位置
rd=newRandom();
for(inti=0;i{
inttempP=(int)(rd.NextDouble()*nodeAll.Count);
antAll[i].NodePosition=nodeAll[tempP];
antAll[i].isFull=false;
antAll[i].nowData=null;
}
for(inti=0;i{
Debug.Write(dataObjAll[i].myID.ToString()",");
Debug.Write(dataObjAll[i].NodePosition.Px.ToString()",");
Debug.Write(dataObjAll[i].NodePosition.Py.ToString()",");
Debug.WriteLine("");
}
Debug.WriteLine("===================================================================================");
}
//主体计算过程
inttp=0;
doubleE1;
doubleE2;
privatevoidCacu()
{
ListnodeT=newList();
ListnodeN=newList();
ListdataN=newList();
for(intt=0;t{
for(inti=0;i{
//计算蚂蚁周围节点数据对象总数
nodeT=antAll[i].NodePosition.getNearByNodes1(gridN);//蚂蚁周围节点列表
nodeN.Clear();
nodeN.Add(antAll[i].NodePosition);//记录当前区域所有节点
inttempIndex=0;
for(intk=0;k{
tempIndex=getNodeId(nodeT[k].Px,nodeT[k].Py);
nodeN.Add(nodeAll[tempIndex]);
}
intsum=0;
dataN.Clear();
for(intk=0;k{
for(intj=0;j{
sum;
}
}
intdataNum=0;
dataNum=antAll[i].NodePosition.hasData()sum;
//判断蚂蚁是否负载
if(antAll[i].isFull==false)//蚂蚁空载的情况
{
//判断蚂蚁所在节点数据对象是否为空
if(antAll[i].NodePosition.hasData()>0)//蚂蚁所在节点数据对象数目m>0
{
//判断蚂蚁所在节点数据对象数目m与蚂蚁周围节点数据对象数目n之和
if((antAll[i].NodePosition.hasData()==1)&&(sum==0))//m=1&&n=0
{
//蚂蚁捡起所在节点数据
antAll[i].isFull=true;
antAll[i].nowData=antAll[i].NodePosition.datalst[0];//*
antAll[i].NodePosition.datalst.RemoveAt(0);
//Debug.WriteLine("m=1&&n=0,捡起");
}
//elseif(((antAll[i].NodePosition.hasData()==1)&&(sum==1))||((antAll[i].NodePosition.hasData()==2)&&(sum==0)))//m=1&&n=1或者m=2&&n=0
//{
////蚂蚁不捡起所在节点数据
////Debug.WriteLine("m=1&&n=1或者m=2&&n=0,不捡起");
//}
elseif(dataNum>=3)//mn>=3
{
//计算信息熵,判断是否捡起
//tempE=getE(antAll[i].NodePosition,1,null);
tp=getSelNode(antAll[i].NodePosition);
if(tp!
=-1)
{
antAll[i].isFull=true;
antAll[i].nowData=antAll[i].NodePosition.datalst[tp];//*
antAll[i].NodePosition.datalst.RemoveAt(tp);
//Debug.WriteLine("存在可以捡起的数据(捡起后信息熵减小),捡起");
}
//else
//{
////Debug.WriteLine("不存在可以捡起的数据,不捡起");
//}
}
}
//elseif(antAll[i].NodePosition.hasData()==0)//蚂蚁所在节点数据对象数目m=0
//{
////Debug.WriteLine("m=0,节点无数据对象,不处理");
//}
}
elseif(antAll[i].isFull==true)//蚂蚁负载的情况
{
//判断蚂蚁所在节点数据对象数目m与蚂蚁周围节点数据对象数目n之和
//if(dataNum==0)//mn=0
//{
////蚂蚁不放下携带的数据
////Debug.WriteLine("mn=0,不放下数据");
//}
if(dataNum==1)//mn=1
{
//蚂蚁放下携带的数据
antAll[i].isFull=false;
//antAll[i].nowData=null;
antAll[i].NodePosition.datalst.Add(antAll[i].nowData);
//更新数据对象位置
dataObjAll[getid(antAll[i].nowData.myID)].NodePosition=antAll[i].NodePosition;
//Debug.WriteLine("mn=1,放下数据");
}
elseif(dataNum>=2)//mn>=2
{
//计算信息熵,判断是否放下
E1=getE(antAll[i].NodePosition,1,antAll[i].nowData);
E2=getE(antAll[i].NodePosition,2,antAll[i].nowData);
if(E1{
//MessageBox.Show("down");
antAll[i].isFull=false;
//antAll[i].nowData=null;
antAll[i].NodePosition.datalst.Add(antAll[i].nowData);
//更新数据对象位置
dataObjAll[getid(antAll[i].nowData.myID)].NodePosition=antAll[i].NodePosition;
//Debug.WriteLine("蚂蚁放下数据后信息熵减小,放下数据");
}
//else
//{
////Debug.WriteLine("蚂蚁放下数据后信息熵增大,不放下数据");
//}
}
}
//移动蚂蚁
Randomrd=newRandom();
inttempP=(int)(rd.NextDouble()*nodeAll.Count);
antAll[i].NodePosition=nodeAll[tempP];
}
}
}
privateintgetid(stringidin)
{
for(inti=0;i{
if(dataObjAll[i].myID==idin)
returni;
}
returnConvert.ToInt32(idin);
}
privateintgetIdInDataAllFromIDtemp(stringid)
{
for(inti=0;i{
if(dataObjAll[i].myID==id)
returni;
}
returnConvert.ToInt32(id);
}
///
///蚂蚁在当前节点所拿起的数据对象
///
///
///
privateintgetSelNode(NodenodeIn)
{
doubleE1;
doubleE2;
E1=getE(nodeIn,1,null);//蚂蚁捡起数据前的信息熵值
for(inti=0;i{
E2=getE(nodeIn,3,nodeIn.datalst[i]);//蚂蚁捡起数据后该区域信息熵值
if(E1returni;
}
return-1;
}
///
///计算当前节点对应区域的熵值(比如一个3*3区域的9个节点对应的熵值)
///
///当前蚂蚁所处节点
///求取熵的类型,1表示原始区域的熵;2表示添加一个数据对象后计算的熵值;3表示删除某一个数据对象后计算的熵值
///type=1时,dataInOrOut=null;type=2或type=3时,dataInOrOut为一个数据对象
///
doublegetE(NodenodeIn,inttype,dataObjdataInOrOut)
{
ListnodeT=nodeIn.getNearByNodes1(gridN);//存储附近节点
ListnodeN=newList();
nodeN.Clear();
nodeN.Add(nodeIn);//记录当前区域所有节点
inttempIndex=0;
for(intk=0;k{
tempIndex=getNodeId(nodeT[k].Px,nodeT[k].Py);
nodeN.Add(nodeAll[tempIndex]);
}
ListdataN=newList();
for(intk=0;k{
if(type==3)//将某一个数据对象排除
{
for(intj=0;j{
if(nodeN[k].datalst[j].myID!
=dataInOrOut.myID)
dataN.Add(nodeN[k].datalst[j]);//将当前影响到的所有数据对象放在一起
}
}
if(type==1)//计算原有的所有数据对象的熵
{
for(intj=0;j{
dataN.Add(nodeN[k].datalst[j]);//将当前影响到的所有数据对象放在一起
}
}
}
if(type==2)//添加一个数据对象
{
dataN.Add(dataInOrOut);
}
//计算熵值
introwC=dataN.Count;
doublesumC=0;//最终熵值
//对一个m*n的二维矩阵(dataN)进行运算,对各个元素频率之和求和。
for(intk=0;k{
Single[]dataCol=newSingle[rowC];
for(intj=0;j{
dataCol[j]=dataN[j].atrLst[k];//二维矩阵(dataN)的i列
}
sumC=getSm(dataCol);
}
returnsumC;
}
///
///计算一个一维矩阵的各元素频率和
///
///
///
privatedoublegetSm(Single[]data)
{
intcrow=data.Length;
Listdatadis=newList();
dataMdt=newdataM();
dt.dataN=data[0];
dt.num=1;
datadis.Add(dt);
for(inti=1;i{
intind=hasB(data[i],datadis);
if(ind!
=-1)
{
datadis[ind].num=1;
}
else
{
dataMdb=newdataM();
db.dataN=data[i];
db.num=1;
datadis.Add(db);
}
}
doublesm=0;
doubletp=0;
for(inti=0;i{
tp=(double)datadis[i].num/crow;
tp=tp*Math.Log(tp);
sm=tp;
}
returnsm;
}
//查询在datadis中是否有data
privateinthasB(Singledata,Listdatadis)
{
for(intj=0;j{
if(data==datadis[j].dataN)
{
returnj;
}
}
return-1;
}
///
///根据位置计算节点在NodeAll中的ID
///
///
privateintgetNodeId(intx,inty)
{
inta=x*gridNy;
return(a);
}
}
classdataM
{
publicSingledataN;
publicintnum;
}
}
Ant.cs文件:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceAntClust
{
///
///蚂蚁类
///
classAnt
{
publicNodeNodePosition;//蚂蚁位置
publicboolisFull=false;//蚂蚁负载状态,默认没有负载
publicdataObjnowData;//当前蚂蚁负载的数据对象
}
}
Node.cs文件:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespace