Comparando números racionais

12

Dado a,b,c,dN e ,b,d{0}

ab<cdad<cb

Minhas perguntas são:

Dadoa,b,c,d

  1. Supondo que podemos decidir em , existe alguma maneira de decidir sem ter que pré-executar as multiplicações (ou divisões), e . Ou existe algum tipo de prova de que não há como.x<yZO(|x|+|y|)ad<cbadcb
  2. Existe um método mais rápido para comparar números racionais do que multiplicar os denominadores.
Realz Slaw
fonte
1
@PKG, mas a multiplicação levará mais que o tempo linear. Eu acho que queremos algo mais rápido para esta pergunta.
23412 Joe
1
O caso complicado é quando um intervalo contém outro, por exemplo, . [a,d][b,c]
PKG
1
Você supõe implicitamente que e têm o mesmo sinal. Caso contrário, a direção da desigualdade muda. bd
Ran G.
1
(1) A multiplicação é quase linear (procure o algoritmo de Fürer). (2) Um "número inteiro racional", pelo menos no contexto da teoria dos números algébricos, na verdade significa apenas um número inteiro. Você quer dizer "racional" ou "número racional".
Yuval Filmus
1
ver também duplicata aparente Como comparar números racionais?
vzn

Respostas:

5

Minha pesquisa atual:

Tentativa inicial de algumas regras gerais

Pode-se tentar fazer algumas regras gerais para resolver a comparação racional:

Supondo que todos os positivos :a,b,c,d

a<bcdab<cd
Isso basicamente significa que, se o lado esquerdo for menor que um e o lado direito for pelo menos um, o lado esquerdo será menor que o lado direito. Na mesma veia:

abcdabcd

Outra regra:

Penso nessa regra como lógica, pois quanto maior o denominador, menor o número, enquanto maior o numerador, maior o número. Portanto, se o lado esquerdo tiver um denominador maioreum numerador menor, o esquerdo será menor.

(b>d)(ac)[ab<cd]

Daqui em diante, assumiremos que , porque, caso contrário, podemos resolvê-lo com as regras acima ou reverter a questão para ca<cb<d , e acabamos com essa condição de qualquer maneira.cd<?ab

Regras :

(ba)b<(dc)d[ab<cd]|a<c,b<d
Essa regra basicamente afirma que você sempre pode subtrair os numeradores dos denominadores e definir os resultados como numeradores, para obter um problema equivalente. Vou deixar de fora a prova.

ab<cadb[ab<cd]|a<c,b<d

Esta regra permite subtrair o numerador e o denominador à esquerda do numerador e denominador à direita para um problema equivalente.

E é claro que há dimensionamento:

akbk<cd[ab<cd]|a<c,b<d
Você pode usar o dimensionamento para tornar as regras de subtração acima mais significativas.

Usando essas regras, você pode brincar com as coisas, aplicá-las repetidamente, em combinações inteligentes, mas há casos em que os números são próximos e patológicos.

Ao aplicar as regras anteriores, você pode reduzir todos esses problemas para: um

ab<ap+qbp+qab<qq|a>q,b>q

Às vezes você pode resolver isso diretamente agora, às vezes não. Os casos patológicos geralmente estão na forma:

ab<cd|a>c,b>d,cO(a),dO(b)

Então você vira e resulta na mesma coisa, apenas com um pouco menos. Cada aplicação das regras + flip reduz em um dígito / bit. AFAICT, você não pode resolvê-lo rapidamente, a menos que aplique as regras vezes (uma vez para cada dígito / bit) no caso patológico, negando sua aparente vantagem.O(n)

Problema em aberto ??

Percebi que esse problema parece ser mais difícil do que alguns problemas atuais em aberto.

Um problema ainda mais fraco é determinar:

ad=?bc

E ainda mais fraco:

ad=?c

