Tecnologia Black: Gaussian Eliminação como melhorar a velocidade e precisão da arte inteiro - fase de eliminação de Gauss foi removido e a ligação divisão

Um algoritmo muito interessante aprendidas em um treinamento qbxt tempo particular.

Pré-conhecimento

  • eliminação de Gauss
  • euclidiana

problema

Você pode querer pensar sobre o porquê da eliminação Gaussian tradicional haverá problema precisão.

Sabemos que, em quatro operações, apenas um será uma perda de precisão é uma divisão.

Então, quais são a eliminação de Gauss na etapa de divisão usa?

  1. mat[i][i...n+1] /= mat[i][i]: coeficientes de PCA em 1
  2. mat[j=i+1...n][k=i...n+1] -= mat[j][i] * mat[i][k]: Shomoto

métodos de otimização tradicionais

PCA coluna

O método tradicional é o de seleccionar directamente mat[i][i]como o elemento principal do coeficiente actual. método principal elemento foi optimizado neste um passo adicional: Nós mat[i...n][i]escolher um valor máximo absoluto do coeficiente como o principal componente no.

O novo método

Primeiras notas que os "principais componentes fator em 1" não é realmente necessário, só precisa mudar a eliminação equação mat[j=i+1...n][k=i...n+1] -= (mat[j][i] / mat[i][j]) * mat[i][k]e substituição de volta na final /mat[i][i]lata.

A questão restante é a eliminação deste passo.

A eliminação utilizando euclidiana

Exemplos de uma divisão euclidiana:

\ [(155,120) = (35,120) = (35,15) = (5,15) = (5,0) \]

Regras: dois inteiros positivos a partir do original em um número inteiro positivo e um 0 .

Lembre-se que a eliminação subtração eliminação método dos elementos Gaussian desta etapa, o nosso objectivo não é mat[j][i]tornar-se nula isso?

algoritmo

Cada eliminação, podemos mat[i][i]e mat[j][i]dois números separados removido, quando subtraindo dois números, mas estes dois números, onde a linha é também correspondentemente subtraídos.

Após esta operação, mat[i][i]e mat[j][i]certamente haverá um torna-se 0 e o outro não é zero. Se mat[i][i]as mudanças a 0, em seguida, extrair o i-ésimo e linha-th j troca de linha.

Um outro processo de eliminação nota podem ser números negativos.

Código de referência

Apenas para fins de referência , e não se determinou que várias soluções sem solução de

#include <cstdio>

#define ll long long
#define re register
#define il inline
#define gc getchar
#define pc putchar

template <class T>
void read(T &x) {
  re bool f = 0;
  re char c = gc();
  while ((c < '0' || c > '9') && c != '-') c = gc();
  if (c == '-') f = 1, c = gc();
  x = 0;
  while (c >= '0' && c <= '9') x = x * 10 + (c ^ 48), c = gc();
  f && (x = -x);
}

template <class T>
void print(T x) {
  if (x < 0) pc('-'), x = -x;
  if (x >= 10) print(x / 10);
  pc((x % 10) ^ 48);
}

template <class T>
void prisp(T x) {
  print(x);
  pc(' ');
}
template <class T>
void priln(T x) {
  print(x);
  pc('\n');
}

int n;

int mat[105][105];

void swap(int &a, int &b) {
  a ^= b ^= a ^= b;
}

void swp(int* a, int* b) {
  for (int i = 1; i <= n + 1; ++i)
    swap(a[i], b[i]);
}

void mul(int* a, int t) {
  for (int i = 1; i <= n + 1; ++i)
    a[i] *= t;
}

void sub(int* a, int* b, int t) {
  for (int i = 1; i <= n + 1; ++i)
    a[i] -= b[i] * t;
}

int ans[105];

int main() {
  read(n);
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n + 1; ++j)
      read(mat[i][j]);
  for (int k = 1; k <= n; ++k) {

    // 找主元
    for (int i = k; i <= n; ++i) {
      if (mat[i][k]) {
        if (i != k) swp(mat[i], mat[k]);
        break;
      }
    }

    for (int i = k + 1; i <= n; ++i) {
      int* a = mat[k];
      int* b = mat[i];
      // 先化成正数
      if (a[k] < 0) mul(a, -1);
      if (b[k] < 0) mul(b, -1);
      // 辗转相除(迭代版)
      while (a[k]) {
        if (a[k] > b[k]) {
          swp(a, b);
        }
        sub(b, a, b[k] / a[k]);
        swp(a, b);
      }
      swp(a, b);
    }
  }
  for (int i = n; i >= 1; --i) {
    ans[i] = mat[i][n + 1];
    for (int j = i + 1; j <= n; ++j)
      ans[i] -= ans[j] * mat[i][j];
    ans[i] /= mat[i][i];
  }
  for (int i = 1; i <= n; ++i) priln(ans[i]);
}

Acho que você gosta

Origin www.cnblogs.com/water-lift/p/12606267.html
Recomendado
Clasificación