Cod sursa(job #2763424)

Utilizator borcanirobertBorcani Robert borcanirobert Data 13 iulie 2021 22:41:36
Problema Algoritmul lui Gauss Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.87 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>

const double eps = 0.0000001;
// Contains methods that can be used to solve a system of equations
class Gauss{
public:
    /// Creates a new Gauss object with given number of unknowns
    Gauss(int numberOfUnknowns)
        : N{0}, M{numberOfUnknowns}
    {}

    /// Creates a new Gauss object with given equations.
    /// Parameters:
    ///     numberOfEquations - the number of equations of the system
    ///     numberOfUnknowns - the number of unknownks of the system
    ///     matrix - the matrix of coefficients of the system
    Gauss(int numberOfEquations, int numberOfUnknowns, const std::vector<std::vector<double>>& matrix)
        : N{numberOfEquations}, M{numberOfUnknowns}, A{matrix}
    {}

    /// Adds a new equation to the system.
    /// Parameters:
    ///     coefficients - the coefficients of the equation
    void addEquation(const std::vector<double>& coefficients)
    {
        A.push_back(coefficients);
        ++N;
    }

    /// Solves the system of equations.
    /// Parameters:
    ///     outSolution: a std::vector<double> containing the solution for the system, if it is unique
    /// Return value: 1 if the system has unique solution, 2 if it has an infinite number of solutions
    ///               and 0 if it has no solution
    int solve(std::vector<double>& outSolution)
    {
        int i{0}, j{0}, k;
        std::vector<double> res(M);
        bool imp{false};

        while ( i < N && j < M )
        {
            // Caut o nilie k pentru care A[i][k] e nenul si daca acea linie
            // nu e linia i o voi interschimba cu linia i
            for ( k = i; k < N; ++k )
                if ( A[k][j] < -eps || A[k][j] > eps )
                    break;

            if ( k == N )
            {
                ++j;
                continue;
            }

            if ( k != i )
            {
                for ( int col = 0; col < M + 1; ++col )
                    std::swap(A[k][col], A[i][col]);
            }

            for ( int col = j + 1; col < M + 1; ++col )
                A[i][col] /= A[i][j];
            A[i][j] = 1.;

            for ( int lin = i + 1; lin < N; ++lin )
            {
                for ( int col = j + 1; col < M + 1; ++col )
                    A[lin][col] -= A[lin][j] * A[i][col];
                A[lin][j] = 0;
            }

            ++i; ++j;
        }

        for ( i = N - 1; i >= 0; --i )
            for ( j = 0; j < M + 1; ++j )
                if ( A[i][j] < -eps || A[i][j] > eps )
                {
                    if ( j == M + 1 )
                    {
                        outSolution = res;
                        return 0;
                    }

                    res[j] = A[i][M];
                    //res.push_back(A[i][M + 1]);
                    for ( k = j + 1; k < M; ++k )
                        res[j] -= res[k] * A[i][k];
                    break;
                }

        outSolution = res;
        return 1;
    }
private:
    int N;      // number of equations
    int M;      // number of unknowns
    std::vector<std::vector<double>> A;      // the matrix of coefficients
};

Gauss* G;

void Read();
void Write();

int main()
{
    Read();
    Write();

    return 0;
}

void Read()
{
    std::ifstream fin("gauss.in");
    
    int N, M;
    fin >> N >> M;
    G = new Gauss(M);

    std::vector<double> eq(M + 1);
    for (int i = 0; i < N; ++i)
    {
        for (int j = 0; j < M + 1; ++j)
            fin >> eq[j];
        
        G->addEquation(eq);
    }

    fin.close();
}

void Write()
{
    std::ofstream fout("gauss.out");

    std::vector<double> res;
    bool state = G->solve(res);

    if (state == 0)
    {
        std::cout << "Imposibil\n";
    }
    else
    {
        for (size_t i = 0; i < res.size(); ++i)
            fout << std::fixed << std::setprecision(10) << res[i] << ' ';
    }

    fout.close();
}