外点惩罚函数法·约束优化问题

外点法惩罚函数(r增加,SUMT.java)用于求解约束优化问题,解题步骤如下:

Step1 输入目标函数与约束方程,构建外点惩罚函数法求解方程,求解初始化。

Step2 对求解方程进行一次无约束优化方法求解(鲍威尔BWE),得到新解。

Step3 新解与原解求误差,如误差满足精度要求,则输出解,否则增加因子r,执行Step 2。

鲍威尔法(BWE.java)是N维无约束求解方法,需要调用一维求解方法,一维求解方法采用黄金分割法(GSM.java)。

在实现算法的代码中,我去掉了输入处理,人为地将输入确定下来,可减少代码篇幅。

我会将文件打包放入我的下载,欢迎大家一起交流。

(1)外点法惩罚函数 SUMT.java:

package ODM.Method;import java.util.Arrays;
/** 无约束优化方法:惩罚函数法·外点法*/
public class SUMT {private int n = 6;                          // 维数,变量个数private final double eps = 1e-5;          // 精度private final double c = 5;               // 递增系数private double r = 0.1;                 // 惩罚因子,趋向无穷public SUMT(){Finit();AlgorithmProcess();AnswerOutput();}// 结果private double[] xs;                       private double ans;private void Finit(){xs = new double[n];Arrays.fill(xs, 0);ans = -1;//xs[0] = xs[1] = xs[2] = xs[4] = 1;   xs[3] = 3; xs[5] = 5;}// 算法主要流程private void AlgorithmProcess(){int icnt = 0;                     // 迭代次数double[] x = new double[n];     // 转化为无约束优化问题的解while(true){icnt++;BWE temp = new BWE(n, r, xs);  // 采用鲍威尔方法求函数最优解x = temp.retAns();if(retOK(x) <= eps){         // 满足精度要求for(int i = 0; i < n; i++)xs[i] = x[i];ans = temp.mAns();break;}r = c * r;for(int i = 0; i < n; i++)xs[i] = x[i];}System.out.println("迭代次数:" + icnt);}// 收敛条件(只有一个,不完善)private double retOK(double[] x){double sum = 0;for(int i = 0; i < n; i++){sum += Math.pow(x[i] - xs[i], 2);}return Math.sqrt(sum);}// 结果输出private void AnswerOutput(){for(int i = 0; i < n; i++)System.out.printf("%.6f\t", xs[i]);System.out.printf("%.6f\n", ans);}public static void main(String[] args) {// TODO Auto-generated method stubnew SUMT();}}

(2)鲍威尔法 BWE.java:

package ODM.Method;import java.util.Arrays;public class BWE {private double r;// 初始化变量private double[] x0;                       // 初始解集private double[][] e;                        // 初始方向private int N;final private double eps = 1e-5;private Func F;// 初始化:初始点, 初始矢量(n 个,n*n 矩阵), 维数private void Init(int n){this.x0 = new double[n];if(r == -1)Arrays.fill(this.x0, 0);else{}this.e = new double[n][n];for(int i = 0; i < n; i++){for(int j = 0; j < n; j++){if(i != j)e[i][j] = 0;else e[i][j] = 1;}}this.N = n;if(r != -1)F = new Func(r);elseF = new Func();}// 搜索点, 方向矢量private double[][] x;private double[][] d;// 方向重排, 队列操作private void queueDir(double[] X){// 删去首方向for(int i = 0; i < N-1; i++){for(int j = 0; j < N; j++){d[i][j] = d[i+1][j];}}// 新方向插入队尾for(int i = 0; i < N; i++)d[N-1][i] = X[i];}private void Process(){x = new double[N+1][N];d = new double[N][N];for(int j = 0; j < N; j++)x[0][j] = x0[j];for(int i = 0; i < N; i++){for(int j = 0; j < N; j++){d[i][j] = e[i][j];}}int k = 0;                          // 迭代次数while(k < N){for(int i = 1; i <= N; i++){GSM t = new GSM(F, x[i-1], d[i-1]);x[i] = t.getOs();}double[] X = new double[N];for(int i = 0; i < N; i++)X[i] = x[N][i] - x[0][i];queueDir(X);GSM t = new GSM(F, x[N], X);x[0] = t.getOs();k++;}}// 答案打印private void AnswerOutput(){for(int i = 0; i < N; i++){System.out.printf("x[%d] = %.6f\n", i+1, x[0][i]);
//          System.out.print(x[0][i] + " ");}System.out.printf("最小值:%.6f\n", F.fGetVal(x[0]));
//      System.out.println(": " + F.fGetVal(x[0]));}public BWE(int n){this.r = -1;Init(n);Process();AnswerOutput();}public BWE(int n, double r, double[] x){this.r = r;Init(n);for(int i = 0; i < n; i++)x0[i] = x[i];Process();}// 返回结果,解向量和最优值public double[] retAns(){return x[0];}public double mAns(){return F.fGetVal(x[0], 0);}/*public static void main(String[] args) {// TODO Auto-generated method stubnew BWE(2);}*/}

(3)黄金分割 GSM.java:

package ODM.Method;
/** 黄金分割法*/
public class GSM {private int N;                                                                // 维度private final double landa = (Math.sqrt(5)-1)/2;                          // 0.618private double[] x1;private double[] x2;private double[] os;private final double eps = 1e-5;                                           // 解精度private ExtM EM;                                                          // 用于获取外推法结果// 最优值输出public double[] getOs() {return os;}// 函数, 初始点, 方向矢量public GSM(Func Sample, double[] x, double[] e) {//for(int i = 0; i < e.length; i++)System.out.print(e[i] + " ");System.out.println();initial(Sample, x, e);process(Sample);AnswerPrint(Sample);}// 结果打印private void AnswerPrint(Func Sample) {os = new double[N];for(int i = 0; i < N; i++)os[i] = 0.5*(x1[i] + x2[i]);//        System.out.println("os = " + os[0] + " " + os[1]);
//      System.out.println("ans = " + Sample.fGetVal(os));}// 向量范值private double FanZhi(double[] b, double[] a){double sum = 0;for(int i = 0; i < N; i++){if(b[i] - a[i] != 0 && b[i] == 0)return eps*(1e10);if(b[i] == 0)continue;sum += Math.pow((b[i] - a[i]) / b[i], 2);}return Math.pow(sum, 0.5);}// 算法主流程private void process(Func Sample) {double[] xx1 = new double[N];SubArraysCopy(xx1);double yy1 = Sample.fGetVal(xx1);double[] xx2 = new double[N];AddArraysCopy(xx2);double yy2 = Sample.fGetVal(xx2);// 迭代过程while(true){if(yy1 >= yy2){ArraysCopy(xx1, x1);ArraysCopy(xx2, xx1);  yy1 = yy2;AddArraysCopy(xx2);yy2 = Sample.fGetVal(xx2);}else{ArraysCopy(xx2, x2);ArraysCopy(xx1, xx2);    yy2 = yy1;SubArraysCopy(xx1);yy1 = Sample.fGetVal(xx1);}//System.out.println(FanZhi(x2, x1) + " / " + Math.abs((yy2 - yy1)/yy2));if(FanZhi(x2, x1) < eps && Math.abs(yy2 - yy1) < eps)break;}}// 获得外推法结果:左右边界private void initial(Func Sample, double[] x, double[] e) {N = x.length;EM = new ExtM(Sample, x, e);x1 = EM.getX1();x2 = EM.getX3();}// 向量赋值private void ArraysCopy(double[] s, double[] e){for(int i = 0; i < N; i++)e[i] = s[i];}// + landaprivate void AddArraysCopy(double[] arr){for(int i = 0; i < N; i++)arr[i] = x1[i] + landa*(x2[i] - x1[i]);}// - landaprivate void SubArraysCopy(double[] arr){for(int i = 0; i < N; i++)arr[i] = x2[i] - landa*(x2[i] - x1[i]);}/*public static void main(String[] args) {// TODO Auto-generated method stubdouble[] C = {0, 0};double[] d = {1, 0};new GSM(new Func(), C, d);}*/
}

以上算法文件包含函数方程,黄金分割时有一维搜索的外推法确定“高低高”区间。

函数方程 Func.java,外推法 ExtM.java。

Func.java:

package ODM.Method;public class Func {private int N;                             // N 维private double[] left;                        // 函数左边界private double[] right;                 // 函数右边界private double r;public Func() {r = -1;}public Func(double r) {this.r = r;}// 定义函数与函数值返回public double fGetVal(double[] x){if(r != -1)return fGetVal(x, r);// 10*(x1+x2-5)^2 + (x1-x2)^2return 10*Math.pow(x[0]+x[1]-5, 2) + Math.pow(x[0]-x[1], 2);//}private double max(double a, double b){return a > b ? a : b;}public double fGetVal(double[] x, double r){double ret = 0;
//      function f1
//      ret =  Math.pow(x[0]-5, 2) + 4*Math.pow(x[1]-6, 2)
//              + r * (
//              + Math.pow(max(64-x[0]*x[0]-x[1]*x[1], 0), 2)
//              + Math.pow(max(x[1]-x[0]-10, 0),  0)
//              + Math.pow(max(x[0]-10, 0), 2)
//              );//        function f2
//      ret = x[0]*x[0] + x[1]*x[1] + r*(1-x[0]>0 ? 1-x[0] : 0)*(1-x[0]>0 ? 1-x[0] : 0);//     function f3ret = Math.pow(x[0]-x[3], 2) + Math.pow(x[1]-x[4], 2) + Math.pow(x[2]-x[5], 2) + r * (+ Math.pow(max(x[0]*x[0]+x[1]*x[1]+x[2]*x[2]-5, 0), 2)+ Math.pow(max(Math.pow(x[3]-3, 2)+x[4]*x[4]-1, 0), 2)+ Math.pow(max(x[5]-8, 0), 2) + Math.pow(max(4-x[5], 0), 2));return ret;}
}

ExtM.java:

package ODM.Method;/** 外推法确定“高-低-高”区间*/
public class ExtM {private int N;                           // 函数维数private double[] x1;private double[] x2;private double[] x3;private double y1;private double y2;private double y3;private double h;                      // 步长private double[] d;                    // 方向矢量public double[] getX1() {return x1;}public double[] getX2() {return x2;}public double[] getX3() {return x3;}public double getH() {return h;}// 函数, 初始点,方向public ExtM(Func Sample, double[] x, double[] e) {initial(Sample, x, e);process(Sample);AnswerPrint();}// 初始化阶段private void initial(Func Sample, double[] x, double[] e){N = x.length;x1 = new double[N];x2 = new double[N];x3 = new double[N];h = 0.01;d = new double[N];ArraysCopy(e, 0, d);//for(int i = 0; i < d.length; i++)System.out.print(d[i]);System.out.println();ArraysCopy(x, 0, x1);y1 = Sample.fGetVal(x1);ArraysCopy(x, h, x2);y2 = Sample.fGetVal(x2);}// 循环部分private void process(Func Sample){if(y2 > y1){h = -h;ArraysCopy(x1, 0, x3);y3 = y1;}else{ArraysCopy(x2, h, x3);    y3 = Sample.fGetVal(x3);}while(y3 < y2){h = 2*h;
//          System.out.println("h = " + h);ArraysCopy(x2, 0, x1);       y1 = y2;ArraysCopy(x3, 0, x2);     y2 = y3;ArraysCopy(x2, h, x3);     y3 = Sample.fGetVal(x3);
//          System.out.println("x1 = " + x1[0] + " " + x1[1] + " y1 = " + y1);
//          System.out.println("x2 = " + x2[0] + " " + x2[1] + " y2 = " + y2);
//          System.out.println("x3 = " + x3[0] + " " + x3[1] + " y3 = " + y3);}}// 打印算法结果private void AnswerPrint(){
//      System.out.println("x1 = " + x1[0] + " " + x1[1] + " y1 = " + y1);
//      System.out.println("x2 = " + x2[0] + " " + x2[1] + " y2 = " + y2);
//      System.out.println("x3 = " + x3[0] + " " + x3[1] + " y3 = " + y3);}// 向量转移private void ArraysCopy(double[] s, double c, double[] e){for(int i = 0; i < s.length; i++)e[i] = d[i]*c + s[i];}/*public static void main(String[] args) {// TODO Auto-generated method stub// new ExtM();}*/}

外点惩罚函数法·约束优化问题相关推荐

  1. matlab 约束函数,【优化求解】MATLAB约束优化之惩罚函数法

    一.算法原理 之前我们了解过的算法大部分都是无约束优化问题,其算法有:黄金分割法,牛顿法,拟牛顿法,共轭梯度法,单纯性法等.但在实际工程问题中,大多数优化问题都属于有约束优化问题.惩罚函数法就可以将约 ...

  2. 最优化课程笔记07——约束问题的非线性规划方法(重点:拉格朗日乘子法和惩罚函数法)

    7.1 间接法:约束转化为无约束问题(含一个重点:拉格朗日乘子法) 当维数多的时候不适用 7.1.2拉格朗日乘子法(重点) 7.1.2.1 等式约束问题 7.1.2.2 不等式约束问题 7.1.3 惩 ...

  3. 惩罚函数内点法c语言,分享:惩罚函数法(内点法、外点法)求解约束优化问题最优值...

    方法一:外点牛顿法: clc m=zeros(1,50);a=zeros(1,50);b=zeros(1,50);f0=zeros(1,50);%a b为最优点坐标,f0为最优点函数值,f1 f2最优 ...

  4. 模拟退火算法(惩罚函数法求约束优化问题)

    构造惩罚函数: p1 = (max(0, 4642 - X[0] - X[1] - X[2] - X[3] - X[4] - X[5] - X[6] - X[7] - X[8] - X[9])) ** ...

  5. 内点惩罚函数法matlab_拉格朗日乘数法求解多元条件极值问题

    点击蓝字,关注废柴姐姐 拉格朗日乘数法 " 一种不直接依赖消元法而求解条件极值问题的有效方法 二元函数入手 我们从  皆为二元函数这一简单情况人手. 欲求函数 的极值,其中受条件 的限制. ...

  6. matlab外罚函数实验报告,外罚函数法matlab

    罚函数法 37页 1下载券 罚函数法 11页 1下载券 罚函数法MATLAB程序 5页 2下载券 1120 罚函数法 (罚函数法... 52页 1下载券 ...... c Ax ? b . 3 算法的 ...

  7. 乘子法罚函数法matlab实例,罚函数法(罚函数法与乘子法合订).ppt

    罚函数法(罚函数法与乘子法合订) 收敛性定理 5 算法评价(优缺点) 二.内点罚函数法(碰壁函数法)-内点法 2 罚函数的特点 3. 算法实现 收敛性定理 构造新的辅助函数 2. 算法实现 乘子法是由 ...

  8. matlab优化设计大作业答案,优化设计有哪些方法(2019优化设计答案大全)

    本书主要介绍机械优化设计方法与实例,全书共有9章,内容主要包括机械优化设计的基本要素及数学模型.优化设计的理论基础.常见的优化设计方法和优化设计软件简介.书中对工程中常见的六大类优化设计方法--一维搜 ...

  9. 机械优化设计——专栏介绍(作者:TDTX)

    机械优化设计--专栏介绍(作者:TDTX) 一.优化设计数学基础 二.一维搜索方法 三.无约束优化方法 四.线性规划 五.约束优化方法 参考文献(学习教材) [注A]机械优化设计对应机械类专业来说是一 ...

  10. 单目标模糊优化设计matlab程序,优化设计有哪些方法

    本书主要介绍机械优化设计方法与实例,全书共有9章,内容主要包括机械优化设计的基本要素及数学模型.优化设计的理论基础.常见的优化设计方法和优化设计软件简介.书中对工程中常见的六大类优化设计方法--一维搜 ...

最新文章

  1. 【Linux】Linux简单操作之管道与重定向
  2. 经典DP 嵌套矩形 (南洋理工ACM—16)
  3. 2018.2.11-12 写作业
  4. Containerd 的前世今生和保姆级入门教程
  5. 关于数据库内“表”的几点
  6. 下一代微服务!ServiceMesh的2018年度总结 | 万字雄文
  7. 使用phpmaill发送邮件的例子
  8. 多GPU运行Deep Learning 和 并行Deep Learning(待续)
  9. PHP 长连接,奏是这么简单
  10. WordPress 安装插件导致 HTTP 500 内部服务器错误的问题
  11. [Linux] 头文件加载顺序
  12. gsp 页面 html.dat,Gsp
  13. 数据分析这么做,销售看了拍手叫好
  14. 9、网友问答----有关清零问题------------------labview宝典
  15. Python 函数的定义与调用
  16. 在前端的js中设置按钮的可见与不可见
  17. java对七牛云文件的增删改查语句_七牛云导播
  18. 关于windows10系统连接隐藏网络时,显示无法连接问题的解决方式
  19. matlab 积分函数曲线,matlab积分函数
  20. AutoCAD 04,07,08,11,14,16,18不同版本的选择建议

热门文章

  1. 数据结构之二叉平衡树
  2. 2022依旧可用的抖音无水印解析工具,免费分享
  3. python 网盘多帐号_教你怎么拥有(很多)百度网盘2T账号
  4. 区县级应急综合管理系统功能
  5. fgo服务器维护补偿,FGO1月23日服务器故障说明公告 全服补偿24圣晶石
  6. http-server 简介
  7. 计算机专业毕业论文写作指导(案例超详解)
  8. 上海瀚示中文显示电子拣货标签 智能仓储物流工匠级革新
  9. 韩立刚计算机网络——第五章:传输层
  10. js 跨域下载链接 下载文件 实现重命名,文件名称 兼容处理