您的位置:首页 > 编程语言 > Go语言

ant colony algorithm && decision tree

2015-09-27 20:28 549 查看
// AntColony.cpp : 定义控制台应用程序的入口点。
//

//#include "stdafx.h"
#include<iostream>
#include<math.h>
#include<time.h>

#include <fstream>
#include <string>
#include <iostream>
#include <vector>

using namespace std;

//打印系列
//GD-E-B-AC-HF-FG-EGJ-DI-CIJ
#define N 788
//孔坐标

double HoleA[660][2]= {(0,0)};
double HoleB[788][2]= {(0,0)};
double HoleC[270][2]= {(0,0)};
double HoleD[212][2]= {(0,0)};
double HoleE[95][2]= {(0,0)};
double HoleF[34][2]= {(0,0)};
double HoleG[20][2]= {(0,0)};
double HoleH[6][2]= {(0,0)};
double HoleI[10][2]= {(0,0)};
double HoleJ[29][2]= {(0,0)};

double HoleGD[232][2] = {(0,0)};

//double C
[2] = {0 };

struct Point
{
int x;
int y;
};

FILE *fp;
char buf[256];
char *p;
char X[10]={'\0'};
char Y[10]={'\0'};
int CoorX;
int CoorY;

char HolePattern = '0';

//函数名称:合并二维数组
//参数1,2。要合并的两个二维数组,参数3,合并数组1的长度。参数4,合并数组2的长度。
//返回:二维数组的首地址。
/********************************************************************************************************/
void combineArray(double arr_one[][2], double arr_two[][2], int combinelength_one, int combinelength_two, double arr_new[][2])
{

//申请空间
//double ** combine_array = new double *[combinelength_one + combinelength_two];
// (int i = 0; i < (combinelength_one + combinelength_two); i++)
//{
//    combine_array[i] = new double[2];
//}

//使用空间
for (int j = 0; j < combinelength_one + combinelength_two; j++)
{
for (int k = 0; k < 2; k++)
{
if (j < combinelength_one)
{
arr_new[j][k] = arr_one[j][k];
}
else
{
arr_new[j][k] = arr_two[j - combinelength_one][k];
}

}
}
//    return combine_array;
}

void printCombineArray(double **Hole)
{
for (int i = 0; i < 10; i++)
{
for (int k = 0; k < 2; k++)
{
cout << i << "-" << k << " = " << Hole[i][k] << "     ";
}
cout << endl;
}
}

