2012-12-19 7 views
6

Mam 2 listy z X, Y współrzędne punktów. Lista 1 zawiera więcej punktów niż lista 2.Znaleźć najlepsze pasujące pary punktów z 2 wektorów

Zadaniem jest znalezienie par punktów w taki sposób, aby zminimalizować ogólną odległość euklidesową.

Mam działający kod, ale nie wiem, czy to jest najlepszy sposób i chciałbym uzyskać podpowiedź, co mogę poprawić dla wyniku (lepszy algorytm do znalezienia minimum) lub szybkość, ponieważ lista jest około 2000 elementów każdy.

Runda w wektorach próbkowania jest zaimplementowana, aby uzyskać także punkty o tych samych odległościach. W funkcji "rdist" wszystkie odległości są generowane w "odległościach". Niż minimum w macierzy służy do połączenia 2 punktów ("dist_min"). Wszystkie odległości od tych 2 punktów zostaną teraz zastąpione przez NA i pętla będzie kontynuowana przez przeszukanie następnego minimum, aż wszystkie punkty listy 2 będą miały punkt z listy 1. Na końcu dodałem wykres do wizualizacji.

require(fields) 

set.seed(1) 
x1y1.data <- matrix(round(runif(200*2),2), ncol = 2) # generate 1st set of points 
x2y2.data <- matrix(round(runif(100*2),2), ncol = 2) # generate 2nd set of points 

distances <- rdist(x1y1.data, x2y2.data) 
dist_min <- matrix(data=NA,nrow=ncol(distances),ncol=7) # prepare resulting vector with 7 columns 

for(i in 1:ncol(distances)) 
{ 
    inds <- which(distances == min(distances,na.rm = TRUE), arr.ind=TRUE) 

    dist_min[i,1] <- inds[1,1]    # row of point(use 1st element of inds if points have same distance) 
    dist_min[i,2] <- inds[1,2]    # column of point (use 1st element of inds if points have same distance) 
    dist_min[i,3] <- distances[inds[1,1],inds[1,2]] # distance of point 
    dist_min[i,4] <- x1y1.data[inds[1,1],1]  # X1 ccordinate of 1st point 
    dist_min[i,5] <- x1y1.data[inds[1,1],2]  # Y1 coordinate of 1st point 
    dist_min[i,6] <- x2y2.data[inds[1,2],1]  # X2 coordinate of 2nd point 
    dist_min[i,7] <- x2y2.data[inds[1,2],2]  # Y2 coordinate of 2nd point 

    distances[inds[1,1],] <- NA # remove row (fill with NA), where minimum was found 
    distances[,inds[1,2]] <- NA # remove column (fill with NA), where minimum was found 
} 

# plot 1st set of points 
# print mean distance as measure for optimization 
plot(x1y1.data,col="blue",main="mean of min_distances",sub=mean(dist_min[,3],na.rm=TRUE))  
points(x2y2.data,col="red")       # plot 2nd set of points 
segments(dist_min[,4],dist_min[,5],dist_min[,6],dist_min[,7]) # connect pairwise according found minimal distance 

output with min distance

+0

Znalezienie pytania o ciemne materię kaggle, być może? –

+0

Pseudo kod byłby łatwy do napisania: 'for (i in 1st.set.points) {for (j in j 2nd.set.points) {oblicz: sqrt ((x1st.set.ponint-x2nd.set.points)^2 + (y1st.set.ponint-y2nd.set.points)^2), zapisz każdą wynikową wartość, a następnie wywołaj funkcję min(), aby określić, która ma najniższą wartość}} ' –

+0

Witam java_xof, myślę, że tak jak ja zrobili.? 'odległości <- rdist (x1y1.data, x2y2.data) dostarcza macierzy wszystkich odległości i' które (odległości == min (odległości, na.rm = TRUE), arr.ind = TRUE) wyszukuje miny w macierz. Ale na wypadek, gdyby były pary o tej samej min. odległość Nie wiem, którą parę wybrać. – user1716533

Odpowiedz

7

Jest to podstawowy problem w optymalizacji kombinatorycznej zwanej assignment problem. Jednym ze sposobów rozwiązania problemu przydziału jest Hungarian algorithm który jest realizowany w trop pakietu R:

require(clue) 
sol <- solve_LSAP(t(distances)) 

Możemy sprawdzić, czy wyprzedza naiwne rozwiązanie:

mean(dist_min[,3]) 
# [1] 0.05696033 
mean(sqrt(
    (x2y2.data[,1] - x1y1.data[sol, 1])^2 + 
    (x2y2.data[,2] - x1y1.data[sol, 2])^2)) 
#[1] 0.05194625 

I możemy skonstruować podobną działkę do tego w swoim pytaniu:

plot(x1y1.data,col="blue")  
points(x2y2.data,col="red") 
segments(x2y2.data[,1], x2y2.data[,2], x1y1.data[sol, 1], x1y1.data[sol, 2]) 

enter image description here

+0

dzięki orizon, wykres pokazuje znaczną poprawę "prostego" algorytmu, ponieważ wiele długich linii można wyeliminować. – user1716533

+0

@ user1716533 to było miłe pytanie. Interesujące jest to, gdzie dokonuje się ulepszeń. Większość bardzo długich odległości w prostym podejściu jest przypisywana bardzo późno w algorytmie, gdy wszystkie dobre miejsca są brane. Prawdopodobnie moglibyśmy poprawić proste podejście, tasując punkty i uruchamiając algorytm kilka razy - ale nie ma większego powodu, aby istnieć implementacje wydajnych i optymalnych algorytmów. – orizon

Powiązane problemy