修正单纯形法·优化算法实现·Java

修正单纯性法

代码如下:

舍去了输入转化的内容,主要包含算法关键步骤。

public class LPSimplexM {

	private static final double inf = 1e9;

	private int n;							// 约束个数
	private double[][] A;					// 输入函数参数
	private double[] b;					// 约束值
	private double[] c;					// 目标函数系数
	private double Z;						// 目标值
	private void InitF() {					// 初始化 First
		/* problem 1.
		 * max Z = 5*x1 + 4*x2;			  min Z = -5*x1 - 4*x2;
		 * x1   + 3*x2 <= 90;				x1 + 3*x2 +  x3				= 90;
		 * 2*x1 + x2   <= 80;		=>	  2*x1 +   x2 	    + x4		= 80;
		 * x1   + x2   <= 45;				x1 +   x2   		  + x5 	= 45;
		 * xi >= 0
		 */
		/* problem 2.
		 * min Z = -7*x1 - 12*x2;
		 * 9*x1 + 4*x2  + x3          = 360;
		 * 4*x1 + 5*x2       +x4 	  = 200;
		 * 3*x1 + 10*x2			 + x5 = 300;
		 *   xi >= 0
		 */
		n = 3;
		A = new double[n+1][n+1];
		b = new double[n+1];
//		c = new double[n<<1];
		Z = inf;
		// 约束初始条件
		A[1][1] = 1;	A[1][2] = 3;
		A[2][1] = 2;	A[2][2] = 1;
		A[3][1] = 1;	A[3][2] = 1;
		// 条件值
		// problem 1.
//		b[1] = 90;
//		b[2] = 80;
//		b[3] = 45;
		// problem 2.
		b[1] = 360;
		b[2] = 200;
		b[3] = 300;
//		for(int i = 1; i <= n; i++)System.out.println("b[" + i + "] = " + b[i]);
		// 目标函数系数
//		c[1] = -5;	c[2] = -4;
	}

	int m;
	private double[][] p;
	private double[][] e, oe;
	private double[][] E, oE;
	private double[] X;
	private boolean[] G;
	private int[] S;
	private void InitS() {
		m = 2;
		p = new double[n+1][n+m+1];
		e = new double[n+1][n+1];
		oe = new double[n+1][n+1];
		E = new double[n+1][n+1];
		oE = new double[n+1][n+1];
		X = new double[n+1];
		G = new boolean[n+m+1];
		S = new int[n+1];

		c = new double[n+m+1];
		// problem 1.
//		c[1] = -5;	c[2] = -4;	c[3] = 0;	c[4] = 0;	c[5] = 0;
		// problem 2.
		c[1] = -7;	c[2] = -12;	c[3] = 0;	c[4] = 0;	c[5] = 0;
		// problem 1.
//		p[1][1] = 1;	p[1][2] = 3;	p[1][3] = 1;	p[1][4] = 0;	p[1][5] = 0;
//		p[2][1] = 2;	p[2][2] = 1;	p[2][3] = 0;	p[2][4] = 1;	p[2][5] = 0;
//		p[3][1] = 1;	p[3][2] = 1;	p[3][3] = 0;	p[3][4] = 0;	p[3][5] = 1;
		// problem 2.
		p[1][1] = 9;	p[1][2] = 4;	p[1][3] = 1;	p[1][4] = 0;	p[1][5] = 0;
		p[2][1] = 4;	p[2][2] = 5;	p[2][3] = 0;	p[2][4] = 1;	p[2][5] = 0;
		p[3][1] = 3;	p[3][2] = 10;	p[3][3] = 0;	p[3][4] = 0;	p[3][5] = 1;

		for(int i = 1; i <= n; i++)
			for(int j = 1; j <= n; j++)
				if(i == j)E[i][j] = oE[i][j] = 1;
				else E[i][j] = oE[i][j] = 0;

		for(int i = 1; i <= n; i++)
			X[i] = b[i];

		G[1] = false;	G[2] = false;	G[3] = true;	G[4] = true;	G[5] = true;

		S[1] = 3;	S[2] = 4;	S[3] = 5;
	}

	public LPSimplexM() {
		InitF();
		InitS();
		AlgorithmProcess();
		solve();
	}

