Saya memiliki kotak ubin dengan ukuran terbatas yang diketahui yang membentuk peta. Beberapa ubin di dalam peta dimasukkan ke dalam set yang dikenal sebagai wilayah. Wilayah ini terhubung, tetapi tidak ada yang diketahui tentang bentuknya. Sebagian besar waktu akan menjadi gumpalan yang cukup teratur, tetapi bisa sangat memanjang dalam satu arah, dan bahkan berpotensi memiliki lubang. Saya tertarik menemukan perbatasan (luar) wilayah tersebut.
Yaitu, saya ingin daftar semua ubin yang menyentuh salah satu ubin di wilayah itu tanpa dirinya berada di wilayah itu. Apa cara yang efisien untuk menemukan ini?
Untuk kesulitan tambahan, kebetulan bahwa ubin saya adalah heks, tapi saya menduga ini tidak membuat banyak perbedaan, setiap ubin masih diberi label dengan bilangan bulat x dan koordinat y dan, mengingat ubin, saya dapat dengan mudah menemukan tetangganya. Berikut adalah beberapa contoh: Hitam adalah wilayah, dan biru yang ingin saya temukan di perbatasan. Ini sendiri, bukan masalah yang sulit, Satu algoritma sederhana untuk ini, dalam pseudo-python, adalah:
def find_border_of_territory(territory):
border = []
for tile in territory:
for neighbor in tile.neighbors():
if neighbor not in territory and neighbor not in border:
border.add(neighbor)
Namun ini lambat dan saya ingin sesuatu yang lebih baik. Saya memiliki O (n) loop di atas wilayah, loop lain (yang pendek, tapi masih) di atas semua tetangga, dan kemudian saya harus memeriksa keanggotaan lebih dari dua daftar, yang salah satunya berukuran n. Itu memberikan skala O yang mengerikan (n ^ 2). Saya dapat menguranginya menjadi O (n) dengan menggunakan set alih-alih daftar untuk perbatasan dan wilayah sehingga keanggotaan cepat untuk memeriksa, tetapi masih tidak bagus. Saya berharap akan ada banyak kasus di mana wilayahnya besar tetapi perbatasannya kecil karena area sederhana vs penskalaan garis. Misalnya jika wilayah tersebut adalah heksa jari-jari 5, ukurannya 91 tetapi batasnya hanya ukuran 36.
Adakah yang bisa mengusulkan sesuatu yang lebih baik?
Edit:
Untuk menjawab beberapa pertanyaan di bawah ini. Wilayah ini dapat berkisar dalam ukuran, dari sekitar 20 hingga 100 atau lebih. Himpunan ubin yang membentuk wilayah adalah atribut dari suatu objek, dan objek inilah yang membutuhkan serangkaian semua ubin perbatasan.
Awalnya wilayah itu dibuat sebagai blok, dan kemudian sebagian besar mendapatkan ubin satu per satu. Dalam hal ini, memang benar bahwa cara tercepat adalah hanya dengan menjaga satu set perbatasan dan hanya memperbaruinya pada ubin yang diperoleh. Kadang-kadang perubahan besar pada wilayah mungkin terjadi - jadi itu perlu dihitung ulang sepenuhnya.
Saya sekarang berpendapat bahwa melakukan algoritma pencarian perbatasan sederhana adalah solusi terbaik. Satu-satunya kompleksitas tambahan yang timbul adalah untuk memastikan bahwa perbatasan dihitung ulang setiap kali mungkin perlu, tetapi tidak lebih dari itu. Saya cukup yakin bahwa ini dapat dilakukan dengan andal dalam kerangka kerja saya saat ini.
Adapun waktu, dalam kode saya saat ini, saya memiliki beberapa rutinitas yang perlu memeriksa setiap ubin wilayah. Tidak setiap belokan, tetapi pada penciptaan dan kadang-kadang sesudahnya. Itu membutuhkan lebih dari 50% dari waktu berjalan sesuai kode tes saya meskipun itu adalah bagian yang sangat kecil dari program lengkap. Karena itu saya ingin meminimalkan pengulangan. NAMUN, kode tes melibatkan lebih banyak pembuatan objek daripada menjalankan normal program (secara alami), jadi saya menyadari ini mungkin tidak terlalu relevan.