zoukankan      html  css  js  c++  java
  • 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]={''};
    char Y[10]={''};
    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
    ");
            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] = '';
                }
                for (int i=0;i<=9;i++)
                {
                    Y[i] = '';
                }
    
            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
    ",CoorY);
                        break;
    
                        case 'B':
                        HoleB [j][0] = CoorX;
                        HoleB [j][1] = CoorY;
                        printf("%d
    ",CoorY);
                        break;
    
                        case 'C':
                        HoleC [j][0] = CoorX;
                        HoleC [j][1] = CoorY;
                        printf("%d
    ",CoorY);
                        break;
    
                        case 'D':
                        HoleD [j][0] = CoorX;
                        HoleD [j][1] = CoorY;
                        printf("%d
    ",CoorY);
                        break;
    
                        case 'E':
                        HoleE [j][0] = CoorX;
                        HoleE [j][1] = CoorY;
                        printf("%d
    ",CoorY);
                        break;
    
                        case 'F':
                        HoleF [j][0] = CoorX;
                        HoleF [j][1] = CoorY;
                        printf("%d
    ",CoorY);
                        break;
    
                        case 'G':
                        HoleG [j][0] = CoorX;
                        HoleG [j][1] = CoorY;
                        printf("%d
    ",CoorY);
                        break;
    
                        case 'H':
                        HoleH [j][0] = CoorX;
                        HoleH [j][1] = CoorY;
                        printf("%d
    ",CoorY);
                        break;
                        
                        case 'I':
                        HoleI [j][0] = CoorX;
                        HoleI [j][1] = CoorY;
                        printf("%d
    ",CoorY);
                        break;
    
                        case 'J':
                        HoleJ [j][0] = CoorX;
                        HoleJ [j][1] = CoorY;
                        printf("%d
    ",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;  
    }  
  • 相关阅读:
    Java相关面试题总结+答案(二)
    Java相关面试题总结+答案(一)
    Java相关面试题总结
    jdk各个版本的新特性(jdk1.7,1.8,1.9)
    Java内存区域
    数据库一、二、三范式
    外部按钮控制video视频的播放暂停
    jquery获取div跟textarea标签内容
    JS获取系统时间及日期
    滚动条插件---jquery.nicescroll.js 简单使用
  • 原文地址:https://www.cnblogs.com/hgonlywj/p/4842691.html
Copyright © 2011-2022 走看看