Un algoritmo per risolvere un semplice (?) Problema di matrice

voti
7

Per questa velocità problema è abbastanza cruciale. Ho disegnato una bella immagine per spiegare meglio il problema. L'algoritmo deve calcolare se i bordi di un rettangolo continuano entro i confini della tela, si intersecano il bordo un altro rettangolo?

Sappiamo:

  1. La dimensione della tela
  2. La dimensione di ciascun rettangolo
  3. La posizione di ciascun rettangolo

Il più veloce la soluzione è la migliore! Sono abbastanza bloccato su questo e non so davvero da dove cominciare.

alt text http://www.freeimagehosting.net/uploads/8a457f2925.gif

Saluti

È pubblicato 08/07/2010 alle 13:23
fonte dall'utente
In altre lingue...                            


6 risposte

voti
2

Le linee non parallele tra di loro stanno per incrociarsi ad un certo punto. Calcolare i pendii di ogni linea e quindi determinare quali linee che non si intersecano con.

Inizia con questo, e poi vediamo come ottimizzare esso. Non sono sicuro di come i dati sono rappresentati e non riesco a vedere la vostra immagine.

Utilizzando piste è un semplice controllo di uguaglianza che probabilmente significa che è possibile usufruire di smistamento dei dati. In realtà, probabilmente si può solo creare una serie di piste distinte. Dovrete capire come rappresentare i dati tali che i due versanti dello stesso rettangolo non sono contati come si intersecano.

EDIT: aspetta .. come possono due rettangoli i cui bordi andare all'infinito si intersecano? Rettangoli sono fondamentalmente due linee perpendicolari tra loro. Non dovrebbe significare che si interseca sempre con un altro, se quelle linee si estendono all'infinito?

Risposto il 08/07/2010 a 13:35
fonte dall'utente

voti
6

Basta creare il set di intervalli per ciascuna delle X e l'asse Y. Poi per ogni nuovo rettangolo, se esistono intervalli intersecano in X o Y. Vedi qui per una modalità di applicazione insiemi intervallo.

Nel primo esempio, l'intervallo impostato sull'asse orizzontale sarebbe { [0-8], [0-8], [9-10] }, e sulla verticale:{ [0-3], [4-6], [0-4] }

Questo è solo un riassunto, mi astratte molti dettagli qui (per esempio, di solito ci si chiederà un intervallo set / albero "che si sovrappongono gli intervalli di questo", invece di "interseca questo uno", ma niente non è fattibile).

modificare

Si prega di guardare questo correlata conferenza MIT (è un po 'lungo, ma assolutamente valga esso). Anche se si trova soluzioni più semplici (di attuazione di un albero rosso-nero aumentata), è bene conoscere le idee che stanno dietro queste cose.

Risposto il 08/07/2010 a 13:36
fonte dall'utente

voti
1

finché lei non ha citato la lingua si è scelto di risolvere il problema, userò una sorta di pseudo codice

l'idea è che se tutto è ok, allora una raccolta differenziata dei bordi del rettangolo lungo un asse dovrebbe essere una sequenza di intervalli non sovrapposti.

  1. numero tutti i rettangoli, assegnando loro i singoli ids
  2. creare una collezione albero binario vuoto (BTC). questa raccolta dovrebbe avere un metodo per inserire un nodo intero con informazioni BTC :: insert (chiave, valore)
  3. per tutti i rettangoli, fare:

foreach rect in rects do
    btc.insert(rect.top, rect.id)
    btc.insert(rect.bottom, rect.id)
  1. ora scorrere l'BTC (questo vi darà un ordinamento)

btc_item = btc.first()
do
    id = btc_item.id
    btc_item = btc.next()
    if(id != btc_item.id)
    then report_invalid_placement(id, btc_item.id)
    btc_item = btc.next()
while btc_item is valid

5,7,8 - ripetere i passi 2,3,4 per rect.left e rect.right coordinate

Risposto il 08/07/2010 a 13:49
fonte dall'utente

voti
1

Mi piace questa domanda. Qui è il mio tentativo di ottenere su di esso:

Se possibile: creare un poligono da ogni rettangolo. Trattare ogni spigolo come linea di lunghezza massima che deve essere agganciato. Utilizzare un algoritmo di ritaglio per controllare il meteo o meno una linea interseca con un altro. Per esempio questo: Linea Clipping

Ma tenere a mente: Se si trova un incrocio che si trova alla posizione di vertice, la sua uno valido.

Risposto il 08/07/2010 a 14:01
fonte dall'utente

voti
1

Ecco un'idea. Invece di creare ciascun rettangolo con (x, y, width, height), loro istanziare con (x1, y1, x2, y2), o almeno avere lo interpreta questi valori riportati larghezza e altezza.

In questo modo, è possibile verificare quali rettangoli hanno una simile xo ydi valore e assicurarsi che il rettangolo corrispondente ha lo stesso valore secondario.


Esempio:

I rettangoli che avete dato hanno i seguenti valori:

  • Square 1: [0, 0, 8, 3]
  • Piazza 3: [0, 4, 8, 6]
  • Square 4: [9, 0, 10, 4]

In primo luogo, si confronta Square 1a Square 3(collisione):

  • Confrontare i valori x
    • [0, 8] a [0, 8] Questi sono esattamente gli stessi, quindi non c'è crossover.
  • Confrontare i valori y
    • [0, 4] a [3, 6] Nessuno di questi numeri sono simili, quindi non sono un fattore

Avanti, mettiamo a confronto Square 3a Square 4(collisione):

  • Confrontare i valori x
    • [0, 8] a [9, 10] Nessuno di questi numeri sono simili, quindi non sono un fattore
  • Confrontare i valori y
    • [4, 6] a [0, 4] I rettangoli hanno il numero 4 in comune, ma 0! = 6, pertanto, non v'è una collisione

Con un know sappiamo che si verifichi una collisione, in modo che il metodo si concluderà, ma permette di valutare Square 1e Square 4per un po 'di chiarezza in più.

  • Confrontare i valori x
    • [0, 8] a [9, 10] Nessuno di questi numeri sono simili, quindi non sono un fattore
  • Confrontare i valori y
    • [0, 3] a [0, 4] I rettangoli hanno il numero 0 in comune, ma 3! = 4, pertanto, non v'è una collisione

Fatemi sapere se avete bisogno di dettagli in più :)

Risposto il 08/07/2010 a 14:08
fonte dall'utente

voti
0

Heh, prendendo gli intervalli sovrapposti rispondono alle estreme, è sufficiente determinare tutti gli intervalli distinti lungo l'asse x ed y. Per ciascuna linea di taglio, fare una ricerca limite superiore lungo l'asse che taglierà in base al valore iniziale del intervallo. Se non trovate un intervallo o l'intervallo non interseca la linea, allora è una linea valida.

La parte leggermente difficile è rendersi conto che le linee di taglio valide non intersecare limiti di un rettangolo lungo un asse, in modo da poter combinare intervalli sovrapposti in un singolo intervallo. Si finisce con un semplice array ordinato (che si compila in O (n)) e una O (log n) la ricerca di ogni linea di taglio.

Risposto il 09/07/2010 a 07:53
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more