This commit is contained in:
pgirl111 2023-12-13 22:39:37 +04:00
commit 81079e0ffb
8 changed files with 356 additions and 0 deletions

38
.gitignore vendored Normal file
View File

@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

17
pom.xml Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.uni</groupId>
<artifactId>simplex</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@ -0,0 +1,25 @@
package ru.uni;
import ru.uni.symplex_method.Constraint;
import ru.uni.symplex_method.ConstraintSign;
import ru.uni.symplex_method.SimplexService;
public class Main {
public static void main(String[] args) {
SimplexService simplexService = new SimplexService();
simplexService.createMatrix(2, 3);
var c1 = new double[]{9, 3, 1};
var c2 = new double[]{8, 1, 2};
var c3 = new double[]{12, 1, 6};
simplexService.addConstraint(new Constraint(c1, ConstraintSign.MORE_EQUALS));
simplexService.addConstraint(new Constraint(c2, ConstraintSign.MORE_EQUALS));
simplexService.addConstraint(new Constraint(c3, ConstraintSign.MORE_EQUALS));
var f = new double[]{4, 6};
simplexService.addFunction(f);
simplexService.findSolution();
}
}

View File

@ -0,0 +1,19 @@
package ru.uni.symplex_method;
public class Constraint {
private ConstraintSign sign;
private double[] coefficientArray;
public ConstraintSign getSign() {
return sign;
}
public double[] getCoefficientArray() {
return coefficientArray;
}
public Constraint(double[] coefficientArray, ConstraintSign sign) {
this.coefficientArray = coefficientArray;
this.sign = sign;
}
}

View File

@ -0,0 +1,6 @@
package ru.uni.symplex_method;
public enum ConstraintSign {
LESS_EQUALS,
MORE_EQUALS
}

View File

@ -0,0 +1,85 @@
package ru.uni.symplex_method;
import java.util.ArrayList;
import java.util.List;
public class SimplexMatrix {
private final double[][] matrix;
private final List<Integer> basis;
private final int varCount;
private final int allVarCount;
private int currentRowCount = 0;
public SimplexMatrix(int varCount, int constraintCount) {
this.varCount = varCount;
this.allVarCount = constraintCount + varCount;
matrix = new double[constraintCount + 1][allVarCount + 1];
basis = new ArrayList<>(constraintCount);
}
public void addBasis(int index, int current) {
basis.set(index, current);
}
public void addBasis(int current) {
if (current > allVarCount || current < 0) {
return;
}
basis.add(current);
}
public boolean isFill() {
return currentRowCount == matrix.length;
}
public int getCurrentRowCount() {
return currentRowCount;
}
public void addRow(double[] coefficients) throws SymplexException {
if (isFill()) {
throw new SymplexException("Матрица уже заполнена!!!");
}
matrix[currentRowCount] = coefficients;
currentRowCount++;
}
public int getVarCount() {
return varCount;
}
public int getAllVarCount() {
return allVarCount;
}
public double[][] getMatrix() {
return matrix;
}
public void pprint() {
int numCols = matrix[0].length;
System.out.print("Базис\t");
System.out.print("b\t\t");
for (int i = 1; i <= numCols-1; i++) {
System.out.print("x" + i +"\t\t\t");
}
System.out.println();
for (int i = 0; i < matrix.length; i++) {
if(i != matrix.length-1) {
System.out.printf("%4s\t", basis.get(i));
} else {
System.out.printf("%4s\t", "D");
}
for (int j = 0; j < numCols; j++) {
System.out.printf("%4f\t", matrix[i][j]);
}
System.out.println();
}
}
}

View File

