2008-10-16 12 views
7

Poszukuję dobrego algorytmu, który da mi unikalne krawędzie z zestawu danych wielokąta. W tym przypadku wieloboki są definiowane przez dwie tablice. Jedna tablica to liczba punktów na wielokąt, a druga tablica to lista indeksów wierzchołków.Algorytm unikalnego znajdowania krawędzi z siatki wielokątnej

Mam wersję, która działa, ale wydajność osiąga powolność po osiągnięciu ponad 500 000 polys. Moja wersja przechodzi przez każdą twarz i dodaje posortowane wierzchołki każdej krawędzi do stl :: set. Mój zestaw danych będzie przede wszystkim polem trójkąta i kwadratu, a większość krawędzi zostanie udostępniona.

Czy istnieje mądrzejszy algorytm do tego?

Odpowiedz

4

Tak
Użyj podwójnej mapy mieszania.
Każda krawędź ma dwa indeksy A, B. powiedzmy, że A> B.
Pierwsza mapa map hash na najwyższym poziomie A do innej mapy hash, która z kolei odwzorowuje B na pewną wartość, która reprezentuje informacje, które chcesz o każdej krawędzi. (lub po prostu bool, jeśli nie potrzebujesz zachować informacji o krawędziach).
Zasadniczo tworzy to dwupoziomowe drzewo złożone z map skrótów.

Aby znaleźć krawędź w tej strukturze, należy wziąć większy indeks, wyszukać go na najwyższym poziomie i skończyć z mapą skrótu. następnie weź mniejszy indeks i sprawdź go w tej drugiej mapie skrótów.

+0

jeśli dobrze rozumiem, możesz skończyć z unikalnym poziomem hashmap pierwszy, ale z dużą ilością 2º poziomie hasms (jedna dla każdej wartości A). Zastanawiam się, czy hity 2º rzeczywiście pomagają, czy jest wystarczająco dużo wartości B na tych drugich hashmapach? – labotsirc

4

Właśnie w celu wyjaśnienia, chcesz, aby uzyskać listę wielokąta jak ten:

A +-----+ B 
    \ |\ 
    \ 1 | \ 
    \ | \ 
     \ | 2 \ 
     \| \ 
     C +-----+ D 

Wtedy zamiast krawędzi tak:

A - B -+ 
B - C +- first polygon 
C - A -+ 

B - D -+ 
D - C +- second polygon 
C - B -+ 

następnie chcesz usunąć duplikaty B - C vs .C - B krawędzi i dzielić się nim?

Jakie problemy z wydajnością występują w przypadku korzystania z algorytmu? Powiedziałbym, że zestaw, który ma rozsądną implementację skrótu, powinien wyglądać całkiem dobrze. Z drugiej strony, jeśli twój hash nie jest optymalny dla danych, będziesz mieć wiele kolizji, które mogą źle wpłynąć na wydajność.

2

Oboje jesteście poprawni. Korzystanie z dobrego hashitu osiągnęło wydajność znacznie przekraczającą wymagane poziomy. Skończyłem przetaczając mój własny mały zestaw haszyszu.

Łączna liczba krawędzi wynosi od N/2 do N. N oznacza liczbę unikalnych wierzchołków w siatce. Wszystkie wspólne krawędzie będą miały wartość N/2, a wszystkie unikalne krawędzie będą mieć wartość N. Z tego miejsca przydzielam bufor uint64 i pakuję moje indeksy do tych wartości. Używając niewielkiego zestawu unikatowych stołów mogę szybko znaleźć unikalne krawędzie!

0

Najpierw należy się upewnić, że wierzchołki są unikatowe. To znaczy, jeśli chcesz mieć tylko jedną krawędź w określonej pozycji. Następnie używać to struktura danych

typedef std::pair<int, int> Edge;

Edge sampleEdge;

std::map<Edge, bool> uniqueEdges;

krawędź zawiera indeksy wierzchołków, które tworzą przewagę w posortowanych. Stąd, jeśli sampleEdge jest krawędzią złożoną z wierzchołków o indeksach 12 i 5, sampleEdge.first = 5 i sampleEdge.12

Następnie można po prostu zrobić

uniqueEdges[sampleEdge] = true;

na wszystkich krawędziach. uniqueEdges pomieści wszystkie unikalne krawędzie.

1
Powiązane problemy