Come trovare il numero di punti con le stesse distanze minime sulla matrice

3

Sto cercando di trovare il numero di punti in una matrice con le stesse distanze minime.

Inizia con una matrice MxN, dove M e N < 50000. Vi è dato un insieme di punti fissi, con le loro rispettive coordinate.
Il problema è trovare il numero di punti nella matrice come la distanza minima da qualsiasi punto nel set può essere raggiunta per almeno due punti nel set. La distanza viene misurata spostando una unità per volta all'orizzonte o verticalmente. Non puoi muoverti diagonalmente.

Un esempio renderebbe le cose più chiare.
Diciamo che abbiamo 3 punti fissi: (1,3), (3,1) e (3,6). Qui il punto (3,3) sarebbe un punto poiché la distanza minima è di 2 unità e può essere raggiunta per i primi due punti fissi nell'insieme. Tuttavia, il punto (4,4) non soddisfa i requisiti. Sebbene la distanza tra (1,3) e (3,1) sia la stessa, 4 unità, la distanza minima è di 3 unità.

La mia idea era di usare qualsiasi punto con le coordinate intere che si trovano sulla bisettrice di un segmento che unisce ogni par come un punto che riempirebbe i nostri requisiti. Ma trovo molti falsi positivi se un punto soddisfa i requisiti, ma non giace sulla bisettrice perpendicolare.

I metodi a forza bruta non funzioneranno, perché è necessario controllare anche un miliardo di distanza per ogni punto e quel diavolo di lavoro da fare.

Come devo risolvere questo problema?

    
posta Stefan4024 19.03.2014 - 02:31
fonte

2 risposte

6

Come illustrato qui , quello che stai cercando è il 1 ° ordine 2 -dimensional diagramma di Voronoi sotto Manhattan o L1-metric . Questo è un problema abbastanza banale (da risolvere in modo efficiente), fortunatamente con molti algoritmi e software esistenti.

In realtà vuoi che il sottoinsieme del diagramma di Voronoi coincida con la griglia discreta definita dalle coordinate della matrice, ma è semplice trovare i punti del diagramma che hanno coordinate integrali.

I "punti fissi" sono chiamati siti, semi, generatori o punti sorgente in diversi contesti. Poiché il numero di siti è ridotto, è più appropriato utilizzare un algoritmo geometria computazionale , ovvero trovare un vector rappresentazione dei segmenti di linea del diagramma, indipendentemente dalla dimensione della matrice (per 10 siti, dovrebbe essere estremamente veloce).

Una libreria altamente riconosciuta è CGAL , che include un gran numero di algoritmi di geometria computazionale in C ++ e in particolare 2D segmenti grafici Delaunay (diagrammi di Voronoi) . Il manuale utente parla solo della distanza euclidea, ma c'è anche una demo del diagramma di Voronei L1 , quindi spero che troverai la tua strada.

Un'altra prospettiva è una rappresentazione raster , usando algoritmi che spazzano l'intero piano (la tua matrice) una volta, in un ordine particolare simile alla propagazione delle onde. Questo è consigliato se il numero di siti è grande, formando forme arbitrarie sul piano. È correlato alla trasformazione a distanza , asse mediale e lo scheletro topologico . Le ultime due sono generalizzazioni del diagramma di Voronoi, in quanto consistono in curve piuttosto che in segmenti di linea in generale, indipendentemente dalla metrica.

Un'ottima soluzione in questa prospettiva è le trasformazioni di distanza delle funzioni campionate , dando anche codice sorgente . Questo è limitato al calcolo della distanza trasformata e alle metriche di distanza separabili per esempio al quadrato Euclideo o L1 (il tuo caso).

Per trovare l'asse mediale dato la trasformazione della distanza, una buona scelta è il mio rivelatore di feature mediale , con codice binario disponibile . Questo lavoro utilizza anche un metodo alternativo per il calcolo della trasformazione della distanza che non ha limiti sulla metrica della distanza. È più lento del precedente ma è ancora lineare rispetto alla dimensione del dominio (la tua matrice). Il calcolo dell'asse mediale stesso è estremamente veloce (tempo lineare sul numero di punti dell'asse mediale).

Asse mediale 2D sotto metrica euclidea http://image.ntua.gr/iva/tools /mfd/fig/biarcs_med_res.png

Ad esempio, puoi dare un'occhiata a questa immagine , dove bianco i punti sono i siti (in realtà formano una curva chiusa sul piano) e le curve rosso-giallastre sono l'asse mediano (euclideo). Nota che questi ultimi hanno una precisione sub-pixel, cioè appaiono come curve anti-alias ad 1 pixel di pixel, sebbene i siti di input no. Questo dimostra che hai le informazioni richieste (posizione esatta) per scoprire se un punto candidato sull'asse mediale ha o meno coordinate integrali. Per avere un'idea della velocità, questo risultato è stato generato in circa 300 ms.

Se ti preoccupi dell'efficienza, il mio consiglio è di cercare algoritmi o codici esistenti. Se insisti sulla tua implementazione, dovrai leggere molto prima, in modo da avere una buona comprensione del problema.

    
risposta data 15.04.2014 - 23:07
fonte
0

Puoi facilmente vedere che se un punto che stai cercando è alla stessa distanza da due o più punti, allora devono essere tutti a una distanza tale che d (a, b) è pari.

Dato questo, puoi scorrere tutte le coppie {a, b} di punti fissi e aggiungere alla tua serie di punti di risultato tutti i punti matrice che sono la metà della distanza d (a, b) da entrambi i punti che Ho scelto. Per farlo, considera i due "cerchi" (nella tua geometria è un quadrato inclinato) di raggio d (a, b) / 2 e centro a e b. Tutti i punti matrice che appartengono a entrambi i cerchi sono probabilmente dei buoni punti per te.

Ora devi verificare se tutti i punti che hai trovato nel passaggio precedente sono effettivamente positivi o falsi positivi. Per farlo, basta scorrere il set di risultati e controllare le distanze da tutti i punti fissi.

L'algoritmo dovrebbe essere abbastanza veloce dato che hai al massimo 10 punti fissi

    
risposta data 26.03.2014 - 15:07
fonte

Leggi altre domande sui tag