Skip to content
2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 60 additions & 0 deletions src/plan.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
На этой стадии нужно написать программу, которая
1.считывает коэффициенты системы линейных уравнений из файла.
1.1 Первая строка содержит N - число переменных и уравнений.
1.2 Каждая последующая строка - N+1 чисел - N коэффициентов уравнения,
и последнее число - правая часть уравнения - константа.
2.решает систему линейных уравнений
3.записывает ответ в другой файл.
3.1 В файл должны быть записаны только ответы, разделенные "\n".
4.пути к файлам следует передавать как аргументы командной строки.
5.Весь процесс решения/преобразований со строками должен быть выведен на консоль.
6.Постарайтесь создать различные классы такие как: Matrix, Row, LinearEquation.
Пример вывода: The lines which start with > represent the user input.

> java Solver -in in.txt -out out.txt
Start solving the equation.
Rows manipulation:
-2 * R1 + R2 -> R2
-3 * R1 + R3 -> R3
0.5 * R2 -> R2
-3 * R2 + R3 -> R3
-2 * R3 -> R3
3.5 * R3 + R2 -> R2
-2 * R3 + R1 -> R1
-1 * R2 + R1 -> R1
The solution is: (1.0, 2.0, 3.0)
Saved to file out.txt

Алгоритм преобразований.
1.Обнулить все коэффициенты первого столбца кроме первого, он должен стать = 1.
2.Последовательно обнулить все коэффициенты второго и последующего столбцов
пока в последней строке все коэффициенты не обнулятся кроме последнего столбца.
3.Вторая часть алгоритма - обнулять коэффициенты выше диагонали,
начиная с последней строки до первой.
4.После этих преобразований решением уравнений будет правая часть матрицы.
Стадия 4.
Может быть случай, когда коэффициент, на который мы будем умножать будет равен 0.
Поэтому перед операцией умножения нужно проверить, коэффициент на равенство 0.
Если нужно искать ненулевой элемент ниже и правее.
1. Если ненулевой элемент ниже, то нужно переставить строки местами
2. Если ниже все элементы нулевые, то продолжаем искать правее
от элемента. Если находим, переставляем столбцы,строки.
Состояние столбцов/строк до перестановки необходимо запомнить,
чтобы после реализации вернуть все на место в исходном порядке и
вывести решение в нужном порядке. В общей сложности может быть
много перестановок.
Если ненулевой элмент не находится ниже и правее, то ищется
ненулевой элемент по всей левой части матрицы и при нахождении
переставляем соответствущие строки и столбцы.
Если ненулевой элемент не найден, первая часть алгоритма завершается.

После этого проверяем на количество решений.
1. все коэффициенты левой части нулевые, п.ч. ненулевая - нет решений.
2. если количество ненулевых элементов на главной диагонали
совпадает с количеством уравнений (в п.ч. не нули) - одно решение
3. если на главной дигонали есть нулевые элементы + в п.ч.нули
-> бесконечно много решений.
C1,C2,C3(1<->2)C2,C1,C3(1<->3)C3,C1,C2
colMove[1]=3
colMove[2]=1
colMove[3]=2
7 changes: 7 additions & 0 deletions src/solver/InvalidDataFileFormat.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package solver;

public class InvalidDataFileFormat extends Exception{
public InvalidDataFileFormat(String msg, Exception cause) {
super(msg, cause);
}
}
122 changes: 120 additions & 2 deletions src/solver/Main.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,125 @@
package solver;

import java.io.File;