int DataInit()
{
if (NULL == (fp = fopen("1.txt", "r")))
{
fprintf(stderr, "Can not open file : 1.txt\n");
return 1;
}

int j =0;
while (1)
{
if (NULL == fgets(buf, 256, fp)) break;

p = buf;
if (NULL  != (p = strstr(p, "A")))
{
printf(p);
HolePattern = 'A';
j =0;
continue;
}

p =buf;
if (NULL  != (p = strstr(p, "B")))
{
printf(p);
HolePattern = 'B';
j =0;
continue;
}

p =buf;
if (NULL  != (p = strstr(p, "C")))
{
printf(p);
HolePattern = 'C';
j =0;
continue;
}

p =buf;
if (NULL  != (p = strstr(p, "D")))
{
printf(p);
HolePattern = 'D';
j =0;
continue;
}

p =buf;
if (NULL  != (p = strstr(p, "E")))
{
printf(p);
HolePattern = 'E';
j =0;
continue;
}

p =buf;
if (NULL  != (p = strstr(p, "F")))
{
printf(p);
HolePattern = 'F';
j =0;
continue;
}

p =buf;
if (NULL  != (p = strstr(p, "G")))
{
printf(p);
HolePattern = 'G';
j =0;
continue;
}

p =buf;
if (NULL  != (p = strstr(p, "H")))
{
printf(p);
HolePattern = 'H';
j =0;
continue;
}

p =buf;
if (NULL  != (p = strstr(p, "I")))
{
printf(p);
HolePattern = 'I';
j =0;
continue;
}

p =buf;
if (NULL  != (p = strstr(p, "J")))
{
printf(p);
HolePattern = 'J';
j =0;
continue;
}

for (int i=0;i<=9;i++)
{
X[i] = '\0';
}
for (int i=0;i<=9;i++)
{
Y[i] = '\0';
}

p = buf;
//     while (p)
//    {
if (NULL != (p = strstr(p, "X") ) )
{
p=p+2;
X[0] = (*p);
int i =0 ;
while ((*p)!=' ')
{
X[i] = (*p);
p++;
i++;
}
CoorX = atoi(X);
printf("%d,",CoorX);
}
//if (p == NULL){break;}

p = buf;
if (NULL != (p = strstr(p, "Y") ) )
{
p=p+2;
X[0] = (*p);
int i = 0 ;
while ( ((*p)!=' ')&&((*p)!=0) )
{
Y[i] = (*p);
p++;
i++;
}
CoorY = atoi(Y);

switch(HolePattern)
{
case 'A':
HoleA [j][0] = CoorX;
HoleA [j][1] = CoorY;
printf("%d\n",CoorY);
break;

case 'B':
HoleB [j][0] = CoorX;
HoleB [j][1] = CoorY;
printf("%d\n",CoorY);
break;

case 'C':
HoleC [j][0] = CoorX;
HoleC [j][1] = CoorY;
printf("%d\n",CoorY);
break;

case 'D':
HoleD [j][0] = CoorX;
HoleD [j][1] = CoorY;
printf("%d\n",CoorY);
break;

case 'E':
HoleE [j][0] = CoorX;
HoleE [j][1] = CoorY;
printf("%d\n",CoorY);
break;

case 'F':
HoleF [j][0] = CoorX;
HoleF [j][1] = CoorY;
printf("%d\n",CoorY);
break;

case 'G':
HoleG [j][0] = CoorX;
HoleG [j][1] = CoorY;
printf("%d\n",CoorY);
break;

case 'H':
HoleH [j][0] = CoorX;
HoleH [j][1] = CoorY;
printf("%d\n",CoorY);
break;

case 'I':
HoleI [j][0] = CoorX;
HoleI [j][1] = CoorY;
printf("%d\n",CoorY);
break;

case 'J':
HoleJ [j][0] = CoorX;
HoleJ [j][1] = CoorY;
printf("%d\n",CoorY);
break;
}
}
// }
j =j+1;
}
fclose(fp);

combineArray (HoleG,HoleD,20,212,HoleGD);
return 0;
}

//----------上面参数是固定的,下面的参数是可变的-----------
//蚂蚁数量
#define M 75
//最大循环次数NcMax
int NcMax = 1;
//信息启发因子,期望启发式因子,全局信息素挥发参数,局部信息素挥发参数, 状态转移公式中的q0
double alpha = 2, beta = 5, rou = 0.1, alpha1 = 0.1,  qzero = 0.1;
//-----------问题三结束------------------------------------------------------------------------

//===========================================================================================================
//局部更新时候使用的的常量,它是由最近邻方法得到的一个长度
//什么是最近邻方法?:)就是从源节点出发,每次选择一个距离最短的点来遍历所有的节点得到的路径
//每个节点都可能作为源节点来遍历
double Lnn;
//矩阵表示两孔之间的距离
double allDistance

;

//计算两个孔之间的距离
double calculateDistance(int i, int j)
{
return sqrt(pow((HoleB[i][0]-HoleB[j][0]),2.0) + pow((HoleB[i][1]-HoleB[j][1]),2.0));
}

//由矩阵表示两两城市之间的距离
void calculateAllDistance()
{
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
{
if (i != j)
{
allDistance[i][j] = calculateDistance(i, j);
allDistance[j][i] = allDistance[i][j];
}
}
}
}

//获得经过n个城市的路径长度
double calculateSumOfDistance(int* tour)
{
double sum = 0;
for(int i = 0; i< N ;i++)
{
int row = *(tour + 2 * i);
int col = *(tour + 2* i + 1);
sum += allDistance[row][col];
}
return sum;
}

class ACSAnt;

class AntColonySystem
{
private:
double info

, visible

;//节点之间的信息素强度,节点之间的能见度
public:
AntColonySystem()
{
}
//计算当前节点到下一节点转移的概率
double Transition(int i, int j);
//局部更新规则
void UpdateLocalPathRule(int i, int j);
//初始化
void InitParameter(double value);
//全局信息素更新
void UpdateGlobalPathRule(int* bestTour, int globalBestLength);
};

