Daha çox

Çoxsaylı çoxbucaqlılar üçün çoxbucaqlı alqoritmdə işarə edin

Çoxsaylı çoxbucaqlılar üçün çoxbucaqlı alqoritmdə işarə edin


Üzərində bir çox poliqon olan bir Google xəritəm var.

Məni maraqlandıran bir problem budur: lat, lng nöqtəsi nəzərə alınaraq, bu nöqtənin yerləşdiyi bütün çoxbucaqlıları təyin etməyin ən yaxşı yolu nədir?

Aydın yol hər poliqon üçün "çoxbucaqlı nöqtə" alqoritmini iterativ şəkildə aparmaqdır, amma bu cür suallara cavab vermək üçün səmərəli bir alqoritmin olub-olmadığını düşünürdüm, xüsusən minlərlə çoxbucaqlınız varsa.


Bu sualların hamısında olduğu kimi, optimal yanaşma "istifadə halları" və xüsusiyyətlərin necə təmsil olunduğundan asılıdır. İstifadəsi halları bir qayda olaraq (a) hər təbəqədə çox və ya az obyekt olub-olmaması və (b) ya (ya da hər ikisi) qatın bəzi məlumat strukturlarını əvvəlcədən hesablamağa imkan verməsi ilə fərqlənir; yəni onlardan birinin və ya hər ikisinin əvvəlcədən hesablamaya qoyulan investisiyanın dəyərli olması üçün kifayət qədər statik və dəyişməz olması.

İndiki halda bu, aşağıdakı ssenariləri verir. Normalda bal dinamikdir: yəni əvvəlcədən verilmir. (Əvvəlcədən və ya çox böyük qruplarda varsa, bunların çeşidlənməsinə əsaslanan bəzi optimallaşdırmalar mövcud olacaq.) Q sorğu nöqtələrinin sayı və P çoxbucaqlının sayı zirvələr.

Vektorlu çoxbucaqlı məlumatlar

(1) Az nöqtə, bir neçə çoxbucaqlı təpə toto ilə. Klassik xətt bıçaqlama alqoritmi kimi kobud güc prosedurundan istifadə edin. Hər hansı bir uyğun metod üçün maliyyət O (P * Q) -dir, çünki bir nöqtəni çoxbucaqlı kənarla müqayisə etmək O (1) vaxta başa gəlir və bu cür müqayisələr aparılmalıdır.

(2) Ola bilsin ki, çoxbucaqlı təpələr, lakin bunlar dinamikdir: sorğuda hər dəfə bir nöqtə istifadə edildikdə, çoxbucaqlıların hamısı dəyişmiş ola bilər. Yenə də kobud bir güc alqoritmi istifadə edin. Maliyyət hələ də O (P * Q), çünki böyük olacaq P böyük olacaq, amma bunun üçün bir kömək yoxdur. Dəyişikliklər kiçik və ya nəzarətlidirsə (məs., çoxbucaqlar bir qədər dəyişir və ya sadəcə yavaşca hərəkət edir) növbəti həll variantını istifadə edə və poliqonlar dəyişdikcə məlumat strukturlarını yeniləməyin təsirli bir yolunu tapa bilərsiniz. Bu, ehtimal ki, orijinal araşdırma üçün bir məsələ ola bilər.

(3) Bir çox çoxbucaqlı zirvələr və statik çoxbucaqlar (yəni çoxbucaqlı təbəqə nadir hallarda dəyişəcək). Axtarışı dəstəkləmək üçün bir məlumat quruluşunu əvvəlcədən hesablayın (bir xətt təmizlənməsi və ya dörd ağac alqoritminə əsaslana bilər). Bu alqoritmlər üçün əvvəlcədən hesablama qiyməti O (P * log (P)), lakin sorğuların dəyəri O (Q * log (P)) olur, buna görə ümumi xərc O ((P + Q) * log ( P)).

Bəzi inkişaflar mövcuddur xüsusi hallar, kimi

(a) Bütün çoxbucaqlar qabarıqdır (poliqonların əvvəlcədən emalı daha tez edilə bilər),