	private void AlgorithmProcess() {
		double[] coE = new double[n+1];	// c * E^-1
		double[] r = new double [n+m+1];	// c - c * E^-1 * p
		double[] oEp = new double[n+1];	// E^-1 * p;
		boolean flag = false;
		while(true) {
			// x = E^-1 * b
			for(int i = 1; i <= n; i++){
				X[i] = 0;
				for(int j = 1; j <= n; j++)
					X[i] += oE[i][j]*b[j];
			}
			// c * E^-1
			for(int i = 1; i <= n; i++){
				coE[i] = 0;
				for(int j = 1; j <= n; j++)
					coE[i] += c[S[j]]*oE[j][i];
			}
			// r = c - c * E^-1 * p     => min r‘ id -> k
			int k = -1;
			flag = false;
			for(int i = 1; i <= n+m; i++)if(!G[i]){
				double ans = 0;
				for(int j = 1; j <= n; j++)
					ans += coE[j]*p[j][i];
				r[i] = c[i] - ans;
				if(!flag && r[i] < 0){
					k = i;
					flag = true;
				}else if(flag && r[i] < r[k]){
					k = i;
				}
			}
			if(k == -1)return ;									// solution output 1(X, S 为最优解)
			// E^-1 * p;				=> min theta>0‘ id -> s
			int s = -1;
			flag = false;
			for(int i = 1; i <= n; i++){
				oEp[i] = 0;
				for(int j = 1; j <= n; j++){
					oEp[i] += oE[i][j]*p[j][k];
				}
				if(oEp[i] > 0){
					if(!flag){
						s = i;
						flag = true;
					}else if(flag && X[i]/oEp[i] < X[s]/oEp[s]){
						s = i;
					}
				}
			}
			if(!flag)return ; 										// no solution 1(无允许解)
			if(s == -1)return ;									// no solution 2(该问题有无解集)
			// p[s] = p[k], 形成新的矢量基 E
			G[S[s]] = false;	G[k] = true;
			S[s] = k;
//			System.out.println("k = " + k + "; s = " + s);
			for(int i = 1; i <= n; i++){
				p[i][k] = -1.0*oEp[i]/oEp[s];
				if(i == s)
					p[i][k] = 1/oEp[s];
			}
			for(int i = 1; i <= n; i++){
				int id = S[i];
				for(int j = 1; j <= n; j++){
					if(i == s){
						e[j][i] = p[j][k];
					}else{
						if(j == i){
							e[j][i] = 1;
						}else{
							e[j][i] = 0;
						}
					}
				}
			}
//			for(int i = 1; i <= n; i++){
//				for(int j = 1; j <= n; j++){
//					System.out.print(oE[i][j] + " ");
//				}System.out.println();
//			}System.out.println("{oE}");
//			for(int i = 1; i <= n; i++){
//				for(int j = 1; j <= n; j++){
//					System.out.print(e[i][j] + " ");
//				}System.out.println();
//			}System.out.println("{e}");
			for(int i = 1; i <= n; i++){
				for(int j = 1; j <= n; j++){
					oe[i][j] = 0;
					for(int t = 1; t <= n; t++){
						oe[i][j] += e[i][t]*oE[t][j];
					}
				}
			}
			for(int i = 1; i <= n; i++){
				for(int j = 1; j <= n; j++){
					oE[i][j] = oe[i][j];
					//System.out.print(oE[i][j] + " ");
				}//System.out.println();
			}//System.out.println();
		}
	}
	// 最优解输出
	private void solve() {
		Z = 0;
		for(int i = 1; i <= n; i++){
			int id = S[i];
			Z += c[id]*X[i];
			System.out.println(id + " : " + X[i] + " * " + -c[id]);
		}
		System.out.println("Z = " + -Z);
	}

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

如有问题,请网友指正。

希望网友的交流,共同进步。

修正单纯形法·优化算法实现·Java

时间: 2024-08-09 02:06:57

修正单纯形法·优化算法实现·Java的相关文章

粒子群优化算法及其java实现

憋了两周终于把开题报告憋出来了,再一次证明自己不适合搞学术,哎--,花了点时间把报告中提到的粒子群算法看了看,看了些资料,用java跑起来. 算法简介 粒子群算法最先由Barnhart博士和Kennedy博士于1995 年提出,是一种源于对鸟群捕食行为的研究而发明的进化计算技术,原理是模仿鸟群寻觅食物的搜索过程,设想鸟群在一定区域搜寻食物,在不知道食物确切位置的情况下,鸟群依靠群体中个体判断距离食物的远近程度来调节飞行方向和飞行速度,最终通过群体的经验和自身记忆的智慧找到食物. 算法原理 算法描

8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来探讨一下非递归方案 实验结果令人还是有些失望,原来非递归方案的性能并不比递归方案性能高 代码如下: package com.newflypig.eightqueen; import java.util.Date; /** * 使用循环控制来实现回溯,解决N皇后 * @author [email pr

深度解读最流行的优化算法:梯度下降

深度解读最流行的优化算法:梯度下降 By 机器之心2016年11月21日 15:08 梯度下降法,是当今最流行的优化(optimization)算法,亦是至今最常用的优化神经网络的方法.本文旨在让你对不同的优化梯度下降法的算法有一个直观认识,以帮助你使用这些算法.我们首先会考察梯度下降法的各种变体,然后会简要地总结在训练(神经网络或是机器学习算法)的过程中可能遇到的挑战.(本文的中文版 PDF 下载地址) 目录: 梯度下降的各种变体 批量梯度下降(Batch gradient descent)

性能优化——算法优化

背景 由于某种原因,我们系统需要记录另一个系统中一个表里的id.但是,当我们记录完了以后,别人系统可能会删除那个表里的一些数据,这样的话,我们这边就多了一些无效数据,所以,我们必须的找到这些无效的id,然后将其删除. 开始,我们的实现是这样:我们将记录下来的所有id放在一个list里,然后传到另一个系统,他将他们已经删除的id返回.具体处理代码如下: <pre name="code" class="java">public String findDele

百钱百鸡,用高中数学优化算法

背景介绍 学习算法的道路上总会有各种各样的感受,偶然间碰到一个源自我国的算法问题,百钱百鸡问题,貌似很经典的问题了,可是我才刚刚知道,感觉自己太LOW了.题目是出自古代的一本叫做算经的书,原文是文言文就不往出贴了,贴了也看不懂,说大家能听懂的话就是: 有公鸡,母鸡,小鸡三种鸡,公鸡5块钱一只,母鸡三块钱一只,小鸡一块钱三只,要求用一百块钱买上面三种鸡(都要有),并且三种鸡总数是一百只,要求所有的解法. 分析 在感叹古人物价的同时,思考题目,其实很简单,只需要满足两个条件: 公鸡 + 母鸡 + 小

[理论篇]深度理解Powell优化算法

1.鲍威尔优化法综述 鲍威尔法又称方向加速法,它由Powell于1964年提出,是利用共轭方向可以加快收敛速度的性质形成的一种搜索方法.该方法不需要对目标函数进行求导,当目标函数的导数不连续的时候也能应用,因此,鲍威尔算法是一种十分有效的直接搜索法. Powell法可用于求解一般无约束优化问题,对于维数n<20的目标函数求优化问题,此法可获得较满意的结果. 不同于其他的直接法,Powell法有一套完整的理论体系,故其计算效率高于其他直接法.该方法使用一维搜索,而不是跳跃的探测步.同时,Powel

梯度下降优化算法综述

本文翻译自Sebastian Ruder的"An overview of gradient descent optimization algoritms",作者首先在其博客中发表了这篇文章,其博客地址为:An overview of gradient descent optimization algoritms,之后,作者将其整理完放在了arxiv中,其地址为:An overview of gradient descent optimization algoritms,在翻译的过程中以

Linkedin工程师是如何优化他们的Java代码的

原文链接:Linkedin工程师是如何优化他们的Java代码的 最近在刷各大公司的技术博客的时候,我在Linkedin的技术博客上面发现了一篇很不错博文.这篇博文介绍了Linkedin信息流中间层Feed Mixer,它为Linkedin的Web主页,大学主页,公司主页以及客户端等多个分发渠道提供支撑(如下图所示). 在Feed Mixer里面用到了一个叫做SPR(念"super")的库.博文讲的就是如何优化SPR的java代码.下面就是他们总结的优化经验. 1. 谨慎对待Java的循

机器学习最常用优化之一——梯度下降优化算法综述

转自:http://www.dataguru.cn/article-10174-1.html 梯度下降算法是机器学习中使用非常广泛的优化算法,也是众多机器学习算法中最常用的优化方法.几乎当前每一个先进的(state-of-the-art)机器学习库或者深度学习库都会包括梯度下降算法的不同变种实现.但是,它们就像一个黑盒优化器,很难得到它们优缺点的实际解释.这篇文章旨在提供梯度下降算法中的不同变种的介绍,帮助使用者根据具体需要进行使用. 这篇文章首先介绍梯度下降算法的三种框架,然后介绍它们所存在的