Confronto di numeri razionali


12

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

ab<cdad<cb

Le mie domande sono:

Dato a,b,c,d

  1. Supponendo che possiamo decidere x<yZ in O(|x|+|y|) , esiste un modo per decidere ad<cb senza dover preformare le moltiplicazioni (o divisioni), ad e cb . O c'è una qualche prova che non c'è modo.
  2. Esiste un metodo più rapido per confrontare i numeri razionali che moltiplicare i denominatori.

1
@PKG ma la moltiplicazione richiederà più del tempo lineare. Penso che vogliamo qualcosa di più veloce per questa domanda.
Joe,

1
Il caso difficile è quando un intervallo ne contiene un altro, ad esempio [a,d][b,c] .
PKG,

1
Assumi implicitamente che e d abbiano lo stesso segno. Altrimenti, la direzione della disuguaglianza cambia. bd
Ran G.,

1
(1) La moltiplicazione è quasi lineare (ricerca dell'algoritmo di Fürer). (2) Un "numero intero razionale", almeno nel contesto della teoria dei numeri algebrica, in realtà significa solo un numero intero. Volete dire "numero razionale" o "numero razionale".
Yuval Filmus,

1
vedi anche il duplicato apparente Come confrontare i numeri razionali?
vzn

Risposte:


5

La mia ricerca attuale:

Tentativo iniziale di alcune regole generali

Si può provare a stabilire alcune regole generali per risolvere il confronto razionale:

Supponendo che tutti i positivi :a,b,c,d

a<bcdab<cd
Ciò significa fondamentalmente, se il lato sinistro è inferiore a uno e il lato destro è almeno uno, il lato sinistro è inferiore al lato destro. Nella stessa vena:

abcdabcd

Un'altra regola:

(b>d)(ac)[ab<cd]
Penso a questa regola come logica, poiché maggiore è il denominatore, minore è il numero, mentre maggiore è il numeratore, maggiore è il numero. Quindi se la parte sinistra ha un denominatore maggiore e un numeratore più piccolo, la sinistra sarà più piccola.

Da qui in avanti, supponiamo che , perché altrimenti possiamo risolverlo con le regole sopra o invertire la domanda in , e finiamo con questa condizione comunque.ca<cb<dcd<?ab

Regole : Questo La regola in sostanza afferma che è sempre possibile sottrarre i numeratori dai denominatori e impostare i risultati come numeratori per ottenere un problema equivalente. Lascio fuori la prova.

(ba)b<(dc)d[ab<cd]|a<c,b<d

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

Questa regola consente di sottrarre il numeratore e denominatore sinistro dal numeratore e denominatore destro per un problema equivalente.

E ovviamente c'è il ridimensionamento:

akbk<cd[ab<cd]|a<c,b<d
Tu può utilizzare il ridimensionamento per rendere più significative le regole di sottrazione riportate sopra.

Usando queste regole puoi giocare con le cose, applicarle ripetutamente, in combinazioni intelligenti, ma ci sono casi in cui i numeri sono vicini e patologici.

Applicando le regole precedenti, è possibile ridurre tutti questi problemi a:

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

A volte puoi risolverlo direttamente ora, a volte no. I casi patologici sono di solito nella forma:

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

Quindi lo capovolgi e ottieni la stessa cosa, solo con un po 'di meno. Ogni applicazione delle regole + vibrazione la riduce di una cifra / bit. AFAICT, non puoi risolverlo rapidamente, a meno che non applichi le regole volte (una volta per ogni cifra / bit) nel caso patologico, annullandone il vantaggio apparente.O(n)

Problema aperto ??

Mi sono reso conto che questo problema sembra essere più difficile di alcuni attuali problemi aperti.

Un problema ancora più debole è determinare:

ad=?bc

Eppure più debole:

ad=?c

Questo è il problema aperto della verifica della moltiplicazione . È più debole, perché se avessi un modo per determinare , allora puoi facilmente determinare , testando due volte con l'algoritmo, , . Iff è vero, lo sai che .a d ? = b c a d ? < b c b c ? < a dad<?bcad=?bcad<?bcbc<?adadbc

Ora, era un problema aperto, almeno nel 1986:ad=?c

La complessità della moltiplicazione e della divisione. Cominciamo con la semplicissima equazione ax = b. Se considerato su numeri interi, testare la sua solvibilità e trovare una soluzione x è possibile per divisione di numeri interi con resto zero. Per verificare una data soluzione x, sarà sufficiente la moltiplicazione dei numeri interi, ma è interessante sapere se esistono metodi di verifica più veloci.

- ARNOLD SCHÖNHAGE nella risoluzione di equazioni in termini di complessità computazionale

Molto interessante, ha anche menzionato la questione della verifica della moltiplicazione di matrici :

È anche interessante sapere se la verifica della moltiplicazione di matrici, vale a dire verificare se AB = G per una data C, potrebbe essere eseguita più velocemente.

- ARNOLD SCHÖNHAGE nella risoluzione di equazioni in termini di complessità computazionale

Questo è stato risolto da allora, ed è infatti possibile verificare in tempo con un algoritmo randomizzato (con la dimensione delle matrici di input, quindi è sostanzialmente lineare-tempo nel dimensione dell'input). Mi chiedo se sia possibile ridurre la moltiplicazione di numeri interi alla moltiplicazione di matrici, specialmente con le loro somiglianze, date le somiglianze di moltiplicazione di numeri interi di Karatsuba con gli algoritmi di moltiplicazione di matrici che seguirono. Quindi forse in qualche modo possiamo sfruttare l'algoritmo di verifica della moltiplicazione di matrici per la moltiplicazione di numeri interi.n × nO(n2)n×n

Ad ogni modo, dal momento che questo è ancora, a mia conoscenza, un problema aperto, il problema più forte di è sicuramente aperto. Sono curioso di sapere se la soluzione del problema di verifica dell'uguaglianza possa influire sul problema della verifica della disuguaglianza di confronto.ad<?cd

Una leggera variazione del nostro problema sarebbe se si garantisse che le frazioni fossero ridotte al minimo; in questo caso è facile dire se . Ciò può influire sulla verifica comparativa per le frazioni ridotte?ab=?cd

Una domanda ancora più sottile, e se avessimo un modo per testare , si estenderebbe al test di ? Non vedo come puoi usare questo "entrambi i modi" come abbiamo fatto per .a d ? = c a d ? < c dad<?cad=?cad<?cd

Relazionato:

  • Riconoscimento approssimativo delle lingue non regolari da parte degli automi finiti

    Fanno del lavoro sulla moltiplicazione approssimativa e sulla verifica randomizzata, che non capisco del tutto.

  • math.SE: come confrontare due moltiplicazioni senza moltiplicare?
  • Supponiamo che ci sia permesso di preelaborare quanto volevamo in tempo polinomiale, possiamo risolvere in tempo lineare?a b = ccab=c
  • Esiste un algoritmo di moltiplicazione di numeri interi non temporali lineare-tempo? Vedi http://compgroups.net/comp.theory/nondeterministic-linear-time-multiplication/1129399

    Esistono algoritmi ben noti per moltiplicare i numeri n-bit con qualcosa di simile alla complessità O (n log (n) log (log (n))). E non possiamo fare meglio di O (n) perché almeno dobbiamo guardare tutti gli input. La mia domanda è: possiamo effettivamente raggiungere O (n) per una classe adatta di algoritmi "non deterministici"?

    Più precisamente, esiste un algoritmo che può accettare due numeri binari n-bit "a" e "b" e un numero 2n-bit "c" e che ti dice in tempo O (n) se "a * b = c"? In caso contrario, esiste un'altra forma di certificato C (a, b, c) in modo tale che un algoritmo possa utilizzarlo per testare il prodotto in tempo lineare? Se non il tempo lineare, il problema del test del prodotto è almeno asintoticamente più semplice rispetto al calcolo? Qualsiasi risultato noto in tal senso sarebbe il benvenuto.

    John.

    -johnh4717


1

modmod 2mod 3q=k1a+k2b+k3c+k4d=kiakqO(|a|)

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

(Come renderlo più preciso?) La distanza dal cuboide alla superficie è generalmente illimitata, e quindi la superficie non può essere calcolata dal decisore


Mi dispiace non ho risposto a questo. Penso che questo potrebbe semplicemente essere al di sopra della mia comprensione, e nel frattempo sono stato impegnato nella ricerca di possibili risposte.
Realz Slaw,

1

Buona domanda. Accetteresti il ​​livello di fiducia?

Forse fare una divisione approssimativa. ie

Per calcolare i quozienti approssimativi limite di a / b, spostare a destra a per ceil (log_2 (b)) e anche per piano (log_2 (b)). Quindi sappiamo che il quoziente preciso è tra questi due valori.

Quindi, a seconda delle dimensioni relative dei quattro numeri interi, si potrebbe essere in grado di escludere determinati casi e ottenere la sicurezza del 100%.

Si può ripetere la procedura per radix diversa da 2, e con una successione di tali operazioni aumentare il livello di confidenza, fino a quando non si osserva in qualche modo un cambio di segno / pareggio?

Questo è il mio primo schizzo di un metodo.


O(n)O(nlogn)

ab=c

1

esiste un modo per decidere l'annuncio <cb senza preformare le moltiplicazioni [costose]

Sicuro.

Idea: confronta l'espansione decimale bit per bit.

L'unico aspetto negativo è che dobbiamo prima escludere l'uguaglianza perché altrimenti non potremmo terminare.
È utile prima confrontare le parti intere perché è facile.

Considera questo:

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
}

Si noti che il do-whileciclo deve terminare poiché i numeri non sono uguali. Tuttavia, non sappiamo per quanto tempo dura; se i numeri sono molto vicini, potrebbe volerci un po '.

10adcb

È veloce? Probabilmente no. Ci sono molti divisoni, moduli e gdcs interi da calcolare, e abbiamo un ciclo il cui numero di iterazioni è inversamente proporzionale alla distanza tra i numeri che confrontiamo.


Il metodo di supporto:

def lowestTerms(a,b) = {
  d = gcd(a,b)
  if d == 1
    return (a,b)
  else
    return lowestTerms(a div d, b div d)
  end
}

a/bc/dadbcadcb

@DavidRicherby Hm. Pensavo principalmente agli overflow: qui, le operazioni hanno meno probabilità di creare numeri enormi.
Raffaello
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.