建筑工地的水泥分配和料场选址问题(Cplex求解线性规划模型+粒子群搜索算法)【Java实现】

news2024/10/6 20:28:20

问题

在这里插入图片描述

问题一求解

求解思路

该问题可以直接建立一个线性规划模型,然后使用cplex求解器来求解

模型

决策变量

x i j :第 i 个料场向第 j 个工地运送的水泥吨数,其中 1 ≪ i ≪ m ; 1 ≪ j ≪ n 其中 x i j 的取值范围是 [ 0 , d j ] ,即供给工地的吨数要小于等于工地的需求量 x_{ij}:第i个料场向第j个工地运送的水泥吨数,其中1\ll i\ll m; 1\ll j\ll n \\ 其中x_{ij}的取值范围是[0,d_j],即供给工地的吨数要小于等于工地的需求量 xij:第i个料场向第j个工地运送的水泥吨数,其中1im1jn其中xij的取值范围是[0,dj],即供给工地的吨数要小于等于工地的需求量

目标函数

o b j : m i n   z = x i j p i j    ∀ i , j 其中 p i j 指的是第 i 个料场到第 j 个工地之间的距离 obj: min\ z=x_{ij}p_{ij}\ \ \forall i,j \\ 其中p_{ij}指的是第i个料场到第j个工地之间的距离 obj:min z=xijpij  i,j其中pij指的是第i个料场到第j个工地之间的距离

约束

约束 1 :任意料场运出的水泥总量不能超出日储量 ∑ j = 1 n x i j ≪ 20    ∀ i 约束 2 :每个工地收到的水泥量等于自己的需求量 ∑ i = 1 m x i j = d j    ∀ j 约束1:任意料场运出的水泥总量不能超出日储量\\ \sum_{j=1}^n{x_{ij}\ll 20\ \ \forall i}\\ 约束2:每个工地收到的水泥量等于自己的需求量\\ \sum_{i=1}^m{x_{ij}=d_j\ \ \forall j} 约束1:任意料场运出的水泥总量不能超出日储量j=1nxij20  i约束2:每个工地收到的水泥量等于自己的需求量i=1mxij=dj  j

代码实现

【存储结果的类】

package com.dam.intelligentWorkshopTrain.supply_of_raw_materials;

import lombok.Data;

/**
 * @Author dam
 * @create 2023/8/15 20:32
 */
@Data
public class Solution {
    /**
     * 目标函数值
     */
    private double objectValue;
    /**
     * 料场i 向 料场j 运输的吨数
     */
    private double[][] xArr;
}

【问题一模型求解主类】

package com.dam.intelligentWorkshopTrain.supply_of_raw_materials;

import ilog.concert.*;
import ilog.cplex.IloCplex;

/**
 * @Author dam
 * @create 2023/8/15 17:29
 */
public class Question1 {

    public static void main(String[] args) throws IloException {
         声明变量
        // 各个工地的坐标位置
        double[][] constructionSitePositionArr = {
                {1.25, 1.25},
                {8.75, 0.75},
                {0.5, 4.75},
                {5.75, 5},
                {3, 6.5},
                {7.25, 7.75}
        };
        // 各个工地的需求量
        double[] demandArr = {3, 5, 4, 7, 6, 11};
        // 各个料场的坐标位置
        double[][] materialYardPositionArr = {
                {5, 1},
                {2, 7}
        };
        // 每个料场的水泥储量
        double[] totalArr = {20, 20};

        IloCplex cplex = new IloCplex();
        Solution solution = cplexSolve(cplex, constructionSitePositionArr, demandArr, materialYardPositionArr, totalArr);
        // 问题求解完成,释放cplex资源
        cplex.end();

        System.out.println("目标函数:" + solution.getObjectValue());
        for (int j = 0; j < solution.getXArr()[0].length; j++) {
            for (int i = 0; i < solution.getXArr().length; i++) {
                double value = solution.getXArr()[i][j];
                if (value > 0) {
                    System.out.println("料场" + (i + 1) + "分配给工地" + (j + 1) + "的吨数是:" + value);
                }
            }
        }
    }

