【智能算法】SOA海鸥优化算法求解无约束多元函数最值(Java代码实现)

本文涉及的产品
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
简介: 【智能算法】SOA海鸥优化算法求解无约束多元函数最值(Java代码实现)

@[toc]


前言

本文以求解二元函数最小值为例,如果需要求解多元函数,只需要修改以下变量即可:

  • varNum:变量维度数
  • ub和lb:变量的上下界
  • vMaxArr:每个维度的搜索速度限制

优化目标

目标:在变量区间范围最小化 Z = x^2 + y^2 - xy - 10x - 4y +60

求解结果

变量取值为:[8.00467444888266, 5.996471166439097]
最优解为:8.000050798490747

搜索过程可视化

在这里插入图片描述

Java算法代码

import java.util.Arrays;
import java.util.Random;

/**
 * @Author:WSKH
 * @ClassName:SOA_Solve
 * @ClassType:
 * @Description:
 * @Date:2022/6/8/18:26
 * @Email:1187560563@qq.com
 * @Blog:https://blog.csdn.net/weixin_51545953?type=blog
 */
public class SOA_Solve {

    // 海鸥对象
    class Seagull {
        // 当前海鸥的坐标(自变量数组)
        double[] curVars;
        // 当前自变量对应的目标函数值
        double curObjValue;
        // 适应度(解决最小化问题,所以适应度为目标函数值的倒数)
        double fit;
        // 全参构造
        public Seagull(double[] curVars, double curObjValue, double fit) {
            this.curVars = curVars;
            this.curObjValue = curObjValue;
            this.fit = fit;
        }
    }

    // 算法参数
    // 变量个数
    int varNum = 2;
    // 最大迭代次数
    int maxGen = 1000;
    // 海鸥群中海鸥的个数
    int seagullNum = 200;
    // 控制采用变量A的频率
    double fc = 2;
    // 定义螺旋形状的常量
    double u = 1;
    double v = 1;
    // 局部盘旋次数
    int localSearchCnt = 10;
    // 步长数组(各个维度的步长)
    double[] stepArr = new double[]{1.2, 1.2};
    // 变量的上下界
    double[] ub = new double[]{1000, 1000};
    double[] lb = new double[]{-1000, -1000};
    // 随机数对象
    Random random = new Random();
    // 海鸥群
    Seagull[] seagulls;
    // 最佳的海鸥
    Seagull bestSeagull;
    // 记录迭代过程
    public double[][][] positionArr;
    // 当前记录的行数
    int r;

    // 求解主函数
    public void solve() {
        // 初始化海鸥群
        initSeagulls();
        // 开始迭代
        for (int i = 0; i < maxGen; i++) {
            // 螺旋行为
            SpiralBehavior(i);
            report();
        }
        // 输出最好的结果
        System.out.println("变量取值为:" + Arrays.toString(bestSeagull.curVars));
        System.out.println("最优解为:" + bestSeagull.curObjValue);
    }

    // 螺旋行为
    void SpiralBehavior(int t) {
        for (int i = 0; i < seagulls.length; i++) {
            for (int j = 0; j < localSearchCnt; j++) {
                Seagull tempSeagull = copySeagull(seagulls[i]);
                double k = random.nextDouble() * 2 * Math.PI;
                double rd = random.nextDouble();
                for (int m = 0; m < varNum; m++) {
                    double r = u * Math.exp(k * v);
                    double x = r * Math.cos(k);
                    double y = r * Math.sin(k);
                    double z = r * k;
                    double ds = getDs(tempSeagull.curVars[m], t, m, rd);
                    double move = (ds * x * y * z) + bestSeagull.curVars[m] - tempSeagull.curVars[m];
                    moveSeagull(tempSeagull, m, move);
                }
                updateSeagull(tempSeagull);
                seagulls[i] = tempSeagull;
                if (tempSeagull.fit > bestSeagull.fit) {
                    bestSeagull = copySeagull(tempSeagull);
                }
            }
        }
    }

    /**
     * @param x 当前海鸥当前维度的值
     * @param t 当前迭代数
     * @param m 当前计算的维度
     * @Description 计算Ds
     */
    double getDs(double x, int t, int m, double rd) {
        double A = fc - (t * (fc / maxGen));
        double B = 2 * A * A * rd;
        double cs = A * x;
        double ms = B * (bestSeagull.curVars[m] - x);
        return Math.abs(cs + ms);
    }

