标签:
// 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[N][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[N][N]; //计算两个孔之间的距离 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[N][N], visible[N][N];//节点之间的信息素强度,节点之间的能见度 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[N];//禁忌表 int Tour[N][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[N]; 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[N][2]; //全局最优长度 double globalBestLength = 0.0; for(int i = 0; i < NcMax; i++) { //局部最优路径 int localTour[N][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; }
ant colony algorithm && decision tree
标签:
原文地址:http://www.cnblogs.com/hgonlywj/p/4842691.html