    /**
     * cplex求解模型
     *
     * @param constructionSitePositionArr
     * @param demandArr
     * @param materialYardPositionArr
     * @param totalArr
     * @return
     * @throws IloException
     */
    public static Solution cplexSolve(IloCplex cplex, double[][] constructionSitePositionArr, double[] demandArr, double[][] materialYardPositionArr, double[] totalArr) throws IloException {
        // 存储求解结果
        Solution solution = new Solution();

         建立模型
        /// 决策变量
        // 料场i 向 料场j 运输的吨数
        IloNumVar[][] xArr = new IloNumVar[materialYardPositionArr.length][constructionSitePositionArr.length];
        for (int i = 0; i < xArr.length; i++) {
            for (int j = 0; j < xArr[0].length; j++) {
                // 最大不超过需求量
                xArr[i][j] = cplex.numVar(0, demandArr[j]);
            }
        }

        /// 添加目标函数:最小化运输费用,即最小化吨千米数
        IloLinearNumExpr iloLinearNumExpr = cplex.linearNumExpr();
        for (int i = 0; i < xArr.length; i++) {
            for (int j = 0; j < xArr[0].length; j++) {
                iloLinearNumExpr.addTerm(Question1.getDistance(materialYardPositionArr[i], constructionSitePositionArr[j]), xArr[i][j]);
            }
        }
        cplex.addMinimize(iloLinearNumExpr);

        /// 添加约束
        // 约束1:每个工地收到的量等于自己的需求量
        for (int j = 0; j < demandArr.length; j++) {
            IloLinearNumExpr iloNumExpr = cplex.linearNumExpr();
            for (int i = 0; i < materialYardPositionArr.length; i++) {
                iloNumExpr.addTerm(xArr[i][j], 1);
            }
            cplex.addEq(iloNumExpr, demandArr[j]);
        }
        // 约束2:每个料场给工地所提供的水泥总量小于等于料场总量
        for (int i = 0; i < totalArr.length; i++) {
            IloLinearNumExpr iloNumExpr = cplex.linearNumExpr();
            for (int j = 0; j < constructionSitePositionArr.length; j++) {
                iloNumExpr.addTerm(xArr[i][j], 1);
            }
            cplex.addLe(iloNumExpr, totalArr[i]);
        }

        /// 模型求解
        // 让cplex不要输出一些奇怪的东西,可以注释掉来看看效果
        cplex.setOut(null);
        if (cplex.solve()) {
            solution.setObjectValue(cplex.getObjValue());
            solution.setXArr(new double[xArr.length][xArr[0].length]);
            for (int j = 0; j < xArr[0].length; j++) {
                for (int i = 0; i < xArr.length; i++) {
                    double value = cplex.getValue(xArr[i][j]);
                    solution.getXArr()[i][j] = value;
                }
            }
        }
        // 清除模型,方便重复使用同一个cplex
        cplex.clearModel();
        return solution;
    }

    /**
     * 获取两个位置之间的距离
     *
     * @param position1
     * @param position2
     * @return
     */
    private static double getDistance(double[] position1, double[] position2) {
        return Math.sqrt(Math.pow(position1[0] - position2[0], 2) + Math.pow(position1[1] - position2[1], 2));
    }

}

【运行结果】

目标函数:136.22751988318154
料场1分配给工地1的吨数是:3.0
料场1分配给工地2的吨数是:5.0
料场2分配给工地3的吨数是:4.0
料场1分配给工地4的吨数是:7.0
料场2分配给工地5的吨数是:6.0
料场1分配给工地6的吨数是:1.0
料场2分配给工地6的吨数是:10.0

Process finished with exit code 0

问题二求解

求解思路

如果直接使用建模的方式来求解,可以将两个料场的位置定为决策变量,即只需要修改上面的目标函数并增加决策变量,但是这样子建立的模型是非线性的,使用cplex无法求解,不过当然是可以使用其他工具来求解的,比如Matlab。

我这里是使用java语言来实现的,因此可以换一种方法来求解该问题,比如结合粒子群算法和上面的线性规划模型来求解。线性规划模型的作用是:给定料场的位置,可以求得料场给每个工地的供给量和总的目标函数值。而粒子群算法可以用来搜索料场的位置,将料场的位置定义为每个粒子的位置即可,在搜索的过程中,粒子每到一个新的位置,就可以调用模型来求解获得目标函数值,以此可以判断粒子的好坏。

代码实现

【克隆工具类】

因为在搜索的过程中,需要不断记录最优的料场位置,而本文的料场位置是使用二维数组来记录的(当然也可以使用一维数组,一维数组的代码实现更加方便,但是我个人觉得二维数组可以更好地理解),二维数组的clone方法不能直接使用,因此需要自己实现一个克隆的方法

