基于基本蚁群算法解决连续优化问题

基于基本蚁群算法解决连续优化问题

相关链接

TSP_旅行商问题-基本蚁群算法

基本蚁群算法解决连续优化问题基本流程

用一个蚂蚁代表一个可行解,一个蚂蚁含有的信息包括各变量值;
1、确定迭代周期;
2、确定蚂蚁数;
2.a、随机初始化蚁群,记录蚁群中的最优解;
2.b、进入循环,将已初始化的蚂蚁分为两种;
2.b.a、一种是上一次蚁群中的最优解,搜索在最优解附近搜索;
可行解格式{ 1 自 变 量 1 2 自 变 量 2 n 自 变 量 n }
X={ x1 x 1 x2 x 2 xn x n }

xi=xi+ωL x i = x i + ω ∗ L


xi=xiωL x i = x i − ω ∗ L 择优录取吧,每次循环后,

ω ω 要变小;




2.b.b、另一种是非最优解,有一定概率向最优解进化;


P=emessbestmessiemessbest P = e m e s s b e s t − m e s s i e m e s s b e s t


messbest m e s s b e s t 最优解蚂蚁的信息素浓度;


messi m e s s i 当前蚂蚁的信息素浓度;






2.b.b.a、向最优解移动:


xi=xi+u(xbestxi) x i = x i + u ∗ ( x b e s t − x i )






2.b.b.b、自己搜索移动:


xi=xi+dxrand(1,1) x i = x i + d x ∗ r a n d ( − 1 , 1 )


2.c、更新信息素


messi=(1p)messi+kaf(X) m e s s i = ( 1 − p ) ∗ m e s s i + k ∗ a − f ( X )

参数设置

最大迭代周期 T = 200;
蚂蚁数量 ant_size = 25;
信息素衰退因子 p = 0.9;
步长系数 ω ω = 1,随着迭代的进行变小
步长系数减小因数 wu = 0.5;该数值越大,搜的范围越精细;
最优解搜索步长 dx[max_x]:一般为自变量取值范围的一半;防止局部最优解;
更新信息素系数 k = 1;
更新信息素因子 a;求最小值时a取e;求最大值时a取0.5;
非最优解步长系数 u = 0.7;
非最优解向最优解进化概率 p0 = 0.7;