//计算当前节点到下一节点转移的概率
double AntColonySystem::Transition(int i, int j)
{
if (i != j)
{
return (pow(info[i][j],alpha) * pow(visible[i][j], beta));
}
else
{
return 0.0;
}
}
//局部更新规则
void AntColonySystem::UpdateLocalPathRule(int i, int j)
{
info[i][j] = (1.0 - alpha1) * info[i][j] + alpha1 * (1.0 / (N * Lnn));
info[j][i] = info[i][j];
}
//初始化
void AntColonySystem::InitParameter(double value)
{
//初始化路径上的信息素强度tao0
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
{
info[i][j] = value;
info[j][i] = value;
if (i != j)
{
visible[i][j] = 1.0 / allDistance[i][j];
visible[j][i] = visible[i][j];
}
}
}
}

//全局信息素更新
void AntColonySystem::UpdateGlobalPathRule(int* bestTour, int globalBestLength)
{
for(int i = 0; i < N; i++)
{
int row = *(bestTour + 2 * i);
int col = *(bestTour + 2* i + 1);
info[row][col] = (1.0 - rou) * info[row][col] + rou * (1.0 / globalBestLength);
info[col][row] =info[row][col];
}
}

class ACSAnt
{
private:
AntColonySystem* antColony;
protected:
int startCity, cururentCity;//初始城市编号,当前城市编号
int allowed
;//禁忌表
int Tour
[2];//当前路径
int currentTourIndex;//当前路径索引,从0开始,存储蚂蚁经过城市的编号
public:
ACSAnt(AntColonySystem* acs, int start)
{
antColony = acs;
startCity = start;
}
//开始搜索
int* Search();
//选择下一节点
int Choose();
//移动到下一节点
void MoveToNextCity(int nextCity);

};

//开始搜索
int* ACSAnt::Search()
{
cururentCity = startCity;
int toCity;
currentTourIndex = 0;
for(int i  = 0; i < N; i++)
{
allowed[i] = 1;
}
allowed[cururentCity] = 0;
int endCity;
int count = 0;
do
{
count++;
endCity = cururentCity;
toCity = Choose();
if (toCity >= 0)
{
MoveToNextCity(toCity);
antColony->UpdateLocalPathRule(endCity, toCity);
cururentCity = toCity;
}
}while(toCity >= 0);
MoveToNextCity(startCity);
antColony->UpdateLocalPathRule(endCity, startCity);

return *Tour;
}

//选择下一节点
int ACSAnt::Choose()
{
int nextCity = -1;
double q = rand()/(double)RAND_MAX;
//如果 q <= q0,按先验知识,否则则按概率转移,
if (q <= qzero)
{
double probability = -1.0;//转移到下一节点的概率
for(int i = 0; i < N; i++)
{
//去掉禁忌表中已走过的节点,从剩下节点中选择最大概率的可行节点
if (1 == allowed[i])
{
double prob = antColony->Transition(cururentCity, i);
if (prob  > probability)
{
nextCity = i;
probability = prob;
}
}
}
}
else
{
//按概率转移
double p = rand()/(double)RAND_MAX;//生成一个随机数,用来判断落在哪个区间段
double sum = 0.0;
double probability = 0.0;//概率的区间点,p 落在哪个区间段,则该点是转移的方向
//计算概率公式的分母的值
for(int i = 0; i < N; i++)
{
if (1 == allowed[i])
{
sum += antColony->Transition(cururentCity, i);
}
}
for(int j = 0; j < N; j++)
{
if (1 == allowed[j] && sum > 0)
{
probability += antColony->Transition(cururentCity, j)/sum;
if (probability >= p || (p > 0.9999 && probability > 0.9999))
{
nextCity = j;
break;
}
}
}
}
return nextCity;
}

//移动到下一节点
void ACSAnt::MoveToNextCity(int nextCity)
{
allowed[nextCity]=0;
Tour[currentTourIndex][0] = cururentCity;
Tour[currentTourIndex][1] = nextCity;
currentTourIndex++;
cururentCity = nextCity;
}