package com.dam.intelligentWorkshopTrain.supply_of_raw_materials.question2;

/**
 * 克隆工具类
 * @Author dam
 * @create 2023/8/16 10:10
 */
public class CloneUtil {
    /**
     * 二维数组克隆
     * @param oldArr
     * @return
     */
    public static double[][] twoDArrClone(double[][] oldArr) {
        double[][] newArr = new double[oldArr.length][oldArr[0].length];
        for (int i = 0; i < oldArr.length; i++) {
            newArr[i] = oldArr[i].clone();
        }
        return newArr;
    }
}

【粒子类】

每一个粒子需要保存一些个体信息,比如粒子当前所在位置、粒子速度、粒子曾经遍历到的历史最优解及其所在位置

初始化粒子的时候,需要设置粒子的位置,我这里直接让粒子随机在布局中的一个位置,这样可以让粒子群的粒子更加分散,找到质量较高的结果的概率更高

package com.dam.intelligentWorkshopTrain.supply_of_raw_materials.question2;

import lombok.Data;

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

/**
 * 粒子类
 *
 * @Author dam
 * @create 2023/8/15 20:40
 */
@Data
public class Particle {

    /**
     * 例子当前位置,即料场的位置
     */
    private double[][] materialYardPositionArr;
    /**
     * x轴方向上的速度
     */
    private double[] xVArr;
    /**
     * y轴方向上的速度
     */
    private double[] yVArr;
    /**
     * 该粒子找到的历史最优解
     */
    private double pBest;
    /**
     * 该粒子找到的历史最优解对应的位置
     */
    private double[][] bestMaterialYardPositionArr;

    public Particle(double xMin, double xMax, double yMin, double yMax, double xV, double yV, int materialYardNum, Random random) {
        this.xVArr = new double[materialYardNum];
        Arrays.fill(this.xVArr, xV);
        this.yVArr = new double[materialYardNum];
        Arrays.fill(this.yVArr, yV);

        // 初始化粒子信息,即初始化位置
        this.materialYardPositionArr = new double[materialYardNum][2];
        for (int i = 0; i < materialYardNum; i++) {
            this.materialYardPositionArr[i][0] = random.nextDouble() * (xMax - xMin) + xMin;
            this.materialYardPositionArr[i][1] = random.nextDouble() * (yMax - yMin) + yMin;
        }
    }


    /**
     * 设置最优解
     */
    public void setBest(double[][] materialYardPositionArr) {
        this.bestMaterialYardPositionArr = CloneUtil.twoDArrClone(materialYardPositionArr);
    }

}

【粒子群算法类】

该类为粒子群算法类,主要用来初始化粒子群,不断迭代来控制粒子的速度变化及位置变化,在迭代过程中不断更新所找到的最优解

因为整个搜索过程需要调用多次cplex求解器来求解模型,我这里做了一点小优化,并不是每次求解模型都new一个IloCplex对象出来,而是只new一个,后面反复清空重新使用

package com.dam.intelligentWorkshopTrain.supply_of_raw_materials.question2;


import com.dam.intelligentWorkshopTrain.supply_of_raw_materials.Question1;
import com.dam.intelligentWorkshopTrain.supply_of_raw_materials.Solution;
import ilog.concert.IloException;
import ilog.cplex.IloCplex;

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

/**
 * 非线性模型,无法求解
 *
 * @Author dam
 * @create 2023/8/15 19:59
 */
public class PsoApi {

    /**
     * 粒子数量
     */
    private int particleNum;
    /**
     * 个体学习因子,设置得越大,粒子越容易根据自己的想法飞行,若设置过大,容易跳出局部最优,但收敛较慢
     */
    private double c1;
    /**
     * 社会学习因子,设置得越大,粒子越容易根据群体的想法飞行,若设置过大,容易陷入局部最优,收敛较快
     */
    private double c2;
    /**
     * 速度最大值
     */
    private double vMax;
    /**
     * 速度的惯性权重
     */
    private double w;
    /**
     * 迭代次数
     */
    private int genMax;

    public PsoApi(int particleNum, double c1, double c2, double vMax, double w, int genMax) {
        this.particleNum = particleNum;
        this.c1 = c1;
        this.c2 = c2;
        this.vMax = vMax;
        this.w = w;
        this.genMax = genMax;
    }