    // 记录
    void report() {
        for (int i = 0; i < seagulls.length; i++) {
            for (int j = 0; j < varNum; j++) {
                positionArr[r][i][j] = seagulls[i].curVars[j];
            }
        }
        r++;
    }

    // 求两个海鸥之间的距离
    double getDistance(Seagull f1, Seagull f2) {
        double dis = 0d;
        for (int i = 0; i < varNum; i++) {
            dis += Math.pow(f1.curVars[i] - f2.curVars[i], 2);
        }
        return Math.sqrt(dis);
    }

    // 初始化海鸥群
    private void initSeagulls() {
        positionArr = new double[maxGen][seagullNum][varNum];
        seagulls = new Seagull[seagullNum];
        for (int i = 0; i < seagullNum; i++) {
            seagulls[i] = getRandomSeagull();
            if (i == 0 || bestSeagull.fit < seagulls[i].fit) {
                bestSeagull = copySeagull(seagulls[i]);
            }
        }
    }

    // 控制海鸥在第m个维度上移动n个距离
    public void moveSeagull(Seagull seagull, int m, double n) {
        // 移动
        seagull.curVars[m] += n;
        // 超出定义域的判断
        if (seagull.curVars[m] < lb[m]) {
            seagull.curVars[m] = lb[m];
        }
        if (seagull.curVars[m] > ub[m]) {
            seagull.curVars[m] = ub[m];
        }
    }

    // 更新海鸥信息
    void updateSeagull(Seagull seagull) {
        double objValue = getObjValue(seagull.curVars);
        seagull.curObjValue = objValue;
        seagull.fit = 1 / objValue;
    }

    // 获取一个随机生成的海鸥
    Seagull getRandomSeagull() {
        double[] vars = new double[varNum];
        for (int j = 0; j < vars.length; j++) {
            vars[j] = lb[j] + random.nextDouble() * (ub[j] - lb[j]);
        }
        double objValue = getObjValue(vars);
        return new Seagull(vars.clone(), objValue, 1 / objValue);
    }

    /**
     * @param vars 自变量数组
     * @return 返回目标函数值
     */
    public double getObjValue(double[] vars) {
        //目标:在变量区间范围最小化 Z = x^2 + y^2 - xy - 10x - 4y +60
        return Math.pow(vars[0], 2) + Math.pow(vars[1], 2) - vars[0] * vars[1] - 10 * vars[0] - 4 * vars[1] + 60;
    }

    // 复制海鸥
    Seagull copySeagull(Seagull old) {
        return new Seagull(old.curVars.clone(), old.curObjValue, old.fit);
    }

}

可视化代码

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;

/**
 * @Author:WSKH
 * @ClassName:PlotUtil
 * @ClassType:
 * @Description:
 * @Date:2022/6/6/18:31
 * @Email:1187560563@qq.com
 * @Blog:https://blog.csdn.net/weixin_51545953?type=blog
 */
public class PlotUtil extends Application {

    //当前的时间轴
    private Timeline nowTimeline;
    //绘图位置坐标
    private double[][][] positionArr;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        // 调用算法获取绘图数据
        SOA_Solve solver = new SOA_Solve();
        solver.solve();
        positionArr = solver.positionArr;

