Rovnice a determinant
vypočítává kořeny soustavy rovnc a determinant matice
cpp
// Rovnice a determinant.cpp : Defines the entry point for the console application.
//
#include<iostream>
#include<string>
#include<fstream>
#include<clocale>
#include<Windows.h>
#include<sstream>
#include<conio.h>
#include<iomanip>
using namespace std;
void Gotoxy(int x, int y) {
COORD pos = {x, y};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
double determinant(double** _matrix, int sizeX) {
//vytvoøení duplicitní matice, aby se nesmazaly hodnoty
double** matrix = new double*[sizeX];
for (int i = 0; i < sizeX; i++) {
matrix[i] = new double[sizeX];
}
//kopírování hodnot
for (int x = 0; x < sizeX; x++) {
for (int y = 0; y < sizeX; y++) {
matrix[x][y] = _matrix[x][y];
}
}
//poèítání determinantu pomocí gaussovy eliminace, souèet prvkù na hlavní diagonále dá dohromady determinant.
for (int radek = 0; radek < sizeX - 1; radek++) {
if (matrix[radek][radek] == 0) {
// hledani prvniho radku ktery nezacina nulou
for (int _radek = radek + 1; _radek < sizeX; _radek++) {
if (matrix[_radek][radek] != 0) { // nalezen nenulovy radek, prehozeni s aktivnim radkem
double pomoc;
for (int _sloupec = radek; _sloupec < sizeX + 1; _sloupec++) {
pomoc = matrix[radek][_sloupec];
matrix[radek][_sloupec] = matrix[_radek][_sloupec];
matrix[_radek][_sloupec] = pomoc;
}
break;
}
}
}
for (int _radek = radek + 1; _radek < sizeX; _radek++) {
// kdyz nebyl nalezen radek nezacinajici nulou - > determinant je roven nule
if (matrix[radek][radek] == 0) {
return 0;
}
double pomer = matrix[_radek][radek] / matrix[radek][radek];
// odeètení / pøiètení øádku
matrix[_radek][radek] = 0; //explicitnì, kvùli nedokonalostem uchovávání v dat. typu double.
for (int sloupec = radek + 1; sloupec < sizeX + 1; sloupec++) {
matrix[_radek][sloupec] -= matrix[radek][sloupec] * pomer;
}
}
}
double determinant = 1;
for (int i = 0; i < sizeX; i++) {
determinant *= matrix[i][i];
}
//mazání dynamicky vytvoøených polí vyhazuje chybu (dùvod?)
/*for (int i = 0; i < sizeX; i++) {
delete[] matrix[i];
}
delete[] matrix;*/
if (determinant == 0) return 0; // kvùli "záporné nule"
return determinant;
}
void PrintMatrix(double** matrix, int sizeX, bool extended) {
stringstream ss;
for (int x = 0; x < sizeX; x++) {
for (int y = 0; y < sizeX; y++) {
ss << setw(6) << setprecision(6) << matrix[x][y] << " ";
}
if (extended) ss << "| " << setw(6) << setprecision(9) << matrix[x][sizeX];
ss << endl;
}
cout << ss.str();
}
void GaussElimination(double** soustava, int pocetNeznamych) {
bool solvable = true;
system("cls");
cout << "Pùvodní matice soustavy:\n";
PrintMatrix(soustava, pocetNeznamych, true);
// primy chod
for (int radek = 0; radek < pocetNeznamych - 1; radek++) {
if (soustava[radek][radek] == 0) {
// hledani prvniho radku ktery nezacina nulou
for (int _radek = radek + 1; _radek < pocetNeznamych; _radek++) {
if (soustava[_radek][radek] != 0) { // nalezen nenulovy radek, prehozeni s aktivnim radkem
double pomoc;
for (int _sloupec = radek; _sloupec < pocetNeznamych + 1; _sloupec++) {
pomoc = soustava[radek][_sloupec];
soustava[radek][_sloupec] = soustava[_radek][_sloupec];
soustava[_radek][_sloupec] = pomoc;
}
break;
}
}
}
for (int _radek = radek + 1; _radek < pocetNeznamych; _radek++) {
// kdyz nebyl nalezen radek nezacinajici nulou
if (soustava[radek][radek] == 0) {
break;
}
double pomer = soustava[_radek][radek] / soustava[radek][radek];
// odeètení / pøiètení øádku
soustava[_radek][radek] = 0; //explicitnì, kvùli nedokonalostem uchovávání v dat. typu double.
for (int sloupec = radek + 1; sloupec < pocetNeznamych + 1; sloupec++) {
soustava[_radek][sloupec] -= soustava[radek][sloupec] * pomer;
}
}
}
cout << "\nMatice soustavy po pøímém chodu gausovy eliminace:\n";
PrintMatrix(soustava, pocetNeznamych, true);
// zpetny chod
for (int radek = pocetNeznamych - 1; radek > 0; radek--) {
for (int _radek = radek - 1; _radek >= 0; _radek--) {
if (soustava[radek][radek] == 0) {
if (soustava[radek][pocetNeznamych] != 0) cout << "\nSoustava nema reseni";
else cout << "\nSoustava ma nekonecne mnoho reseni, zde je výsledná matice soustavy:\n";
PrintMatrix(soustava, pocetNeznamych, true);
solvable = false;
break;
}
double pomer = soustava[_radek][radek] / soustava[radek][radek];
for (int sloupec = pocetNeznamych; sloupec >= radek; sloupec--) {
soustava[_radek][sloupec] -= pomer * soustava[radek][sloupec];
}
soustava[_radek][radek] = 0; //explicitnì, kvùli nedokonalostem uchovávání v dat. typu double.
}
if (!solvable) break;
}
// normovani vysledku
if (solvable) {
cout << "\nMatice soustavy po zpìtném chodu gausovy eliminace:\n";
PrintMatrix(soustava, pocetNeznamych, true);
for (int radek = 0; radek < pocetNeznamych; radek++) {
soustava[radek][pocetNeznamych] /= soustava[radek][radek];
soustava[radek][radek] = 1;
}
cout << "\nMatice soustavy po znormování:\n";
PrintMatrix(soustava, pocetNeznamych, true);
cout << "\nKoreny soustavy rovnic:\n";
for (int i = 0; i < pocetNeznamych; i++)
cout << soustava[i][pocetNeznamych] << "\n";
}
cout << "\nStisknìte libovolnou klávesu pro návrat do hlavního menu.\n";
_getch();
}
void Kramerius(double** soustava, int pocetNeznamych) {
double determinantZakladu;
system("cls");
cout << "Pùvodní matice soustavy:\n";
PrintMatrix(soustava, pocetNeznamych, true);
cout << "\nZákladní matice:\n";
PrintMatrix(soustava, pocetNeznamych, false);
determinantZakladu = determinant(soustava, pocetNeznamych);
cout << "Determinant = " << determinantZakladu << endl;
if (determinantZakladu == 0) {
cout << "\nSoustava má nekoneènì mnoho a nebo žádné øešení.\n\nStisknìte libovolnou klávesu pro návrat do hlavního menu.";
_getch();
}
else {
// pomocná matice
double** matrix = new double*[pocetNeznamych];
for (int i = 0; i < pocetNeznamych; i++) {
matrix[i] = new double[pocetNeznamych];
}
// pole pro uložení øešení
double* roots = new double[pocetNeznamych];
//zkopírování matice
for (int radek = 0; radek < pocetNeznamych; radek++) // prvni sloupec je prohozen
matrix[radek][0] = soustava[radek][pocetNeznamych];
for (int sloupec = 1; sloupec < pocetNeznamych; sloupec++) // zbylé sloupce
for (int radek = 0; radek < pocetNeznamych; radek++)
matrix[radek][sloupec] = soustava[radek][sloupec];
// první neznámá
cout << "\n1. neznámá - pøíslušná matice: \n";
PrintMatrix(matrix, pocetNeznamych, false);
roots[0] = determinant(matrix, pocetNeznamych);
cout << "Determinant = " << roots[0];
roots[0] /= determinantZakladu;
cout << "\nHodnota = " << roots[0] << endl << endl;
// výpoètová smyèka pro další neznámé
for (int neznama = 1; neznama < pocetNeznamych; neznama++) {
//zkopírování matice
for (int sloupec = 0; sloupec < pocetNeznamych; sloupec++)
for (int radek = 0; radek < pocetNeznamych; radek++)
matrix[radek][sloupec] = soustava[radek][sloupec];
//kopírování urèitého sloupce
for (int radek = 0; radek < pocetNeznamych; radek++) {
matrix[radek][neznama] = soustava[radek][pocetNeznamych];
}
// výpis / výpoèet
cout << neznama + 1 << ". neznámá - pøíslušná matice: \n";
PrintMatrix(matrix, pocetNeznamych, false);
roots[neznama] = determinant(matrix, pocetNeznamych);
cout << "Determinant = " << roots[neznama];
roots[neznama] /= determinantZakladu;
cout << "\nHodnota = " << roots[neznama] << endl << endl;
}
cout << "Koøeny soustavy rovnic:\n";
for (int i = 0; i < pocetNeznamych; i++) {
cout << roots[i] << endl;
}
cout << "\nStisknìte libovolnou klávesu pro návrat do hlavního menu.\n";
_getch();
//mazání dynamicky vytvoøených polí vyhazuje chybu (dùvod?)
/*for (int i = 0; i < pocetNeznamych; i++) {
delete[] matrix[i];
}
delete[] matrix;
delete[] roots;*/
}
}
void RandInput(double** matrix, int sizeX, bool extended) {
string input;
int min, max;
do {
system("cls");
cout << "Zadejte minimální hodnotu: ";
getline(cin, input);
if (!atoi(input.c_str())) {
cout << "Neplatná volba, stisknìte libovolnou klávesu a zkuste to znovu.";
_getch();
}
else min = atoi(input.c_str());
} while (!(atoi(input.c_str()) || input == "0"));
max = min - 1;
do {
system("cls");
cout << "Zadejte maximální hodnotu: ";
getline(cin, input);
if (!atoi(input.c_str()) || atoi(input.c_str()) < min) {
cout << "Neplatná volba, stisknìte libovolnou klávesu a zkuste to znovu.";
_getch();
}
else max = atoi(input.c_str());
} while (!(atoi(input.c_str()) || (input == "0")) || min > max);
for (int x = 0; x < sizeX; x++) {
for (int y = 0; y < sizeX; y++) {
matrix[x][y] = min + rand() % (max - min + 1);
}
if (extended) matrix[x][sizeX] = min + rand() % (max - min + 1);
}
}
bool FileInput(double** matrix, int sizeX, bool extended) {
system("cls");
bool validInput = true;
string inputLine;
string number;
stringstream buffer;
fstream file;
file.open("input.txt");
if (file.is_open()) {
for (int x = 0; x < sizeX; x++) {
// naètení øádku a pøipravení na zpracování
getline(file, inputLine);
stringstream buffer(inputLine);
for (int y = 0; y < sizeX; y++) {
if (getline(buffer, number, ' ')) { //pokud je na øádku dosud nepøeètené èíslo
while (number == "") {
getline(buffer, number, ' ');
}
if (atof(number.c_str()) || number == "0") // pokud se opravdu jedná o èíslo
matrix[x][y] = atof(number.c_str());
else { // pokud se nejedná o èíslo
cout << "Na øádku " << x + 1 << " na pozici " << y + 1 << " se vyskytuje neèíslo.\n";
validInput = false;
break;
}
}
else {
cout << "Na øádku " << x + 1 << " je nedostateèný poèet èísel.\n";
validInput = false;
break;
}
}
if (extended && validInput) { // pokud se naèítá rozšíøená matice
if (getline(buffer, number)) { // je na øádku další èíslo
if (atof(number.c_str()) || number == "0") // pokud se opravdu jedná o èíslo
matrix[x][sizeX] = atof(number.c_str());
else {
cout << "Na øádku " << x + 1 << " na pozici " << sizeX + 1 << " se vyskytuje neèíslo.\n";
validInput = false;
}
}
else {
cout << "Na øádku " << x + 1 << " je nedostateèný poèet èísel.\n";
validInput = false;
}
}
if (!validInput) {
cout << "Stisknìte libovolnou klávesu pro návrat do pøedchozí nabídky.\n";
_getch();
return false;
}
}
}
else {
cout << "Soubor nemohl být otevøen, zkontrolujte, zda se nachází ve složce s .exe\n"
<< "Stisknìte libovolnou klávesu pro návrat do pøedchozí nabídky.\n";
_getch();
return false;
}
return true;
}
void ManualInput(double** matrix, int sizeX, bool extended) {
bool validInput;
string inputLine, number;
system("cls");
cout << "Zadejte jednotlivé " << ((extended) ? "koeficienty soustavy rovnic" : "øádky matice") << endl;
for (int x = 0; x < sizeX; x++) {
// naètení øádku a pøipravení na zpracování
getline(cin, inputLine);
stringstream buffer(inputLine);
validInput = true;
for (int y = 0; y < sizeX; y++) {
if (getline(buffer, number, ' ')) { //pokud je na øádku dosud nepøeètené èíslo
if (stod(number.c_str()) || number == "0") // pokud se opravdu jedná o èíslo
matrix[x][y] = stod(number.c_str());
else { // pokud se nejedná o èíslo
cout << "Na øádku se vyskytuje neèíslo, opakujte zadání øádku.\n";
x -= 1;
validInput = false;
break;
}
}
else {
cout << "Nedostateèný poèet èísel, " << (((extended ? sizeX + 1 : sizeX) < 5) ? "jsou" : "je") << " tøeba " << (extended ? sizeX + 1 : sizeX) << (((extended ? sizeX + 1 : sizeX) < 5) ? " èísla" : " èísel") << " na øádek. Zadejte øádek znovu.\n";
x -= 1;
validInput = false;
break;
}
}
if (extended && validInput) { // pokud se naèítá rozšíøená matice
if (getline(buffer, number, ' ')) { // je na øádku další èíslo
if (stod(number.c_str()) || number == "0") // pokud se opravdu jedná o èíslo
matrix[x][sizeX] = stod(number.c_str());
else {
cout << "Na øádku se vyskytuje neèíslo, opakujte zadání øádku.\n";
x -= 1;
}
}
else {
cout << "Nedostateèný poèet èísel, je tøeba " << (extended ? sizeX + 1 : sizeX) << (((extended ? sizeX + 1 : sizeX) < 5) ? " èísla" : " èísel") << " na øádek. Zadejte øádek znovu.\n";
x -= 1;
}
}
}
}
void LinRovnice() {
bool inputSuccess = false, fileInputSuccess = true;
double** soustava;
string input;
int pocetNeznamych;
do {
system("cls");
cout << "Zadejte poèet neznámých v soustavì rovnic: ";
getline(cin, input);
pocetNeznamych = atoi(input.c_str());
if (!pocetNeznamych) {
cout << "Neplatná volba, stisknìte libovolnou klávesu a zkuste to znovu.";
_getch();
}
} while (!pocetNeznamych);
// vytvoøení dynamického pole
soustava = new double*[pocetNeznamych];
for (int i = 0; i < pocetNeznamych; i++)
soustava[i] = new double[pocetNeznamych + 1];
do {
inputSuccess = false;
system("cls");
cout << "Øešení soustavy lineárních rovnic o " << pocetNeznamych << " neznámých. Zadejte zpùsob zadání:\n"
<< " - 1 - Ruèní zadání koeficientù\n"
<< " - 2 - Naètení ze souboru \"input.txt\"\n"
<< " - 3 - Zvolení náhodných èísel v urèitém rozsahu\n"
<< " - 4 - Návrat do hlavního menu\n";
cout << "Zadejte volbu: ";
while (!inputSuccess) {
switch (_getch()) {
case '1':
ManualInput(soustava, pocetNeznamych, true);
inputSuccess = fileInputSuccess = true;
break;
case '2':
fileInputSuccess = FileInput(soustava, pocetNeznamych, true);
inputSuccess = true;
break;
case '3':
RandInput(soustava, pocetNeznamych, true);
inputSuccess = fileInputSuccess = true;
break;
case '4':
return;
default:
inputSuccess = false;
break;
}
}
} while (!inputSuccess || !fileInputSuccess);
system("cls");
cout << "Vyberte zpùsob øešení soustavy:\n"
<< " - 1 - Gaussova eliminaèní metoda (pøímý a zpìtný chod)\n"
<< " - 2 - Kramerovo pravidlo (pomocí determinantu matice)\n"
<< "Zadejte volbu: ";
while (true) {
switch (_getch()) {
case '1':
GaussElimination(soustava, pocetNeznamych);
for (int i = 0; i < pocetNeznamych; i++)
delete[] soustava[i];
delete[] soustava;
return;
case '2':
Kramerius(soustava, pocetNeznamych);
for (int i = 0; i < pocetNeznamych; i++)
delete[] soustava[i];
delete[] soustava;
return;
default:
break;
}
}
return;
}
void DeterminantMatrix() {
bool inputSuccess = false;
double ** matrix;
int size;
string input;
do {
system("cls");
cout << "Zadejte øád matice: ";
getline(cin, input);
size = atoi(input.c_str());
if (!size) {
cout << "Neplatná volba, stisknìte libovolnou klávesu a zkuste to znovu.";
_getch();
}
} while (!size);
// vytvoøení dynamického pole
matrix = new double*[size];
for (int i = 0; i < size; i++)
matrix[i] = new double[size];
bool fileInputSuccess = true;
do {
inputSuccess = false;
system("cls");
cout << "Zadejte zpùsob zadání:\n"
<< " - 1 - Ruèní zadání øádkù matice\n"
<< " - 2 - Naètení ze souboru \"input.txt\"\n"
<< " - 3 - Zvolení náhodných èísel v urèitém rozsahu\n"
<< " - 4 - Návrat do hlavního menu\n";
cout << "Zadejte volbu: ";
while (!inputSuccess) {
switch (_getch()) {
case '1':
ManualInput(matrix, size, false);
inputSuccess = fileInputSuccess = true;
break;
case '2':
fileInputSuccess = FileInput(matrix, size, false);
inputSuccess = true;
break;
case '3':
RandInput(matrix, size, false);
inputSuccess = fileInputSuccess = true;
break;
case '4':
return;
default:
inputSuccess = false;
break;
}
}
} while (!inputSuccess || !fileInputSuccess);
system("cls");
cout << "Zadaná matice:\n";
PrintMatrix(matrix, size, false);
cout << endl << "Determinant = " << determinant(matrix, size) << endl << endl;
cout << "Stisknìte libovolnou klávesu pro návrat do hlavního menu.\n";
//mazání dynamicky vytvoøených polí vyhazuje chybu (dùvod?)
/*for (int i = 0; i < size; i++) {
delete[] matrix[i];
}
delete[] matrix;*/
_getch();
return;
}
int main(int argc, string args[]) {
// nastavení podpory diakritiky - WIN only
SetConsoleOutputCP(1250);
bool run = true, inputSuccess;
while (run) {
system("cls");
// nametag
Gotoxy(110, 25);
cout << "Radek Zikmund, ètvrtá, 2014";
Gotoxy(0, 0);
inputSuccess = false;
cout << "Program na øešení soustav lineárních rovnic a výpoètu determinantu matice.\n"
<< " - 1 - Øešení lineárních rovnic\n"
<< " - 2 - Výpoèet determinantu matice\n"
<< " - 3 - Ukonèení programu\n";
cout << "Zadejte volbu: ";
while (!inputSuccess && run) {
switch (_getch()) {
case '1':
LinRovnice();
inputSuccess = true;
break;
case '2':
DeterminantMatrix();
inputSuccess = true;
break;
case '3':
run = false;
break;
default:
break;
}
}
}
return 0;
}
Neformátovaný
Přidáno: 8.12.2014
Expirace: Neuvedeno