    /**
     * 求解
     */
    public void solve(double[][] constructionSitePositionArr, double[] demandArr, double[] totalArr) throws IloException {
         变量声明
        // 存储粒子
        Particle[] particleArr;
        // 所有粒子找到的最优解(由于问题为最小化问题,设置初始最优值为较大的数)
        double globalBest = Double.MAX_VALUE;
        // 群体最优解对应的x和y
        double[][] bestMaterialYardPositionArr = null;
        // 随机数工具
        Random random = new Random();
        // cplex对象
        IloCplex cplex = new IloCplex();
        long start = System.currentTimeMillis();
        int materialYardNum = totalArr.length;

         初始化粒子
        // 根据工地找出最大最小坐标
        double xMin = Double.MAX_VALUE;
        double xMax = -Double.MAX_VALUE;
        double yMin = Double.MAX_VALUE;
        double yMax = -Double.MAX_VALUE;
        for (int i = 0; i < constructionSitePositionArr.length; i++) {
            double curX = constructionSitePositionArr[i][0];
            double curY = constructionSitePositionArr[i][1];
            xMin = Math.min(curX, xMin);
            xMax = Math.max(curX, xMax);
            yMin = Math.min(curY, yMin);
            yMax = Math.max(curY, yMax);
        }
        particleArr = new Particle[this.particleNum];
        for (int i = 0; i < particleArr.length; i++) {
            // 初始化粒子群,注意:这里设置每个粒子的速度一样,读者可以根据自己的喜爱进行设置
            // 初始化粒子的坐标和速度
            particleArr[i] = new Particle(xMin, xMax, yMin, yMax, 0.01, 0.01, materialYardNum, random);
            // 初始化粒子的函数值(粒子还没有开始飞,当前位置肯定是找到过的最优位置啦)
            particleArr[i].setBest(particleArr[i].getMaterialYardPositionArr());
            Solution solution = Question1.cplexSolve(cplex, constructionSitePositionArr, demandArr, particleArr[i].getMaterialYardPositionArr(), totalArr);
            particleArr[i].setPBest(solution.getObjectValue());
            // 由于问题为最小化问题,目标函数越小越好
            if (solution.getObjectValue() < globalBest) {
                bestMaterialYardPositionArr = CloneUtil.twoDArrClone(particleArr[i].getMaterialYardPositionArr());
                globalBest = solution.getObjectValue();
            }
        }

         开始求解
        for (int i = 0; i < this.genMax; i++) {
            // 对每个粒子进行操作
            for (int j = 0; j < this.particleNum; j++) {
                // 更新速度
                updateSpeed(particleArr, bestMaterialYardPositionArr, random, materialYardNum, j);

                // 更新位置
                updatePosition(materialYardNum, xMin, xMax, yMin, yMax, particleArr[j]);

                /// 更新粒子历史最优解和粒子全体最优解
                Solution solution = Question1.cplexSolve(cplex, constructionSitePositionArr, demandArr, particleArr[j].getMaterialYardPositionArr(), totalArr);
                if (solution.getObjectValue() < particleArr[j].getPBest()) {
                    particleArr[j].setBest(particleArr[j].getMaterialYardPositionArr());
                    particleArr[j].setPBest(solution.getObjectValue());
                }
                // 由于问题为最小化问题,目标函数越小越好
                if (solution.getObjectValue() < globalBest) {
                    bestMaterialYardPositionArr = CloneUtil.twoDArrClone(particleArr[j].getMaterialYardPositionArr());
                    globalBest = solution.getObjectValue();
                    System.out.println("当前最优解:" + globalBest);
                    System.out.println("料场最优坐标");
                    for (int w = 0; w < bestMaterialYardPositionArr.length; w++) {
                        System.out.println(Arrays.toString(bestMaterialYardPositionArr[w]));
                    }
                    System.out.println("当前是第" + (i + 1) + "代");
                    System.out.println();
                }
            }
        }

        // 问题求解完成,释放cplex资源
        cplex.end();
        // 输出保留6位小数
        System.out.println("---------------------------结果输出---------------------------");
        System.out.println("最优目标函数值:" + String.format("%.6f", globalBest));
        System.out.println("料场最优坐标");
        for (int i = 0; i < bestMaterialYardPositionArr.length; i++) {
            System.out.println(Arrays.toString(bestMaterialYardPositionArr[i]));
        }
        System.out.println("求解时间:" + (System.currentTimeMillis() - start) + "ms");

    }