Esse é o problema aberto de verificação da multiplicação . É mais fraco, porque se você tivesse uma maneira de determinar , então você pode facilmente determinar a d ? = b c , testando usando o algoritmo duas vezes, a d ? < b c , b c ? < a d . Iff tanto é verdade, você sabe que um d b c .ad<?bcad=?bcad<?bcbc<?adadbc

Agora, era um problema em aberto, pelo menos em 1986:ad=?c

A complexidade da multiplicação e divisão. Vamos começar com a equação muito simples ax = b. Quando considerado sobre os números inteiros, é possível testar sua solvabilidade e encontrar uma solução x pela divisão inteira com o restante zero. Para verificar uma determinada solução x, a multiplicação inteira será suficiente, mas é um problema em aberto interessante se existem métodos mais rápidos de verificação.

- ARNOLD SCHÖNHAGE na resolução de equações em termos de complexidade computacional

Muito interessante, ele também mencionou a questão de verificar a multiplicação da matriz :

Também é uma questão interessante se a verificação da multiplicação da matriz, ou seja, verificar se AB = G para um dado C, poderia ser feita mais rapidamente.

- ARNOLD SCHÖNHAGE na resolução de equações em termos de complexidade computacional

Isso já foi resolvido e é realmente possível verificar em tempo com um algoritmo aleatório (com n × n sendo o tamanho das matrizes de entrada, portanto, é basicamente o tempo linear no tamanho da entrada ) Gostaria de saber se é possível reduzir a multiplicação inteira à multiplicação de matrizes, especialmente com suas semelhanças, dadas as semelhanças da multiplicação inteira de Karatsuba com os algoritmos de multiplicação de matrizes que se seguiram. Então, talvez, de alguma forma, possamos alavancar o algoritmo de verificação de multiplicação de matrizes para multiplicação de números inteiros.O(n2)n×n

Enfim, uma vez que este ainda é, que eu saiba, um problema aberto, o problema mais forte de está certamente aberto. Estou curioso para saber se a solução do problema de verificação de igualdade teria alguma influência no problema de verificação de desigualdade de comparação.ad<?cd

Uma pequena variação do nosso problema seria se as frações fossem reduzidas aos termos mais baixos; Nesse caso, é fácil saber se . Isso pode ter alguma influência na verificação comparativa de frações reduzidas?ab=?cd

Uma pergunta ainda mais sutil, e se tivéssemos uma maneira de testar , seria este estender-se a testar um d ? = c ? Não vejo como você pode usar isso "nos dois sentidos", como fizemos para um d ? < c d .ad<?cad=?cad<?cd

Palavras-chave:

  • Reconhecimento aproximado de idiomas não regulares por autômatos finitos

    Eles trabalham na multiplicação aproximada e na verificação aleatória, que eu não entendo completamente.

  • math.SE: Como comparar duas multiplicações sem multiplicar?
  • Suponha que tenhamos permissão para pré-processar quanto desejássemos no tempo polinomial, podemos resolver a b = c no tempo linear?cumab=c
  • Existe um algoritmo de multiplicação de números inteiros não-determinísticos em tempo linear? Consulte http://compgroups.net/comp.theory/nondeterministic-linear-time-multiplication/1129399

    Existem algoritmos conhecidos para multiplicar números de n bits com algo como complexidade O (n log (n) log (log (n))). E não podemos fazer melhor que O (n) porque pelo menos temos que olhar para todas as entradas. Minha pergunta é: podemos realmente alcançar O (n) para uma classe adequada de algoritmos "não determinísticos"?

    Mais precisamente, existe um algoritmo que pode aceitar dois números binários de n bits "a" e "b" e um número de 2n bits "c" e informar em O (n) tempo se "a * b = c"? Caso contrário, existe alguma outra forma de certificado C (a, b, c) tal que um algoritmo possa usá-lo para testar o produto em tempo linear? Se não for tempo linear, o problema de testar o produto é pelo menos assintoticamente mais fácil do que calculá-lo? Quaisquer resultados conhecidos nesse sentido seriam bem-vindos.

    John.

    ―Johnh4717

