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