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

版权声明:本文为博主原创文章,未经博主同意不得转载,博客主页 http://blog.csdn.net/i_love_home https://blog.csdn.net/zstu_wangrui/article/details/36242529

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

       外点法惩处函数(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 f3 ret = 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();}*/}


转载于:https://www.cnblogs.com/ldxsuanfa/p/10761431.html

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

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

相关文章

在单元测试和TDD中指定时间的重要性

最近&#xff0c;我一直在写与自动测试有关的更高级的概念&#xff08;主要与Spock有关&#xff09;。 但是&#xff0c;在进行测试培训时&#xff0c;我清楚地看到&#xff0c;通常对特定工具的知识并不是主要问题。 即使使用Spock&#xff0c;也可以编写肿且难以维护的测试&a…

40个Java多线程问题总结

前言 Java多线程分类中写了21篇多线程的文章&#xff0c;21篇文章的内容很多&#xff0c;个人认为&#xff0c;学习&#xff0c;内容越多、越杂的知识&#xff0c;越需要进行深刻的总结&#xff0c;这样才能记忆深刻&#xff0c;将知识变成自己的。这篇文章主要是对多线程的问题…

.pro.user文件

.pro.user 用于记录打开工程的路径&#xff0c;所用的编译器、构建的工具链、生成目录、打开工程的qt-creator的版本等。 当更换编译环境时&#xff0c;要将其删除。

python tkinter实例_python绘制一个图形示例源码(tkinter)

【实例简介】 【实例截图】【核心代码】 # -*- coding: utf-8 -*- #!/usr/bin/python import math from tkinter import * class PTS: def __init__(self): self.x 0 self.y 0 points [] def LineToDemo(): screenx 400 screeny 400 canvas Canvas(width screenx,height…

PHP算法之冒泡排序

//冒泡排序 //①思路,先比较出第一次,找一个最大的值,排到最后; //②重复count遍之后,就能得到排序; //③优化,每一次循环之后不需要再次全部重复; $array [11,5,4,58,1,222,34]; for ($j 0; $j< count($array)-1; $j) { for($i 0 ; $i < count($array)-$j-1; $i){if(…

jaxb 命名空间_在JAXB解组期间应用名称空间

jaxb 命名空间对于某些XML模式来说&#xff0c;它是一组严格的规则&#xff0c;用于规定XML文档的结构方式。 但是对于其他人来说&#xff0c;通常的准则是指出XML的外观。 这意味着有时出于某些原因&#xff0c;人们希望接受不符合XML模式的输入。 在此示例中&#xff0c;我将…

pro文件

配置 注释 以“#”开始&#xff0c;到这一行结束。 快捷键&#xff1a;Ctrl / CONFIG 指定编译器选项和项目配置&#xff0c;值由qmake内部识别并具有特殊意义。 以下配置值控制编译标志&#xff1a; 选项说明release项目以release模式构建。如果也指定了debug&#xff0c;那么…

Java Thread 总结

线程的概述&#xff08;Introduction&#xff09; 线程是一个程序的多个执行路径&#xff0c;执行调度的单位&#xff0c;依托于进程存在。 线程不仅可以共享进程的内存&#xff0c;而且还拥有一个属于自己的内存空间&#xff0c;这段内存空间也叫做线程栈&#xff0c;是在建立…

前端和后端哪个工资高_新媒体运营和网络运维哪个好,哪个工资待遇高,门槛低?...

文/水流云在草青青通常情况下&#xff0c;门槛高低和待遇高低成反比。工资待遇和工作本领成正比。除非你有人脉或贵人&#xff0c;除非你踩狗屎运。门槛低&#xff0c;待遇高的工作对绝大多数人而言是梦话。不知题主朋友的特长是什么&#xff1f;有哪些工作经验&#xff1f;青青…

python框架源码学习

最近下了一个别人的接口测试框架原码来学习 1.有用到logbook模块进行日志管理 2.使用xlrd模块对excel数据表的操作 3.使用自定义的代码输出测试报告 4.使用logger模块记录运行时日志 主要是看了关于接口的代码&#xff1a;封装了http请求的get/post请求 用法&#xff1a; 需要导…