Realz Slaw
fonte
1

Aqui está uma tentativa muito parcial de reprovação. Suponha-se que pode fazer uso de uma única (número constante de) adições e subtracções em nosso decisor, bem como um número constante de wrt predefinido números. Em outras palavras, podemos fazer um número constante de m o d 2 , m o d 3 , etc, em nosso decisor. Então as únicas quantidades que podemos calcular são da forma q = k 1 a + k 2 b + k 3 c + k 4 d = kmodmod 2mod 3 onde o k s' são predefinidos constantes. Note que q pode ser calculado no tempo O ( | a | ) .q=k1a+k2b+k3c+k4d=kiakqO(|a|)

B:B=1ad>bca,b,c,dR4Bad=bc(a,b,c,d)q:|qa|=k1,

(Como tornar isso mais preciso?) A distância do cuboide à superfície é geralmente ilimitada e, portanto, a superfície não pode ser calculada pelo decisor

PKG
fonte
Desculpe, não respondi a isso. Eu acho que isso pode estar simplesmente acima do meu entendimento, e eu estive ocupado pesquisando possíveis respostas enquanto isso.
Realz Slaw
1

Boa pergunta. Você aceitaria nível de confiança?

Talvez faça divisão aproximada. Ou seja,

Para calcular os quocientes aproximados delimitadores de a / b, mova à direita a pelo teto (log_2 (b)) e também pelo piso (log_2 (b)). Então, sabemos que o quociente exato está entre esses dois valores.

Então, dependendo dos tamanhos relativos dos quatro números inteiros, é possível descartar certos casos e obter 100% de confiança.

Pode-se repetir o procedimento para radix diferente de 2 e, por uma sucessão de tais operações, aumentar o nível de confiança, até que uma mudança de sinal / desempate seja observada de alguma forma?

Esse é o meu primeiro rascunho de um método.

Cris Stringfellow
fonte
O(n)O(nregistron)
umab=c
1

existe alguma maneira de decidir ad <cb sem ter que pré-formar as multiplicações [caras]

Certo.

Idéia: compare a expansão decimal pouco a pouco.

A única parte desagradável é que temos que excluir a igualdade primeiro porque, caso contrário, não podemos terminar.
É útil comparar primeiro as partes inteiras, porque isso é fácil.

Considere isto:

def less( (a,b), (c,d) ) = {
  // Compare integer parts first
  intA = a div b
  intC = c div d

  if intA < intB
    return True
  else if intA > intB
    return False
  else // intA == intB
    // Normalize to a number in [0,1]
    a = a mod b
    c = c mod d

    // Check for equality by reducing both
    // fractions to lowest terms
    (a,b) = lowestTerms(a,b)
    (c,d) = lowestTerms(c,d)

    if a == c and b == d
      return False
    else
      do
        // Compute next digits in decimal fraction 
        a = 10 * a
        c = 10 * c

        intA = a div b
        intC = c div d

        // Remove integer part again
        a = a mod b
        c = c mod d
      while intA == intC

      return intA < intC
    end
  end
}

Observe que o do-whileloop precisa terminar, pois os números são desiguais. Porém, não sabemos quanto tempo isso dura; se os números estiverem muito próximos, pode demorar um pouco.

10umadcb

Isso é rápido? Provavelmente não. Existem muitas divisões inteiras, módulos gdces para calcular, e temos um loop cujo número de iterações é inversamente proporcional à distância entre os números que comparamos.


O método auxiliar:

def lowestTerms(a,b) = {
  d = gcd(a,b)
  if d == 1
    return (a,b)
  else
    return lowestTerms(a div d, b div d)
  end
}
Rafael
fonte
uma/bc/dumadbcumadcb
@DavidRicherby Hm. Eu estava pensando principalmente em estouros - aqui, as operações têm menos probabilidade de criar grandes números.
Raphael