    /**
     * 更新例子的位置
     * @param materialYardNum
     * @param xMin
     * @param xMax
     * @param yMin
     * @param yMax
     * @param particleArr
     */
    private void updatePosition(int materialYardNum, double xMin, double xMax, double yMin, double yMax, Particle particleArr) {
        for (int k = 0; k < materialYardNum; k++) {
            //todo 这部分的冗余代码比较多,读者可以想办法优化,比如将xVArr和yVArr合并为一个二维的数组,这样一个遍历就可以解决了
            
            double nextX = particleArr.getMaterialYardPositionArr()[k][0] + particleArr.getXVArr()[k];
            // 处理越界
            if (nextX > xMax) {
                nextX = xMax;
            } else if (nextX < xMin) {
                nextX = xMin;
            }
            particleArr.getMaterialYardPositionArr()[k][0] = nextX;

            double nextY = particleArr.getMaterialYardPositionArr()[k][1] + particleArr.getYVArr()[k];
            // 处理越界
            if (nextY > yMax) {
                nextY = yMax;
            } else if (nextY < yMin) {
                nextY = yMin;
            }
            particleArr.getMaterialYardPositionArr()[k][1] = nextY;
        }
    }

    /**
     * 更新粒子的速度
     * @param particleArr
     * @param bestMaterialYardPositionArr
     * @param random
     * @param materialYardNum
     * @param j
     */
    private void updateSpeed(Particle[] particleArr, double[][] bestMaterialYardPositionArr, Random random, int materialYardNum, int j) {
        for (int k = 0; k < materialYardNum; k++) {
            //todo 这部分的冗余代码比较多,读者可以想办法优化,比如将xVArr和yVArr合并为一个二维的数组,这样一个遍历就可以解决了
            
            // 更新x轴方向上的速度
            particleArr[j].getXVArr()[k] = this.w * particleArr[j].getXVArr()[k]
                    + this.c1 * random.nextDouble() * (particleArr[j].getBestMaterialYardPositionArr()[k][0] - particleArr[j].getMaterialYardPositionArr()[k][0])
                    + this.c2 * random.nextDouble() * (bestMaterialYardPositionArr[k][0] - particleArr[j].getMaterialYardPositionArr()[k][0]);
            // 处理x轴方向速度越界
            if (particleArr[j].getXVArr()[k] > this.vMax) {
                particleArr[j].getXVArr()[k] = this.vMax;
            } else if (particleArr[j].getXVArr()[k] < -this.vMax) {
                particleArr[j].getXVArr()[k] = -this.vMax;
            }

            // 更新y轴方向上的速度
            particleArr[j].getYVArr()[k] = this.w * particleArr[j].getYVArr()[k]
                    + this.c1 * random.nextDouble() * (particleArr[j].getBestMaterialYardPositionArr()[k][1] - particleArr[j].getMaterialYardPositionArr()[k][1])
                    + this.c2 * random.nextDouble() * (bestMaterialYardPositionArr[k][1] - particleArr[j].getMaterialYardPositionArr()[k][1]);
            // 处理y轴方向速度越界
            if (particleArr[j].getYVArr()[k] > this.vMax) {
                particleArr[j].getYVArr()[k] = this.vMax;
            } else if (particleArr[j].getYVArr()[k] < -this.vMax) {
                particleArr[j].getYVArr()[k] = -this.vMax;
            }
        }
    }

}

【主类】

该类主要用来声明数据,给粒子群算法设置参数,最后调用粒子群算法来对问题进行求解

package com.dam.intelligentWorkshopTrain.supply_of_raw_materials.question2;

import ilog.concert.IloException;

/**
 * @Author dam
 * @create 2023/8/15 21:24
 */
public class Question2_PSO {
    public static void main(String[] args) {
         声明变量
        // 各个工地的坐标位置
        double[][] constructionSitePositionArr = {
                {1.25, 1.25},
                {8.75, 0.75},
                {0.5, 4.75},
                {5.75, 5},
                {3, 6.5},
                {7.25, 7.75}
        };
        // 各个工地的需求量
        double[] demandArr = {3, 5, 4, 7, 6, 11};
        // 每个料场的水泥储量
        double[] totalArr = {20, 20};
        
        // 设置粒子群算法的参数
        PsoApi psoApi = new PsoApi(100, 0.05, 0.05, 5, 0.9, 100);
        try {
            // 调用粒子群算法
            psoApi.solve(constructionSitePositionArr, demandArr, totalArr);
        } catch (IloException e) {
            throw new RuntimeException(e);
        }

    }
}

