From 81079e0ffbc98c1962004535943c7e1b924ada3d Mon Sep 17 00:00:00 2001 From: pgirl111 Date: Wed, 13 Dec 2023 22:39:37 +0400 Subject: [PATCH] lab1 --- .gitignore | 38 +++++ pom.xml | 17 ++ src/main/java/ru/uni/Main.java | 25 +++ .../ru/uni/symplex_method/Constraint.java | 19 +++ .../ru/uni/symplex_method/ConstraintSign.java | 6 + .../ru/uni/symplex_method/SimplexMatrix.java | 85 ++++++++++ .../ru/uni/symplex_method/SimplexService.java | 159 ++++++++++++++++++ .../uni/symplex_method/SymplexException.java | 7 + 8 files changed, 356 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/ru/uni/Main.java create mode 100644 src/main/java/ru/uni/symplex_method/Constraint.java create mode 100644 src/main/java/ru/uni/symplex_method/ConstraintSign.java create mode 100644 src/main/java/ru/uni/symplex_method/SimplexMatrix.java create mode 100644 src/main/java/ru/uni/symplex_method/SimplexService.java create mode 100644 src/main/java/ru/uni/symplex_method/SymplexException.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/.gitignore @@ -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 \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..fbcd21a --- /dev/null +++ b/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + ru.uni + simplex + 1.0-SNAPSHOT + + + 17 + 17 + UTF-8 + + + \ No newline at end of file diff --git a/src/main/java/ru/uni/Main.java b/src/main/java/ru/uni/Main.java new file mode 100644 index 0000000..ab0fa04 --- /dev/null +++ b/src/main/java/ru/uni/Main.java @@ -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(); + } +} \ No newline at end of file diff --git a/src/main/java/ru/uni/symplex_method/Constraint.java b/src/main/java/ru/uni/symplex_method/Constraint.java new file mode 100644 index 0000000..af0d380 --- /dev/null +++ b/src/main/java/ru/uni/symplex_method/Constraint.java @@ -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; + } +} diff --git a/src/main/java/ru/uni/symplex_method/ConstraintSign.java b/src/main/java/ru/uni/symplex_method/ConstraintSign.java new file mode 100644 index 0000000..c94c0d3 --- /dev/null +++ b/src/main/java/ru/uni/symplex_method/ConstraintSign.java @@ -0,0 +1,6 @@ +package ru.uni.symplex_method; + +public enum ConstraintSign { + LESS_EQUALS, + MORE_EQUALS +} diff --git a/src/main/java/ru/uni/symplex_method/SimplexMatrix.java b/src/main/java/ru/uni/symplex_method/SimplexMatrix.java new file mode 100644 index 0000000..ae8e004 --- /dev/null +++ b/src/main/java/ru/uni/symplex_method/SimplexMatrix.java @@ -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 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(); + } + } + + +} diff --git a/src/main/java/ru/uni/symplex_method/SimplexService.java b/src/main/java/ru/uni/symplex_method/SimplexService.java new file mode 100644 index 0000000..510164a --- /dev/null +++ b/src/main/java/ru/uni/symplex_method/SimplexService.java @@ -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(); + } +} diff --git a/src/main/java/ru/uni/symplex_method/SymplexException.java b/src/main/java/ru/uni/symplex_method/SymplexException.java new file mode 100644 index 0000000..30e9579 --- /dev/null +++ b/src/main/java/ru/uni/symplex_method/SymplexException.java @@ -0,0 +1,7 @@ +package ru.uni.symplex_method; + +public class SymplexException extends Exception { + public SymplexException(String error) { + super(error); + } +}