//------------------------------------------
//选择下一个节点,配合下面的函数来计算的长度
int ChooseNextNode(int currentNode, int visitedNode[])
{
int nextNode = -1;
double shortDistance = 0.0;
for(int i = 0; i < N; i++)
{
//去掉已走过的节点,从剩下节点中选择距离最近的节点
if (1 == visitedNode[i])
{
if (shortDistance == 0.0)
{
shortDistance = allDistance[currentNode][i];
nextNode = i;
}
if(shortDistance < allDistance[currentNode][i])
{
nextNode = i;
}
}
}
return nextNode;
}

//给一个节点由最近邻距离方法计算长度
double CalAdjacentDistance(int node)
{
double sum = 0.0;
int visitedNode
;
for(int j = 0; j < N; j++)
{
visitedNode[j] = 1;
}
visitedNode[node] = 0;
int currentNode = node;
int nextNode;
do
{
nextNode = ChooseNextNode(currentNode, visitedNode);
if (nextNode >= 0)
{
sum += allDistance[currentNode][nextNode];
currentNode= nextNode;
visitedNode[currentNode] = 0;
}
}while(nextNode >= 0);
sum += allDistance[currentNode][node];
return sum;
}

//---------------------------------结束---------------------------------------------

//--------------------------主函数--------------------------------------------------
int main()
{
time_t timer,timerl;

DataInit();

time(&timer);
unsigned long seed = timer;
seed %= 56000;
srand((unsigned int)seed);

//由矩阵表示两两城市之间的距离
calculateAllDistance();
//蚁群系统对象
AntColonySystem* acs = new AntColonySystem();
ACSAnt* ants[M];
//蚂蚁均匀分布在城市上
for(int k = 0; k < M; k++)
{
ants[k] = new ACSAnt(acs, (int)(k%N));
}
calculateAllDistance();
//随机选择一个节点计算由最近邻方法得到的一个长度
int node = rand() % N;
Lnn = CalAdjacentDistance(node);

//各条路径上初始化的信息素强度
double initInfo = 1 / (N * Lnn);
acs->InitParameter(initInfo);

//全局最优路径
int globalTour
[2];
//全局最优长度
double globalBestLength = 0.0;
for(int i = 0; i < NcMax; i++)
{
//局部最优路径
int localTour
[2];
//局部最优长度
double localBestLength = 0.0;
//当前路径长度
double tourLength;
for(int j = 0; j < M; j++)
{
int* tourPath = ants[j]->Search();
tourLength = calculateSumOfDistance(tourPath);
//局部比较,并记录路径和长度
if(tourLength < localBestLength || abs(localBestLength - 0.0) < 0.000001)
{
for(int m = 0; m< N; m++)
{
int row = *(tourPath + 2 * m);
int col = *(tourPath + 2* m + 1);
localTour[m][0] = row;
localTour[m][1] = col;
}
localBestLength = tourLength;
}
}
//全局比较,并记录路径和长度
if(localBestLength < globalBestLength || abs(globalBestLength - 0.0) < 0.000001)
{
for(int m = 0; m< N; m++)
{
globalTour[m][0] = localTour[m][0];
globalTour[m][1] = localTour[m][1];
}
globalBestLength = localBestLength;
}
acs->UpdateGlobalPathRule(*globalTour, globalBestLength);
//输出所有蚂蚁循环一次后的迭代最优路径
//cout<<"第 "<<i + 1<<" 迭代最优路径:"<<localBestLength<<"."<<endl;
for(int m = 0; m< N; m++)
{
//        cout<<localTour[m][0]<<".";
}
cout<<endl;
}
//输出全局最优路径
cout<<"全局最优路径长度:"<<globalBestLength<<endl;
//    cout<<"全局最优路径:";
for(int m = 0; m< N; m++)
{
// cout<<globalTour[m][0]<<".";
if (m == 0)
{
int i = globalTour[m][0];
cout<<"起点坐标X:"<<HoleB[i][0]<<"起点坐标Y:" <<HoleB[i][1];
}
if (m == N-1)
{
int i = globalTour[m][0];
cout<<"终点坐标X:"<<HoleB[i][0]<<"终点坐标Y:" <<HoleB[i][1];
//printf ("%f",HoleGD[i][1]);
}
}
cout<<endl;
time(&timerl);
int t = timerl - timer;

double  cost = globalBestLength /100000* 25.4*  0.06;

printf ("加工A孔需要的花费%f",cost);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: