ant colony algorithm && decision tree

// 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;  
}  

 

posted on 2015-09-27 20:28  HGonlyWJ  阅读(303)  评论(0编辑  收藏  举报

W3C中国
阮老师的网络日志
canvas
runoob
迷渡
并发编程网
原生JS例子
前端外刊评论