【运行】

当前最优解:88.50017762115978
料场最优坐标
[6.995460835765463, 7.431965294573079]
[2.4232613334428765, 5.420225506839392]
当前是第1代

当前最优解:88.43200001652829
料场最优坐标
[7.003560835765462, 7.4400652945730785]
[2.4313613334428767, 5.428325506839392]
当前是第2代

当前最优解:88.37092613583344
料场最优坐标
[7.010850835765463, 7.447355294573079]
[2.4386513334428765, 5.435615506839392]
当前是第3代

当前最优解:88.31619438714196
料场最优坐标
[7.017411835765462, 7.453916294573078]
[2.4452123334428766, 5.442176506839392]
当前是第4代

当前最优解:88.26712846008976
料场最优坐标
[7.023316735765462, 7.459821194573078]
[2.4511172334428766, 5.448081406839392]
当前是第5代

当前最优解:88.22312716663495
料场最优坐标
[7.028631145765463, 7.465135604573079]
[2.4564316434428766, 5.453395816839392]
当前是第6代

当前最优解:88.1836555959095
料场最优坐标
[7.0334141147654625, 7.469918573573079]
[2.4612146124428764, 5.458178785839392]
当前是第7代

当前最优解:88.14823739455572
料场最优坐标
[7.0377187868654625, 7.474223245673079]
[2.4655192845428764, 5.462483457939392]
当前是第8代

当前最优解:87.87110543103842
料场最优坐标
[7.37221941415926, 7.472158486930282]
[3.744400991411965, 5.193926703167144]
当前是第9代

当前最优解:86.94994195734931
料场最优坐标
[7.1143623064881805, 7.627892453016968]
[3.4019200051871716, 5.430391345444132]
当前是第10代

当前最优解:86.23975720549879
料场最优坐标
[7.324184226794703, 7.663656711228883]
[3.012995154097673, 5.642541692214598]
当前是第11代

当前最优解:86.23745998092613
料场最优坐标
[7.236137326506472, 7.75]
[2.804696509875521, 5.792557866752227]
当前是第13代

当前最优解:85.79420546873902
料场最优坐标
[7.277291908434675, 7.75]
[3.042386487841036, 5.490155588705559]
当前是第13代

当前最优解:85.7401223802724
料场最优坐标
[7.252795182230648, 7.75]
[2.9139246554783913, 5.622177963512921]
当前是第15代

当前最优解:85.71122420252955
料场最优坐标
[7.2226019632563165, 7.75]
[3.2656022819683046, 5.871079972622107]
当前是第19代

当前最优解:85.49458063165437
料场最优坐标
[7.245769701653424, 7.75]
[3.2946251539561096, 5.904325759516212]
当前是第20代

当前最优解:85.4509241798177
料场最优坐标
[7.264671022225204, 7.75]
[3.3014973294756103, 5.749172090266563]
当前是第25代

当前最优解:85.383103191951
料场最优坐标
[7.258010737754079, 7.75]
[3.340243912257952, 5.695326263970876]
当前是第25代

当前最优解:85.37611196230958
料场最优坐标
[7.260859212787864, 7.75]
[3.2305121221006603, 5.668446593189184]
当前是第28代

当前最优解:85.37028591165853
料场最优坐标
[7.2536923453472015, 7.75]
[3.376598914930889, 5.6973535637469315]
当前是第29代

当前最优解:85.32396377315396
料场最优坐标
[7.252168191046689, 7.75]
[3.1676286576076826, 5.760573217144864]
当前是第29代

当前最优解:85.30131868341802
料场最优坐标
[7.249047625903025, 7.75]
[3.20787665106796, 5.760005370791448]
当前是第31代

当前最优解:85.27628292994825
料场最优坐标
[7.250787629818613, 7.75]
[3.263808468189787, 5.679476503001795]
当前是第41代

当前最优解:85.27025155292363
料场最优坐标
[7.249905732152565, 7.75]
[3.268868570723304, 5.679396795227463]
当前是第45代

当前最优解:85.26812668241098
料场最优坐标
[7.250191427294184, 7.75]
[3.2498860087141708, 5.661247085205052]
当前是第57代

当前最优解:85.26657211227986
料场最优坐标
[7.249971762881258, 7.75]
[3.24862404799676, 5.660537597317892]
当前是第71代