@ -0,0 +1,159 @@
package ru.uni.symplex_method;
import java.util.Arrays;
public class SimplexService {
private SimplexMatrix simplexMatrix;
private final int maxIterCount = 10;
public void createMatrix(int varCount, int constraintCount) {
this.simplexMatrix = new SimplexMatrix(varCount, constraintCount);
}
public void addConstraint(Constraint constraint) {
if (simplexMatrix.isFill()) {
return;
}
double[] coefficients = constraint.getCoefficientArray();
if (coefficients.length != simplexMatrix.getVarCount() + 1) {
return;
}
var count = simplexMatrix.getAllVarCount() + 1;
double[] all = new double[count];
System.arraycopy(coefficients, 0, all, 0, coefficients.length);
// приводим к кнф
if (constraint.getSign().equals(ConstraintSign.MORE_EQUALS)) {
all = Arrays.stream(all).map(x -> -x).toArray();
}
// вводим новую переменную
var basisIndex = simplexMatrix.getVarCount() + simplexMatrix.getCurrentRowCount() + 1;
all[basisIndex] = 1;
simplexMatrix.addBasis(basisIndex);
try {
simplexMatrix.addRow(all);
} catch (Exception e) {
System.out.println("Не удалось добавить ограничение: " + e.getMessage());
}
}
public void addFunction(double[] coefficients) {
if (coefficients.length < simplexMatrix.getVarCount()) {
return;
}
var count = simplexMatrix.getAllVarCount() + 1;
double[] all = new double[count];
System.arraycopy(coefficients, 0, all, 1, coefficients.length);
all = Arrays.stream(all).map(x -> -x).toArray();
try {
simplexMatrix.addRow(all);
} catch (Exception e) {
System.out.println("Не удалось добавить функцию: " + e.getMessage());
}
}
public void findSolution() {
if (simplexMatrix == null) {
return;
}
var isFind = false;
int iterCount = 0;
while (iterCount < maxIterCount && !isFind) {
isFind = checkCondition();
if (!isFind) {
System.out.printf("----Итерация %d----%n", iterCount);
printMatrix();
try {
doIter();
} catch (SymplexException exception) {
System.out.println("Произошла ошибка при выполнении: " + exception.getMessage());
break;
}
iterCount++;
printMatrix();
}
}
if (isFind) {
System.out.println("Решение найдено:");
printMatrix();
} else {
System.out.println("Решения нет");
}
}
private boolean checkCondition() {
var matrix = simplexMatrix.getMatrix();
return Arrays.stream(matrix).allMatch(x -> x[0] >= 0);
}
private void doIter() throws SymplexException {
var matrix = simplexMatrix.getMatrix();
// поиск разрешающей строки и столбца
int indexRow = findRowIndex(matrix);
if (indexRow == -1) {
throw new SymplexException("Разрешающая строка не найдена");
}
var row = matrix[indexRow];
int indexColumn = findColIndex(row);
if (indexColumn == -1) {
throw new SymplexException("Разрешающий столбец не найден");
}
double element = row[indexColumn];
// разделить строку с индексом indexRow на разрешающий элемент
row = Arrays.stream(matrix[indexRow]).map(x -> x / element).toArray();
// привести к нулям все элементы по indexColumn с помощью сложения с найденной строкой
for (int i = 0; i < matrix.length; i++) {
if (i == indexRow) {
continue;
}
double additionValue = -matrix[i][indexColumn];
for (int j = 0; j < matrix[0].length; j++) {
matrix[i][j] = matrix[i][j] + row[j] * additionValue;
}
}
matrix[indexRow] = row;
simplexMatrix.addBasis(indexRow, indexColumn);
}
private int findRowIndex(double[][] matrix) {
int index = -1;
double maxAbs = -1;
for (int i = 0; i < matrix.length-1; i++) {
if (matrix[i][0] < 0) {
var value = Math.abs(matrix[i][0]);
if (value > maxAbs) {
maxAbs = value;
index = i;
}
}
}
return index;
}
private int findColIndex(double[] matrix) {
int index = -1;
double maxAbs = -1;
for (int i = 1; i < matrix.length; i++) {
if (matrix[i] < 0) {
var value = Math.abs(matrix[i]);
if (value > maxAbs) {
maxAbs = value;
index = i;
}
}
}
return index;
}
public void printMatrix() {
simplexMatrix.pprint();
}
}

View File

@ -0,0 +1,7 @@
package ru.uni.symplex_method;
public class SymplexException extends Exception {
public SymplexException(String error) {
super(error);
}
}