lab1
This commit is contained in:
commit
81079e0ffb
38
.gitignore
vendored
Normal file
38
.gitignore
vendored
Normal 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
17
pom.xml
Normal 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>
|
25
src/main/java/ru/uni/Main.java
Normal file
25
src/main/java/ru/uni/Main.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
19
src/main/java/ru/uni/symplex_method/Constraint.java
Normal file
19
src/main/java/ru/uni/symplex_method/Constraint.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
6
src/main/java/ru/uni/symplex_method/ConstraintSign.java
Normal file
6
src/main/java/ru/uni/symplex_method/ConstraintSign.java
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package ru.uni.symplex_method;
|
||||||
|
|
||||||
|
public enum ConstraintSign {
|
||||||
|
LESS_EQUALS,
|
||||||
|
MORE_EQUALS
|
||||||
|
}
|
85
src/main/java/ru/uni/symplex_method/SimplexMatrix.java
Normal file
85
src/main/java/ru/uni/symplex_method/SimplexMatrix.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
159
src/main/java/ru/uni/symplex_method/SimplexService.java
Normal file
159
src/main/java/ru/uni/symplex_method/SimplexService.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package ru.uni.symplex_method;
|
||||||
|
|
||||||
|
public class SymplexException extends Exception {
|
||||||
|
public SymplexException(String error) {
|
||||||
|
super(error);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user