当前最优解:85.26646536552198
料场最优坐标
[7.250041161365652, 7.75]
[3.252702374447127, 5.653289733955173]
当前是第90代

当前最优解:85.2662612100008
料场最优坐标
[7.250020608545754, 7.75]
[3.2528207689360498, 5.654146585813984]
当前是第91代

当前最优解:85.26608067383026
料场最优坐标
[7.250002111007846, 7.75]
[3.2529273239760803, 5.654917752486913]
当前是第92---------------------------结果输出---------------------------
最优目标函数值:85.266081
料场最优坐标
[7.250002111007846, 7.75]
[3.2529273239760803, 5.654917752486913]
求解时间:956ms

Process finished with exit code 0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/885620.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

prisma的增删改查

目录 一、单表1.增自增问题2.查询所有信息3.查询以l开头的数据4.查询限定数据5.查询唯一的数据6.分页查询7.改8.删 二、联表1.新增文章2.将文章和用户关联3.查询用户的同时查询用户的文章4.关联查询&#xff08;级联操作&#xff0c;链式调用&#xff09; 一、单表 模型 mode…

腾讯云轻量服务器测评:2核 2G 4M

腾讯云轻量2核2G4M服务器&#xff0c;4M带宽下载速度可达512KB/秒&#xff0c;系统盘为50GB SSD盘&#xff0c;300GB月流量&#xff0c;地域节点可选上海、广州和北京&#xff0c;腾讯云百科分享腾讯云2核2G4M轻量应用服务器配置性能表&#xff1a; 目录 腾讯云轻量2核2G4M服…

Spring MVC 中的常见注解的用法

目录 认识 Spring MVC什么是 Spring MVCMVC 的定义 Spring MVC 注解的运用1. Spring MVC 的连接RequestMapping 注解 2. 获取参数获取单个参数获取多个参数传递对象表单传参后端参数重命名RequestBody 接收 JSON 对象PathVariable 获取 URL 中的参数上传文件 RequestPart获取 C…

最小生成树,Kruskal算法

最小生成树&#xff08;Minimum Spanning Tree&#xff0c;简称 MST&#xff09;是一个连通图的子图&#xff0c;它包含图中的所有节点&#xff0c;并且是一个树&#xff08;无环连通图&#xff09;&#xff0c;同时保证连接所有节点的边的权重之和最小。 在一个带权重的连通图…

R语言实现非等比例风险生存资料分析(1)

#非等比例风险的生存资料分析 ###1 生成模拟数据### library(flexsurv) set.seed(123) # 生成样本数量 n <- 100 # 生成时间数据 time <- sample(1:1000,n,replaceF) # 调整shape和scale参数以控制生存曲线形状 # 生成事件数据&#xff08;假设按比例风险模型&#xff0…

【SpringBoot】中的ApplicationRunner接口 和 CommandLineRunner接口

1. ApplicationRunner接口 用法&#xff1a; 类型&#xff1a; 接口 方法&#xff1a; 只定义了一个run方法 使用场景&#xff1a; springBoot项目启动时&#xff0c;若想在启动之后直接执行某一段代码&#xff0c;就可以用 ApplicationRunner这个接口&#xff0c;并实现接口…

YB2416是支持高电压输入的同步降压电源管理芯片

简介&#xff1a; YB2416是支持高电压输入的同步降压电源管理芯片&#xff0c;在 4~30V 的宽输入电压范围内可实现3A的连续电流输出。通过调节 FB 端口的分压电阻&#xff0c;可以输出1.8V到28V的稳定电压。YB2416具有优秀的恒压/恒流(CC/C)特性。YB2416 采用电流模式的环路控制…

UI自动化测试常见的Exception

一. StaleElementReferenceException&#xff1a; - 原因&#xff1a;引用的元素已过期。原因是页面刷新了&#xff0c;此时当然找不到之前页面的元素。- 解决方案&#xff1a;不确定什么时候元素就会被刷新。页面刷新后重新获取元素的思路不变&#xff0c;这时可以使用python的…

【云原生】【k8s】从小白到大神之路之学习运维第82天-------基于Prometheus监控Kubernetes集群

第四阶段 时 间&#xff1a;2023年8月17日 参加人&#xff1a;全班人员 内 容&#xff1a; 基于Prometheus监控Kubernetes集群 目录 一、Prometheus简介 &#xff08;一&#xff09;Prometheus的基本原理 &#xff08;二&#xff09;Prometheus优势 &#xff08;三&a…