(b) Bütün çoxbucaqlı interyerlər bir-birindən ayrılıb, bu halda onların birləşməsini tək bir çoxbucaqlı kimi düşünə bilərsiniz (bu, üçbucağa əsaslanan kimi birbaşa effektiv alqoritmlərə imkan verir və

(c) Əksər poliqonlar çox əyri deyil- yəni, məhdudlaşdırıcı qutularının böyük hissələrini tuturlar - bu halda yalnız məhdudlaşdırıcı qutulara əsaslanan ilkin bir test edə bilərsiniz və sonra bu həlli dəqiqləşdirə bilərsiniz. Bu məşhur bir optimallaşdırma.

(d) Xalların sayı çoxdur. Onları çeşidləmək vaxtı yaxşılaşdıra bilər. Məsələn, bir soldan sağa bir çoxbucaqlı nöqtə süpürmə alqoritmini tətbiq edərkən nöqtələri ilk koordinatındakı çeşidləyərək nöqtələri çoxbucaqlı kənarlarla süpürdüyünüz vaxt eyni zamanda süpürməyə imkan verərdiniz. Belə bir optimallaşdırmanın dərc olunduğundan xəbərdar deyiləm. Hərçənd nəşr olunanlardan biri, bütün nöqtələrin və çoxbucaqlı təpələrin birləşməsinin məhdud bir üçbucağını yerinə yetirməkdir: üçbucaq tamamlandıqdan sonra daxili nöqtələri müəyyənləşdirmək tez olmalıdır. Hesablama dəyəri O (Q * log (Q) + (P + Q) * log (P + Q)) olaraq ölçülür.

Raster poliqon məlumatları

Bu olduqca asandır: çoxbucaqlı təbəqəyə ikili göstərici raster kimi baxın (1 = çoxbucaq içərisində, 0 = çöldə). (Bunun üçün raster dəyərlərini daxili / xarici göstəricilərə çevirmək üçün axtarış cədvəli tələb oluna bilər.) Hər bir nöqtə sondası, raster hüceyrəsini indeksləşdirmək və dəyərini oxumaq üçün O (1) səyini tələb edir. Ümumi səy O (Q) -dir.

Ümumiyyətlə

Gözəl hibrid həll bir çox statik vektor çoxbucaqlı vəziyyətində (yuxarıdakı vektor 3-cü vəziyyət) əvvəlcə çoxbucaqlıları rastləşdirmək, bəlkə də kobud bir qətnamə ilə, bu dəfə çoxbucaqlı sərhədin hər hansı bir hissəsini kəsən hüceyrələri ayırmaqdır (deyək ki, onlara 2 dəyər verin) . Raster zonddan istifadə etmək (dəyəri: O (1)) ümumiyyətlə qəti cavabla nəticələnir (nöqtənin içərisində və xaricində olduğu bilinir), ancaq bəzən qeyri-müəyyən bir cavabla nəticələnir (nöqtə ən azı bir kənarın olduğu bir hüceyrəyə düşür) keçir), bu vəziyyətdə daha bahalı O (log (P)) vektor sorğusu edilir. Bu metod raster üçün əlavə saxlama xərcləri tələb edir, lakin bir çox hallarda kiçik bir raster də (bir MB 2000-dən 2000-ə qədər olan, 0,1,2, null} dəyər saxlayan bir raster üçün imkan verir) hesablama vaxtında böyük üstünlüklər verə bilər. . Asimptotik olaraq hesablama səyləri bir vektor həlli ilə eynidır, amma praktikada O (Q + P * log (P)) və ehtimal ki O (Q + P) qədər aşağıdır (üçün çox incə bir qətnamə istifadə edərək əldə edildi raster və yerinə yetirilməsi lazım olan çox nadir vektor sorğuları üçün kobud güc metodlarından istifadə etmək).


Dörd ağac kimi bir şeydə saxlanılan çoxbucaqlı məhdudlaşdırma qutuları olsaydı, hansını çox poliqonları yoxlayacağınızı tez müəyyənləşdirmək üçün istifadə edə bilərsiniz. Ən azı nöqtənin hər bir çoxbucaqlı üçün çoxbucaqlı bir nöqtə yerinə qoymağın əksinə hər bir çoxbucaqlı məhdudlaşdıran qutunun içində olub olmadığını görə bilərsiniz. Şəxsən mən yaddaşdakı çoxbucaqlıları önbelleğe alan və mənim üçün kəsişmə sorğusunu yerinə yetirmək üçün JTS və ya NetTopology paketi kimi bir şey istifadə edən bir veb xidmət qurardım.


Postgisdə ST_Intersects əvvəlcə nöqtənin çoxbucaqlının sərhəd qutusunun içində olub olmadığını tapmaq üçün indekslərdən istifadə edir və sonra həqiqətən çoxbucağın içində olub olmadığını yoxlamaq üçün yenidən yoxlama aparır. Bu sürətli, tez-tez çox sürətli.

Məlumatlarınızı PostGIS-də saxlamısınızsa, verilənlər bazasının hesablama üçün doğru yer olduğuna şübhə etməməlisiniz. Digər hallarda poliqonlarınızı orta və ya müştəri proqramına göndərməlisiniz. Bunun özü hesablamaları aparmaqdan daha çox vaxt alacaq və yalnız müvafiq poliqonları əldə edəcəkdir.

/ Nicklas


Videoya baxın: Çevrə və Dairə 24. Riyaziyyat Test Toplusu DİM 2019 1-ci Dərslər