import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class Main {
public static void main(String[] args) {
System.out.print("Hello world!");
static String inFile;
static String outFile;
public static void main(String[] args) throws InvalidDataFileFormat {
//get_in_file
if (args.length!=4) {
System.out.println("Invalid comand-line arguments");
return;
}

for (int i = 0; i < args.length; i+=2) {
if (args[i].equalsIgnoreCase("-in"))
inFile = args[i+1];
else if (args[i].equalsIgnoreCase("-out"))
outFile = args[i+1];
}
try {
List<String> lines = Files.readAllLines( Paths.get(inFile));
int n=0,v=0;
int k=0;
try {
for (String s:lines.get(0).split("\\s")) {
if (k==0)
n = Integer.parseInt(s);//количество строк - уравнений
else
v = Integer.parseInt(s);//количество столбцов - переменных
k++;
}
if (v==0) v=n;
}
catch (NumberFormatException e){
throw new InvalidDataFileFormat(
//String.format("The string '%s' cannot be parsed as an array of numbers", s),
String.format("Incorrect data file format, '%s' cannot be parsed as two numbers", lines.get(0)),
e);
}
lines.remove(0);
if (lines.size() != n) {
throw new InvalidDataFileFormat("Incorrect data file format, count of data rows isn't equal n", null);
}
System.out.println("Start solving the equation.\n" +
"Rows manipulation:");
Matrix m = new Matrix(n,v);
for (String line : lines) {
m.addRow(lines.indexOf(line), line);
}
String manipulation;
//m.otladka = true;
m.print();
for (int i = 0; i < m.M; i++) {
while (true)
{
manipulation = m.rows[i].transform1(i);
if (!manipulation.equals("")) {
System.out.println(manipulation);
m.print();
if (!manipulation.contains("<->")) break;
} else break;
};

for (int j = i+1; j < m.N; j++) {
manipulation = m.rows[j].transform0(i, m.rows[i]);
if (!manipulation.equals("")) {
System.out.println(manipulation);
m.print();
}
}
}
int check = m.checkSolution();

String result="";
switch (check) {
case 0: {
result = "Infinite solutions";
System.out.println(result);
break;
}
case -1: {
result = "No solutions";
System.out.println(result);
break;
}
case 1: {
System.out.println("-------");
for (int i = m.N - 1; i >= 0; i--) {
for (int j = i - 1; j >= 0; j--) {
manipulation = m.rows[j].transform0(i, m.rows[i]);
if (!manipulation.equals("")) {
System.out.println(manipulation);
m.print();
}
}
}
result = m.printSolution();
break;
}
default:break;
}
File file = new File(outFile);
try (FileWriter writer = new FileWriter(file)) {
writer.write(result);
System.out.printf("Saved to file %s\n",outFile);
} catch (IOException e) {
System.out.printf("File writing error %s", e.getMessage());
}

}
catch (IOException e){
System.out.println("File reading error: " + inFile);
}
catch (InvalidDataFileFormat | ParsingArrayException e){
System.out.println(e.getMessage());
}
}
}
176 changes: 176 additions & 0 deletions src/solver/Matrix.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
package solver;

import java.util.Arrays;

//import java.util.Arrays;
class Pos{
int x;
int y;

public Pos(int x, int y) {
this.x = x;
this.y = y;
}
public String asString(){
return this.x+","+this.y;
}
}

public class Matrix {
public static final double threshold = 0.000001;
int N;//количество строк
int M;//количество столбцов
Row[] rows;
int[] colMove;
int iteration = 0;
private boolean colsSwaped = false;

public boolean otladka = false;

public static boolean compareDouble(double d1, double d2){
return (Math.abs(d1 - d2) < threshold);
}

public Matrix(int n, int m) {
N = n;
M = m;
rows = new Row[n];
colMove = new int[m];//сюда будем записывать перемещения столбов
for (int i = 0; i < M; i++)
this.colMove[i] = i;
}

public void addRow(int index, String str) throws ParsingArrayException {
this.rows[index] = new Row(index+1, M+1, this);
this.rows[index].fillRow(str);
}

public void print(){
if (!otladka) return;
for (Row r:this.rows) {
System.out.println(r.asString());
}
}

public String printSolution(){
if (colsSwaped) return printSolution1();
String sOut = "The solution is: (";
String result="";
double s;
for (Row r:this.rows) {
s =r.getCol(this.M);
result+=s+"\n";
sOut += s+", ";
}
System.out.println(sOut.replaceAll(",\\s$", ")"));
return result;
}

private String printSolution1(){
String sOut = "The solution is: (";
double[] d= new double[colMove.length];
String result="";
for (int i = 0; i < colMove.length; i++) {
d[colMove[i]]=this.rows[i].getCol(this.M);
}
for (int i = 0; i < colMove.length; i++) {
result+=d[i]+"\n";
sOut += d[i]+", ";
}
System.out.println(sOut.replaceAll(",\\s$", ")"));
return result;
}

public String swapRows(int src, int dest){
try {
Row r1 = this.rows[src];
Row r2 = this.rows[dest];
iteration++;
String result = String.format("%d: %s<->%s", iteration, r1.getName(), r2.getName());
Row tmp;
tmp = this.rows[dest];
this.rows[dest] = this.rows[src];
this.rows[src] = tmp;
this.rows[src].setMoved(true, src + 1);
this.rows[dest].setMoved(true, dest + 1);
return result;
}
catch (Exception e){
System.out.println(String.format("SwapRow(src=%d,dest=%d)",src,dest));
throw e;
}
}


public String swapColumns(int src, int dest){
for (Row r:this.rows) {
r.swapCells(src,dest);
}
int tmp =this.colMove[dest];
this.colMove[dest] = this.colMove[src];
this.colMove[src] = tmp;
iteration++;
colsSwaped = true;
return String.format("%d; C%d<->C%d",iteration, src,dest);
}

public int findNonZeroBelow(int col, Row rowBelow){
for (int i = rowBelow.getRowNum()/*-1+1*/; i < N; i++) {
//if (this.rows[i].getCol(col)!=0) return i;
if (!compareDouble(this.rows[i].getCol(col),0)) return i;
}
return -1;
}

public int findNonZeroRighter(int colAfterIndex, Row row){
for (int j = colAfterIndex+1; j < M; j++) {
// if (row.getCol(j)!=0) return j;
if (!compareDouble(row.getCol(j),0)) return j;
}
return -1;
}

public Pos findNonZeroEverywhere(int colAfterIndex, Row rowBelow){
int fromRow=0;
if (rowBelow == null) fromRow = 0;
else fromRow = rowBelow.getRowNum();
for (int i = fromRow; i < N; i++) {
for (int j = colAfterIndex+1; j < M; j++) {
// if (this.rows[i].getCol(j)!=0) return new Pos(i,j);
if (!compareDouble(this.rows[i].getCol(j),0)) return new Pos(i,j);
}
}
return null;
}

public Pos getNumberOfZeroRows(){
//в ч запишем количество нулевых строк,
//в y количество нулевых строк с ненулевой правой частью
Pos result= new Pos(0,0);
int cnt0 =0, cnt1 =0;
for (Row r:this.rows) {
cnt0=0;
for (int i = 0; i < M+1; i++) {
//if (r.getCol(i)!=0) {
if (!compareDouble(r.getCol(i),0)){
if (i==M) result.y++;
break;
}
cnt0++;
}
if (cnt0==M+1) result.x++;
}
return result;
}

public int checkSolution(){
Pos zeroRowsCnt = this.getNumberOfZeroRows();
if (otladka)
System.out.println(zeroRowsCnt.asString());
if (zeroRowsCnt.y>0) return -1;//no solutions
int cntEq = this.N-zeroRowsCnt.x;//количество ненулевых уравнений
if (cntEq==this.M) return 1;//one solution
if (cntEq<this.M) return 0;//Infinite solutions
return -1;
}
}
11 changes: 11 additions & 0 deletions src/solver/ParsingArrayException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package solver;

public class ParsingArrayException extends Exception{
public ParsingArrayException(String msg, Exception cause) {
super(msg, cause);
}

public ParsingArrayException(String msg) {
super(msg);
}
}
Loading