        // 画图
        try {
            BorderPane root = new BorderPane();
            root.setStyle("-fx-padding: 20;");
            Scene scene = new Scene(root, 1600, 900);
            double canvasWid = 800;
            double canvasHei = 800;
            //根据画布大小缩放坐标值
            this.fixPosition(canvasWid - 100, canvasHei - 100);

            //画布和画笔
            HBox canvasHbox = new HBox();
            Canvas canvas = new Canvas();
            canvas.setWidth(canvasWid);
            canvas.setHeight(canvasHei);
            canvasHbox.setPrefWidth(canvasWid);
            canvasHbox.getChildren().add(canvas);
            canvasHbox.setAlignment(Pos.CENTER);
            canvasHbox.setStyle("-fx-spacing: 20;" +
                    "-fx-background-color: #87e775;");
            root.setTop(canvasHbox);
            GraphicsContext paintBrush = canvas.getGraphicsContext2D();

            //启动
            HBox hBox2 = new HBox();
            Button beginButton = new Button("播放迭代过程");
            hBox2.getChildren().add(beginButton);
            root.setBottom(hBox2);
            hBox2.setAlignment(Pos.CENTER);
            //启动仿真以及暂停仿真
            beginButton.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
                nowTimeline.play();
            });

            //创建扫描线连接动画
            nowTimeline = new Timeline();
            createAnimation(paintBrush);

            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 修正cityPositionArr的坐标,让画出来的点在画布内
     *
     * @param width
     * @param height
     */
    private void fixPosition(double width, double height) {
        double minX = Double.MAX_VALUE;
        double maxX = -Double.MAX_VALUE;
        double minY = Double.MAX_VALUE;
        double maxY = -Double.MAX_VALUE;

        for (int i = 0; i < this.positionArr.length; i++) {
            for (int j = 0; j < this.positionArr[0].length; j++) {
                minX = Math.min(minX, this.positionArr[i][j][0]);
                maxX = Math.max(maxX, this.positionArr[i][j][0]);
                minY = Math.min(minY, this.positionArr[i][j][1]);
                maxY = Math.max(maxY, this.positionArr[i][j][1]);
            }
        }

        double multiple = Math.max((maxX - minX) / width, (maxY - minY) / height);

        //转化为正数数
        for (int i = 0; i < this.positionArr.length; i++) {
            for (int j = 0; j < this.positionArr[0].length; j++) {
                if (minX < 0) {
                    this.positionArr[i][j][0] = this.positionArr[i][j][0] - minX;
                }
                if (minY < 0) {
                    this.positionArr[i][j][1] = this.positionArr[i][j][1] - minY;
                }
            }
        }

        for (int i = 0; i < this.positionArr.length; i++) {
            for (int j = 0; j < this.positionArr[0].length; j++) {
                this.positionArr[i][j][0] = this.positionArr[i][j][0] / multiple;
                this.positionArr[i][j][1] = this.positionArr[i][j][1] / multiple;
            }
        }

    }

    /**
     * 用画笔在画布上画出所有的孔
     * 画第i代的所有粒子
     */
    private void drawAllCircle(GraphicsContext paintBrush, int i) {
        paintBrush.clearRect(0, 0, 2000, 2000);
        paintBrush.setFill(Color.RED);
        for (int j = 0; j < this.positionArr[i].length; j++) {
            drawCircle(paintBrush, i, j);
        }
    }

    /**
     * 用画笔在画布上画出一个孔
     * 画第i代的第j个粒子
     */
    private void drawCircle(GraphicsContext paintBrush, int i, int j) {
        double x = this.positionArr[i][j][0];
        double y = this.positionArr[i][j][1];
        double radius = 2;
        // 圆的直径
        double diameter = radius * 2;
        paintBrush.fillOval(x, y, diameter, diameter);
    }

    /**
     * 创建动画
     */
    private void createAnimation(GraphicsContext paintBrush) {
        for (int i = 0; i < this.positionArr[0].length; i++) {
            int finalI = i;
            KeyFrame keyFrame = new KeyFrame(Duration.seconds(i * 0.05), event -> drawAllCircle(paintBrush, finalI));
            nowTimeline.getKeyFrames().add(keyFrame);
        }
    }

}
相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
1天前
|
算法
基于遗传优化算法的风力机位置布局matlab仿真
本项目基于遗传优化算法(GA)进行风力机位置布局的MATLAB仿真,旨在最大化风场发电效率。使用MATLAB2022A版本运行,核心代码通过迭代选择、交叉、变异等操作优化风力机布局。输出包括优化收敛曲线和最佳布局图。遗传算法模拟生物进化机制,通过初始化、选择、交叉、变异和精英保留等步骤,在复杂约束条件下找到最优布局方案,提升风场整体能源产出效率。
|
7天前
|
机器学习/深度学习 存储 算法
近端策略优化(PPO)算法的理论基础与PyTorch代码详解
近端策略优化(PPO)是深度强化学习中高效的策略优化方法,广泛应用于大语言模型的RLHF训练。PPO通过引入策略更新约束机制,平衡了更新幅度,提升了训练稳定性。其核心思想是在优势演员-评论家方法的基础上,采用裁剪和非裁剪项组成的替代目标函数,限制策略比率在[1-ϵ, 1+ϵ]区间内,防止过大的策略更新。本文详细探讨了PPO的基本原理、损失函数设计及PyTorch实现流程,提供了完整的代码示例。
122 10
近端策略优化(PPO)算法的理论基础与PyTorch代码详解
|
1月前
|
算法 数据可视化 安全
基于DWA优化算法的机器人路径规划matlab仿真
本项目基于DWA优化算法实现机器人路径规划的MATLAB仿真,适用于动态环境下的自主导航。使用MATLAB2022A版本运行,展示路径规划和预测结果。核心代码通过散点图和轨迹图可视化路径点及预测路径。DWA算法通过定义速度空间、采样候选动作并评估其优劣(目标方向性、障碍物距离、速度一致性),实时调整机器人运动参数,确保安全避障并接近目标。
149 68
|
1天前
|
机器学习/深度学习 数据采集 算法
基于WOA鲸鱼优化的CNN-GRU-SAM网络时间序列回归预测算法matlab仿真
本项目基于MATLAB 2022a实现时间序列预测,采用CNN-GRU-SAM网络结构,结合鲸鱼优化算法(WOA)优化网络参数。核心代码含操作视频,运行效果无水印。算法通过卷积层提取局部特征,GRU层处理长期依赖,自注意力机制捕捉全局特征,全连接层整合输出。数据预处理后,使用WOA迭代优化,最终输出最优预测结果。
|
4天前
|
算法
基于SOA海鸥优化算法的三维曲面最高点搜索matlab仿真
本程序基于海鸥优化算法(SOA)进行三维曲面最高点搜索的MATLAB仿真,输出收敛曲线和搜索结果。使用MATLAB2022A版本运行,核心代码实现种群初始化、适应度计算、交叉变异等操作。SOA模拟海鸥觅食行为,通过搜索飞行、跟随飞行和掠食飞行三种策略高效探索解空间,找到全局最优解。
|
2天前
|
传感器 算法
基于GA遗传算法的多机无源定位系统GDOP优化matlab仿真
本项目基于遗传算法(GA)优化多机无源定位系统的GDOP,使用MATLAB2022A进行仿真。通过遗传算法的选择、交叉和变异操作,迭代优化传感器配置,最小化GDOP值,提高定位精度。仿真输出包括GDOP优化结果、遗传算法收敛曲线及三维空间坐标点分布图。核心程序实现了染色体编码、适应度评估、遗传操作等关键步骤,最终展示优化后的传感器布局及其性能。
|
6天前
|
传感器 算法 物联网
基于粒子群算法的网络最优节点部署优化matlab仿真
本项目基于粒子群优化(PSO)算法,实现WSN网络节点的最优部署,以最大化节点覆盖范围。使用MATLAB2022A进行开发与测试,展示了优化后的节点分布及其覆盖范围。核心代码通过定义目标函数和约束条件,利用PSO算法迭代搜索最佳节点位置,并绘制优化结果图。PSO算法灵感源于鸟群觅食行为,适用于连续和离散空间的优化问题,在通信网络、物联网等领域有广泛应用。该算法通过模拟粒子群体智慧,高效逼近最优解,提升网络性能。
|
6天前
|
机器学习/深度学习 数据采集 算法
基于GWO灰狼优化的CNN-GRU-SAM网络时间序列回归预测算法matlab仿真
本项目基于MATLAB2022a,展示了时间序列预测算法的运行效果(无水印)。核心程序包含详细中文注释和操作视频。算法采用CNN-GRU-SAM网络,结合灰狼优化(GWO),通过卷积层提取局部特征、GRU处理长期依赖、自注意力机制捕捉全局特征,最终实现复杂非线性时间序列的高效预测。
|
23天前
|
传感器 安全 算法
消防救援支队消防员单兵装备智能养护舱电机驱动java版程序(二)
本文探讨消防救援中智能养护舱电机驱动的Java程序设计,作为系列文章第二部分。通过自动化和智能化手段,智能养护舱提升了装备维护效率与准确性。文章详细介绍了电机驱动模块的设计与实现,包括硬件选型、PID控制策略、安全保护机制及Java程序架构,确保电机精确控制、稳定性和安全性。未来将优化功能并引入智能算法和物联网技术,进一步提升装备维护智能化水平。
|
23天前
|
IDE Java 开发工具
消防救援支队消防员单兵装备智能养护舱点击驱动java版程序(一)
智能消防作战服架通过电机驱动系统提升消防员作业效率和安全性。本文介绍基于Java的电机驱动程序开发,涵盖硬件准备、软件环境搭建及驱动程序实现。重点包括串口通信配置、电机控制类设计与控制逻辑实现,确保电机高效稳定运行。通过正确配置通信协议和串口参数,并添加异常处理机制,保障系统的安全性和可靠性。

热门文章

最新文章