改变单纯形算法使目标函数最小化而不是最大化



我创建了以下单纯形算法,该算法最大化了目标函数。我希望相反的事情发生。在这个例子中,有两个变量,算法必须计算出将这两个变量(13.0和23.0)乘以什么,以便在约束集内获得最大可能的结果。我希望算法能计算出尽可能低的结果。

我的代码:

import java.util.*;

public class Simplex
{
private static final double EPSILON = 1.0E-10;
private double[][] tableaux;
private int numOfConstraints;
private int numOfVariables;
private int[] basis;
/**
* Constructor for objects of class Simplex
*/
public Simplex()
{

double[][] thisTableaux = {
{  5.0, 15.0 },
{  4.0,  4.0 },
{ 35.0, 20.0 },
};
double[] constraints = { 480.0, 160.0, 1190.0 };
double[] variables = {  13.0,  23.0 };
numOfConstraints = constraints.length;
numOfVariables = variables.length;
tableaux = new double[numOfConstraints+1][numOfVariables+numOfConstraints+1];
//adds all elements from thisTableaux to tableaux
for(int i=0; i < numOfConstraints; i++)
{
for(int j=0; j < numOfVariables; j++)
{
tableaux[i][j] = thisTableaux[i][j];
}
} 

//adds a slack variable for each variable there is and sets it to 1.0
for(int i=0; i < numOfConstraints; i++)
{
tableaux[i][numOfVariables+i] = 1.0;
}

//adds variables into the second [] of tableux
for(int j=0; j < numOfVariables; j++)
{
tableaux[numOfConstraints][j] = variables[j];
}

//adds constraints to first [] of tableaux
for(int k=0; k < numOfConstraints; k++)
{
tableaux[k][numOfConstraints+numOfVariables] = constraints[k];
}

basis = new int[numOfConstraints];
for(int i=0; i < numOfConstraints; i++)
{
basis[i] = numOfVariables + i;
}
//show();
//optimise();
//assert check(thisTableaux, constraints, variables);

}
public void optimise() {
while(true) {
int q = findLowestNonBasicCol();
if(q == -1) {
break;
}
int p = getPivotRow(q);
if(p == -1) throw new ArithmeticException("Linear Program Unbounded");
pivot(p, q);
basis[p] = q;
}
}
public int findLowestNonBasicCol() {
for(int i=0; i < numOfConstraints + numOfVariables; i++)
{
if(tableaux[numOfConstraints][i] > 0) {

return i;
}
}
return -1;

}
public int findIndexOfLowestNonBasicCol() {
int q = 0;
for(int i=1; i < numOfConstraints + numOfVariables; i++)
{
if(tableaux[numOfConstraints][i] > tableaux[numOfConstraints][q]) {
q = i;
}
}
if(tableaux[numOfConstraints][q] <= 0) {
return -1;
}
else {
return q;
}
}
/**
* Finds row p which will be the pivot row using the minimum ratio rule.
* -1 if there is no pivot row
*/
public int getPivotRow(int q) {
int p = -1;
for(int i=0; i < numOfConstraints; i++) {
if (tableaux[i][q] <=0) {
continue;
}
else if (p == -1) {
p = i;
}
else if((tableaux[i][numOfConstraints+numOfVariables] / tableaux[i][q] < tableaux[p][numOfConstraints+numOfVariables] / tableaux[p][q])) {
p = i;
}
}

return p;

}
public void pivot(int p, int q) {
for(int i=0; i <= numOfConstraints; i++) {
for (int j=0; j <= numOfConstraints + numOfVariables; j++) {
if(i != p && j != q) {
tableaux[i][j] -= tableaux[p][j] * tableaux[i][q] / tableaux[p][q];
}
}
}
for(int i=0; i <= numOfConstraints; i++) {
if(i != p) {
tableaux[i][q] = 0.0;
}
}
for(int j=0; j <= numOfConstraints + numOfVariables; j++) {
if(j != q) {
tableaux[p][j] /= tableaux[p][q];
}
}
tableaux[p][q] = 1.0;
show();
}
public double result() {
return -tableaux[numOfConstraints][numOfConstraints+numOfVariables];
}

public double[] primal() {
double[] x = new double[numOfVariables];
for(int i=0; i < numOfConstraints; i++) {
if(basis[i] < numOfVariables) {
x[basis[i]] = tableaux[i][numOfConstraints+numOfVariables];
}
}
return x;
}
public double[] dual() {
double[] y = new double[numOfConstraints];
for(int i=0; i < numOfConstraints; i++) {
y[i] = -tableaux[numOfConstraints][numOfVariables];
}
return y;
}
public boolean isPrimalFeasible(double[][] thisTableaux, double[] constraints) {
double[] x = primal();
for(int j=0; j < x.length; j++) {
if(x[j] < 0.0) {
StdOut.println("x[" + j + "] = " + x[j] + " is negative");
return false;
}
}
for(int i=0; i < numOfConstraints; i++) {
double sum = 0.0;
for(int j=0; j < numOfVariables; j++) {
sum += thisTableaux[i][j] * x[j];
}
if(sum > constraints[i] + EPSILON) {
StdOut.println("not primal feasible");
StdOut.println("constraints[" + i + "] = " + constraints[i] + ", sum = " + sum);
return false;
}
}
return true;
}

private boolean isDualFeasible(double[][] thisTableaux, double[] variables) {
double[] y = dual();
for(int i=0; i < y.length; i++) {
if(y[i] < 0.0) {
StdOut.println("y[" + i + "] = " + y[i] + " is negative");
return false;
}
}
for(int j=0; j < numOfVariables; j++) {
double sum = 0.0;
for(int i=0; i < numOfConstraints; i++) {
sum += thisTableaux[i][j] * y[i];
}
if(sum < variables[j] - EPSILON) {
StdOut.println("not dual feasible");
StdOut.println("variables[" + j + "] = " + variables[j] + ", sum = " + sum);
return false;
}
}
return true;
}
private boolean isOptimal(double[] constraints, double[] variables) {
double[] x = primal();
double[] y = dual();
double value = result();
double value1 = 0.0;
for(int j=0; j < x.length; j++) {
value1 += variables[j] * x[j];
}
double value2 = 0.0;
for(int i=0; i < y.length; i++) {
value2 += y[i] * constraints[i];
}
if(Math.abs(value - value1) > EPSILON || Math.abs(value - value2) > EPSILON) {
StdOut.println("value = " + value + ", cx = " + value1 + ", yb = " + value2);
return true;
}
return true;
}
private boolean check(double[][] thisTableaux, double[] constraints, double [] variables) {
return isPrimalFeasible(thisTableaux, constraints) && isDualFeasible(thisTableaux, variables) && isOptimal(constraints, variables);
}

}

如果您需要更多信息,请询问。感谢您的帮助。

如果你想最小化f(x),这相当于最大化-f(x)。因此,如果你发布的代码正确地解决了最大化问题,你可以使用它来最小化任何目标函数f(x。

请注意,不更改约束,只更改目标函数。

例如,最小化f(x)=3x+5,x>=1等于最大化-f(x)=-3x-5,x>=1。

min[f(x),x>=1]=f(1)=8=-(-8)=-[-f(1。

通常,min[f(x)]=f(Xmin)=-[-f(Xmax)]=-max[-f(x)]和Xmin=Xmax。

在上面的例子中,min[f(x)]=-max[-f(x)]=8并且Xmin=Xmax=1。

在您给出的特定示例中,您只需更改行

double[] variables = {  13.0,  23.0 };

double[] variables = {  -13.0,  -23.0 };

返回的变量值应与最小情况下的值相同

double[] variables = {  13.0,  23.0 };

并且将目标函数的值乘以-1将给出情况下目标的最小值

double[] variables = {  13.0,  23.0 };

最新更新