本算法的fun()函数里包含三个求最小值样例;
三个return分别代表三个函数

  • 函数一:二维分段函数,自变量范围[-5,5]

    f()={x2,x<=1;(x3)23,x>1; f ( ) = { x 2 , x <= 1 ; ( x − 3 ) 2 − 3 , x > 1 ;
    图像:
    《基于基本蚁群算法解决连续优化问题》
    10组测试结果:
    《基于基本蚁群算法解决连续优化问题》

  • 函数二:二维复杂函数,自变量范围[-5,5]

    f()=x+10sin(5x)+7cos(4x) f ( ) = x + 10 ∗ s i n ( 5 ∗ x ) + 7 ∗ c o s ( 4 ∗ x )
    图像:
    《基于基本蚁群算法解决连续优化问题》
    10组测试结果:
    《基于基本蚁群算法解决连续优化问题》

  • 函数三:三维函数,自变量 x0 x 0 范围[-10,10], x1 x 1 范围[-10,10];

    f()=x01+abs(x1) f ( ) = x 0 1 + a b s ( x 1 )
    图像:
    《基于基本蚁群算法解决连续优化问题》
    10组测试结果:
    《基于基本蚁群算法解决连续优化问题》

算法代码

#include<iostream>
#include<ctime>
#include<cmath>
#include<fstream>
#include<algorithm>
#include<string.h>
#include<iomanip>
using namespace std;
//常量
const int max_x = 10;//自变量规模最大值
const int max_ants = 1000;//蚂蚁规模最大值
//变量
int x_size;//自变量规模
int low_bound[max_x];//自变量下界
int high_bound[max_x];//自变量上界
int ant_size=5;//蚂蚁数量
int T;//迭代周期
double message[max_ants];//信息素
double w;//步长系数,随着迭代的进行变小
double wu;//步长系数减小因数
double dx[max_x];//最优解搜索步长
double k;//更新信息素系数
double a;//更新信息素因子
double u;//非最优解步长系数
double p0;//非最优解向最优解进化概率
double p;//信息素衰减系数
double best_ants[max_x];//最优解对应自变量值
double best;//最优解
double fun(double* num){//求解函数

    return num[0] <= 1 ? pow(num[0], 2) : (pow(num[0] - 3, 2) - 3);
    //return num[0] + 10 * sin(5 * num[0]) + 7 * cos(4 * num[0]);
    //return num[0] / (1 + abs(num[1]));
}
void init() {
    x_size=1;//自变量规模
    for (int i = 0; i < x_size; ++i) {
        low_bound[i] = -5;//自变量下界
        high_bound[i]=5;//自变量上界
        dx[i]=high_bound[i]-low_bound[i];//最优解搜索步长,,一般为数据范围的一半
    }
    T = 200;//迭代周期
    ant_size = 25;//蚂蚁数量

    w=1;//最优解步长系数,随着迭代的进行变小
    wu = 0.5;
    k=1;//更新信息素系数
    //a=exp(1);//更新信息素因子
    a = 0.5;///////////////
    p0 = 0.7;//非最优解向最优解进化概率
    u=0.7;//非最优解步长系数
    p=0.9;//信息素衰减系数
    //best =1e9;////////////
    best = -1e9;
}

double mrand(int l, int r) {//范围在20内
    int t = l;
    r -= l;
    l -= l;
    const double v = 1e3;
    r *= v;
    l *= v;
    double temp = rand() % ((r - l) + 1);
    //int a = RAND_MAX;
    temp += 1 + l;
    return temp / v+t;
    //return (rand() % ((r - l) + 1) + 1 + l)/1e6;
}
double get_p(int i, int bes) {
    return exp(message[bes] - message[i]) / exp(message[bes]);
}
void islegal(double* xi) {
    for (int i = 0; i < x_size; ++i) {
        if (xi[i] > high_bound[i])
            xi[i]=high_bound[i];
        else if(xi[i] < low_bound[i])
            xi[i] = low_bound[i];
    }
}
//max
/* void moni() { a = 0.5;/////////////// best = -1e9; double t_ants[max_ants][max_x];//蚁群 double value[max_ants];// double ans = best;// int t_ant;//局部最优解 for (int i = 0; i < ant_size; ++i) { for (int j = 0; j < x_size; ++j) { t_ants[i][j] = mrand(low_bound[j], high_bound[j]); } value[i] = fun(t_ants[i]); if (ans < value[i]) {///////// ans = value[i]; t_ant = i; } message[i] = k * pow(a, -fun(t_ants[i]));//信息素初始化 } int t = T; double x1[max_x];//构建临时解 double x2[max_x]; while (t--) {//开始迭代循环 for (int i = 0; i<ant_size; ++i) {//更新信息素 //message[i] = (1-p) * message[i] + t_mess[i]; //message[i] = (1 - p) * message[i] + k * pow(a, -fun(t_ants[t_ant])); message[i] = (1 - p) * message[i]; } double tw = w; for (int i = 0; i<ant_size; ++i) {//遍历每只蚂蚁 if (value[i] == ans) {//上次循环最优解 for (int j = 0; j < x_size; ++j) { x1[j] = t_ants[i][j] + tw * dx; x2[j] = t_ants[i][j] - tw * dx; } tw *= 0.1; islegal(x1); if (value[i] < fun(x1)) {////////////// value[i] = fun(x1); ans = value[i]; t_ant = i; for (int j = 0; j < x_size; ++j) { t_ants[i][j] = x1[j]; } } islegal(x2); if (value[i] < fun(x2)) {/////////////// value[i] = fun(x2); ans = value[i]; t_ant = i; for (int j = 0; j < x_size; ++j) { t_ants[i][j] = x2[j]; } } } else {//非最优解 if (get_p(i, ans)<p0) {//向最优解移动 for (int j = 0; j < x_size; ++j) { x1[j] = t_ants[i][j] + u * (t_ants[t_ant][j] - t_ants[i][j]); } } else { for (int j = 0; j < x_size; ++j) { x1[j] = t_ants[i][j] + dx * mrand(-1, 1); } } islegal(x1); if (ans < fun(x1)) {////////////// ans = fun(x1); value[i] = ans; t_ant = i; for (int j = 0; j < x_size; ++j) t_ants[i][j] = x1[j]; } } //t_mess[i] += k * pow(a, -ans); message[i] += k * pow(a, -fun(t_ants[i])); } // //for (int i = 0; i<ant_size; ++i) {//更新信息素 //message[i] = (1-p) * message[i] + t_mess[i]; //message[i] = (1 - p) * message[i] + k * pow(a, -fun(t_ants[t_ant])); //} //ans = min(ans,t_ans); } for (int i = 0; i < x_size; ++i) { best_ants[i] = t_ants[t_ant][i]; } best = ans; } */
void moni() {//min

    a=exp(1);//更新信息素因子
    best = 1e9;
    double t_ants[max_ants][max_x];//蚁群
    double value[max_ants];//
    double ans = best;//
    int t_ant;//局部最优解
    for (int i = 0; i < ant_size; ++i) {
        for (int j = 0; j < x_size; ++j) {
            t_ants[i][j] = mrand(low_bound[j], high_bound[j]);
        }
        value[i] = fun(t_ants[i]);
        if (ans > value[i]) {/////////
            ans = value[i];
            t_ant = i;
        }
        message[i] = k * pow(a, -fun(t_ants[i]));//信息素初始化
    }
    int t = T;
    double x1[max_x];//构建临时解
    double x2[max_x];

    while (t--) {//开始迭代循环
        for (int i = 0; i<ant_size; ++i) {//更新信息素
            //message[i] = (1-p) * message[i] + t_mess[i];
            //message[i] = (1 - p) * message[i] + k * pow(a, -fun(t_ants[t_ant]));
            message[i] = (1 - p) * message[i];
        }
        double tw = w;
        for (int i = 0; i<ant_size; ++i) {//遍历每只蚂蚁
            if (value[i] == ans) {//上次循环最优解
                for (int j = 0; j < x_size; ++j) {
                    x1[j] = t_ants[i][j] + tw * dx[j];
                    x2[j] = t_ants[i][j] - tw * dx[j];
                }
                tw *= wu; 
                islegal(x1);
                if (value[i] > fun(x1)) {//////////////
                    value[i] = fun(x1);
                    ans = value[i];
                    t_ant = i;
                    for (int j = 0; j < x_size; ++j) {
                        t_ants[i][j] = x1[j];
                    }
                }
                islegal(x2);
                if (value[i] > fun(x2)) {///////////////
                    value[i] = fun(x2);
                    ans = value[i];
                    t_ant = i;
                    for (int j = 0; j < x_size; ++j) {
                        t_ants[i][j] = x2[j];
                    }
                }
            }
            else {//非最优解
                if (get_p(i, ans)<p0) {//向最优解移动
                    for (int j = 0; j < x_size; ++j) {
                        x1[j] = t_ants[i][j] + u * (t_ants[t_ant][j] - t_ants[i][j]);
                    }
                }
                else {
                    for (int j = 0; j < x_size; ++j) {
                        x1[j] = t_ants[i][j] + dx[j] * mrand(-1, 1);
                    }
                }
                islegal(x1);
                if (ans > fun(x1)) {//////////////
                    ans = fun(x1);
                    value[i] = ans;
                    t_ant = i;
                    for (int j = 0; j < x_size; ++j)
                        t_ants[i][j] = x1[j];
                }
            }
            //t_mess[i] += k * pow(a, -ans);
            message[i] += k * pow(a, -fun(t_ants[i]));
        }
        //
        //for (int i = 0; i<ant_size; ++i) {//更新信息素
            //message[i] = (1-p) * message[i] + t_mess[i];
            //message[i] = (1 - p) * message[i] + k * pow(a, -fun(t_ants[t_ant]));
        //}
        //ans = min(ans,t_ans);
    }
    for (int i = 0; i < x_size; ++i) {
        best_ants[i] = t_ants[t_ant][i];
    }
    best = ans;
}
void output() {
    for (int i = 0; i < x_size; ++i) {
        cout << "x" << i << " = " << best_ants[i];
        if (i != x_size - 1)
            cout << " , ";
        else
            cout << endl;
    }
    cout <<fixed<< "f() = " << best << endl;
    cout.clear();
}
int main() {
    srand(time(nullptr));
    int t;
    while (cin >> t) {//仅作为重启算法开关使用,无意义
        //for (int i = 0; i < t; ++i) {
            init();//使用程序内置数据使用init()函数,
                   //test();//使用文件读取数据使用test()函数
            moni();//开始算法
            output();//输出
        //}
    }
    return 0;
}
    原文作者:蚁群算法
    原文地址: https://blog.csdn.net/wordsin/article/details/79983257
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