使用TestContainers进行数据库测试

如果您曾经编写过测试数据库交互的代码&#xff0c;例如数据访问对象&#xff0c;那么您很可能遇到了测试中最长期的烦恼之一&#xff1a;为了准确地测试这些交互&#xff0c;需要一个数据库。 为了本文的方便&#xff0c;让我们考虑一个将PostgreSQL用作其环境的一部分的应用…

cuda安装配置VS2013

1.1 安装cuda 首先官网下载安装包&#xff0c;这个就不细说了 &#xff0c;我下的是这个版本cuda_8.0.61_win10.exe&#xff0c;&#xff0c;注意win7和win10版本要对应&#xff0c;千万别弄错了 之后双击会出现如下截图&#xff0c;解压完以后一直点下一步如下图出现这个等半个…

两列布局、三列适应布局、两列等高适应布局。

一. 两列布局&#xff1a;左侧定宽、右侧自适应。 四种方法 &#xff1a;flex 、position、float和负外边距、外边距 1. 使用flex. <!DOCTYPE html> <html> <head><meta charset"utf-8"><title></title><style type"tex…

操作系统的线程和进程的区别_面试官:你熟悉多线程嘛?线程跟进程有什么区别?...

这篇文章跟大家聊聊线程&#xff0c;讲到线程&#xff0c;⼜不得不提进程了~进程我们估计是很了解的了&#xff0c;在windows下打开任务管理器&#xff0c;可以发现我们在操作系统上运⾏的程序都是进程。什么是叫一个进程&#xff1f; 什么叫一个线程&#xff1f;进程&#xff…

以OpenCV为例配置VS第三方库

正常情况下&#xff0c;你拿到的别人的第三方动态库&#xff08;静态库调用方式这里不讲&#xff0c;有另外一篇文章&#xff09;至少应该包含下面三种文件&#xff1a; 1. 头文件&#xff0c;这个一般放在include这样字眼的文件夹下&#xff0c;比如OpenCV的&#xff1a;然后i…

光纤接口怎么接 图解_光纤的数据比网线快很多倍,但为什么没有在家庭局域网中普及呢?...

光纤的数据吞吐量比网线大很多&#xff0c;速度也更快&#xff0c;网络光纤入户已经普及&#xff0c;但是家庭内组网却没有普及&#xff0c;大部分家庭组网还是网线较多。分析起来主要的原因有&#xff1a;光纤线的价格和网线差不多&#xff0c;但是因为光纤所使用的专用的光接…

项目Alpha冲刺--1/10

项目Alpha冲刺--1/10作业要求 这个作业属于哪个课程软件工程1916-W(福州大学)这个作业要求在哪里项目Alpha冲刺团队名称基于云的胜利冲锋队项目名称云评&#xff1a;高校学生成绩综合评估及可视化分析平台这个作业的目标团队的代码规范、本次冲刺任务与计划其他参考文献1.邹欣.…

Java连接postgresql数据库

1.下载驱动jar 下载地址&#xff1a;https://jdbc.postgresql.org/download.html 2.导入jar包 新建lib文件夹&#xff0c;将下载的jar驱动包拖到文件夹中。 将jar驱动包添加到Libraries 3.程序代码如下&#xff1a;HelloWorld.java package test; import java.sql.Connecti…

jvm默认的初始化参数_您是否应该信任JVM中的默认设置?

jvm默认的初始化参数如今&#xff0c;JVM被认为是智能的。 预期配置不多-只需设置要在启动脚本中使用的最大堆&#xff0c;您就可以进行了。 所有其他默认设置都很好。 大概我们当中有些人误以为。 实际上&#xff0c;在运行时期间发生了很多事情&#xff0c;无法自动调整性能&…

setGeometry

setGeometry (9,9, 50, 25) 从屏幕上&#xff08;9&#xff0c;9&#xff09;位置开始&#xff08;即为最左上角的点&#xff09;&#xff0c;显示一个50*25的界面&#xff08;宽50&#xff0c;高25&#xff09; 如果在控件中加上了layout布局&#xff0c;就会发现发现没有办法…