java.security.InvalidKeyException: Illegal key size

JDK受版本安全限制&#xff0c;默认只允许128位长度以内的。秘钥长度&#xff0c;如果密钥大于128, 会抛出java.security.InvalidKeyException: Illegal key size 异常. java运行时环境默认读到的是受限的policy文件. 文件位于${java_home}/jre/lib/security, 这种限制是因为美…

【IMX6ULL驱动开发学习】06.DHT11温湿度传感器驱动程序编写与测试

一、DHT11简介 DHT11是一款可测量温度和湿度的传感器。比如市面上一些空气加湿器&#xff0c;会测量空气中湿度&#xff0c;再根据测量结果决定是否继续加湿。 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器&#xff0c;具有超小体积、极低功耗的特点…

配置 autofs

配置 autofs 配置 autofs&#xff0c;按照以下要求自动挂载远程用户的家目录&#xff0c;要求如下&#xff1a; host.domain8.rhce.cc ( 172.25.250.250 ) NFS 导出 /rhome 到您的系统。此文件系统包含 为用户 remoteuser1 预配置的主目录 remoteuser1 的主目录是 host.dom…

【快速解决】尝试卸载 Office 时出现错误代码 30029-4,解决office安装报错等问题,解决无法安装office的问题

目录 ​编辑 前言&#xff08;本文可以快速解决你遇到的问题&#xff09; 问题描述 解决无法安装问题的步骤分为以下两个主要阶段&#xff1a; 第一步&#xff1a;卸载现有的 Office 软件 第二步&#xff1a;安装所需的新版 Office 安装步骤如下&#xff1a; 1.启动微信…

看完《孤注一掷》:原来这类人最容易被电信诈骗!

最近&#xff0c;你看了诈骗电影《孤注一掷》吗&#xff1f; “想成功先发疯&#xff0c;不顾一切向钱冲&#xff1b;拼一次富三代&#xff0c;拼命才能不失败&#xff1b;今天睡地板&#xff0c;明天当老板&#xff01;”诈骗工厂里的被骗去打黑工的人们一次次高呼着朗朗上口…

基于Java+SpringBoot+vue前后端分离企业oa管理系统设计实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

【LangChain】P0 LangChain 是什么与准备工作

LangChain 是什么与准备工作 LangChain 是什么&#xff1f;所谓增强数据感知所谓与环境互动 Get Started下载安装 langchain下载安装 openai获取 OpenAI API Key通过名为 openai_api_key 的参数传递密钥 LangChain 是什么&#xff1f; LangChain 是一个利用语言模型开发应用程序…

YOLOv8改进后效果

数据集 自建铁路障碍数据集-包含路障&#xff0c;人等少数标签。其中百分之八十作为训练集&#xff0c;百分之二十作为测试集 第一次部署 版本&#xff1a;YOLOv5 训练50epoch后精度可达0.94 mAP可达0.95.此时未包含任何改进操作 第二次部署 版本&#xff1a;YOLOv8改进版本 首…

“智”创未来,引领信息化新风潮,数字转型再添强动力

如今企业信息化已经成为了现代商业发展的大势所趋。信息化的浪潮不但带来了新的机遇&#xff0c;也对企业提出了更高的要求。企业需要借助科技的力量&#xff0c;实现数字化、智能化、高效化的转型&#xff0c;以应对激烈的市场竞争。 湖南远跃作为国内领先的信息一体化 解决方…

【Linux】进程的基本属性|父子进程关系

个人主页&#xff1a;&#x1f35d;在肯德基吃麻辣烫 我的gitee&#xff1a;Linux仓库 个人专栏&#xff1a;Linux专栏 分享一句喜欢的话&#xff1a;热烈的火焰&#xff0c;冰封在最沉默的火山深处 文章目录 前言进程属性1.进程PID和PPID2.fork函数创建子进程1&#xff09;为什…

炫酷UI前端效果的CSS生成工具

提升设计人员和前端开发人员的工作 推荐炫酷UI前端效果的CSS生成工具1.Neumorphism2.带有渐变的图标3.Interactions4.大型数据库5.动画6.Mask7.动画按钮8. 自定义形状分隔线9.背景图案10. SVG波浪推荐炫酷UI前端效果的CSS生成工具 1.Neumorphism 地址:https://neumorphism.i…