Siklus dalam perangkat lunak hierarki keluarga

1594

Saya adalah pengembang beberapa perangkat lunak silsilah keluarga (ditulis dalam C ++ dan Qt). Saya tidak punya masalah sampai salah satu pelanggan saya mengirimi saya laporan bug. Masalahnya adalah bahwa pelanggan memiliki dua anak dengan putri mereka sendiri, dan, akibatnya, ia tidak dapat menggunakan perangkat lunak saya karena kesalahan.

Kesalahan-kesalahan itu adalah hasil dari berbagai pernyataan dan invarian saya tentang grafik keluarga yang sedang diproses (misalnya, setelah berjalan satu siklus, program menyatakan bahwa X tidak bisa menjadi ayah dan kakek dari Y).

Bagaimana saya bisa menyelesaikan kesalahan-kesalahan itu tanpa menghapus semua pernyataan data?

Partick Höse
sumber
30
Jika Anda melacak pohon keluarga Anda cukup jauh ke belakang, Anda akan mengenai masalah ini jauh lebih sering daripada yang Anda inginkan. Meninggalkan perwakilan pohon mungkin menyakitkan tetapi pada akhirnya akan lebih benar.
Thomas
55
Anda seharusnya tidak menambahkan pernyataan untuk hal-hal yang tidak biasa, hanya hal-hal yang tidak mungkin. Siklus adalah hal-hal nyata yang tidak mungkin dalam grafik silsilah keluarga ... tidak ada yang bisa menjadi leluhurnya sendiri melalui metode apa pun. Pernyataan lain ini hanya palsu dan harus dihapus.
pgod
44
Ini sama sekali bukan pertanyaan konyol di dunia pembiakan hewan peliharaan. Anak perempuan ke ayah, ibu ke anak laki-laki, saudara perempuan ke saudara laki-laki, cucu sampai kakek-nenek adalah teknik standar di sana, dan peternak peliharaan memerlukan perangkat lunak silsilah keluarga juga. "Murni-murni" my ¤% # &.
kaleissin
31
Menikah dengan sepupu pertama sangat umum di Inggris Victoria, terutama di kalangan kelas atas (itu adalah cara terbaik untuk menyimpan uang di dalam keluarga). Charles Darwin, misalnya, menikahi sepupu pertamanya, Emma Wedgwood. Perangkat lunak silsilah keluarga apa pun perlu mendukung situasi seperti ini.
rtperson

Jawaban:

727

Tampaknya Anda (dan / atau perusahaan Anda) memiliki kesalahpahaman mendasar tentang apa yang seharusnya menjadi silsilah keluarga.

Izinkan saya mengklarifikasi, saya juga bekerja untuk sebuah perusahaan yang memiliki (sebagai salah satu produknya) silsilah keluarga dalam portofolionya, dan kami telah berjuang dengan masalah yang sama.

Masalahnya, dalam kasus kami, dan saya menganggap kasus Anda juga, berasal dari format GEDCOM yang sangat beralasan tentang apa yang seharusnya menjadi sebuah keluarga. Namun format ini mengandung beberapa kesalahpahaman yang parah tentang seperti apa sebenarnya silsilah keluarga.

GEDCOM memiliki banyak masalah, seperti ketidakcocokan dengan hubungan seks yang sama, inses, dll ... Yang dalam kehidupan nyata lebih sering terjadi daripada yang Anda bayangkan (terutama ketika kembali ke masa 1700-1800).

Kami telah memodelkan silsilah keluarga kami dengan apa yang terjadi di dunia nyata: Peristiwa (misalnya, kelahiran, pernikahan, pertunangan, serikat pekerja, kematian, adopsi, dll.). Kami tidak membatasi hal ini, kecuali untuk hal-hal yang mustahil secara logis (misalnya, seseorang tidak dapat menjadi orang tua sendiri, hubungan memerlukan dua individu, dll ...)

Kurangnya validasi memberi kita solusi yang lebih "dunia nyata", lebih sederhana dan lebih fleksibel.

Adapun kasus khusus ini, saya akan menyarankan menghapus pernyataan karena mereka tidak berlaku secara universal.

Untuk menampilkan masalah (yang akan muncul) saya sarankan menggambar simpul yang sama sebanyak yang diperlukan, mengisyaratkan duplikasi dengan menerangi semua salinan pada memilih salah satu dari mereka.

Bert Goethals
sumber
32
Ini terlihat seperti pendekatan yang tepat, dan cukup mudah untuk memperluas untuk mendeteksi masalah yang lebih kompleks. Anda dapat menentukan serangkaian hubungan "A terjadi sebelum B" di antara berbagai peristiwa. Misalnya, seseorang dilahirkan sebelum peristiwa lain yang melibatkan mereka. Ini adalah grafik berarah. Anda kemudian dapat memeriksa bahwa grafik tidak mengandung siklus. Lihat pertanyaan ini di StackOverflow. Ini harus ok sampai perjalanan waktu ditemukan.
Paul Harrison
41
@ paul-harrison Kalau di situ saja sesederhana itu. Dalam catatan yang lebih lama (bahkan yang baru) ada ketidakkonsistenan tanggal. Baptisan sebelum kelahiran, banyak catatan kelahiran dll ... Jadi sampai batas tertentu, dalam catatan resmi, ada perjalanan waktu. Kami mengizinkan data yang tidak konsisten ini. Kami mengizinkan pengguna untuk menunjukkan aplikasi apa yang harus dipertimbangkan "catatan kelahiran" jika terjadi duplikat. Dan kami akan menunjukkan garis waktu yang rusak jika ditemukan.
Bert Goethals
38
@ ben-voigt GEDCOM adalah format yang dibuat oleh Gereja Yesus Kristus dari Orang-Orang Suci Zaman Akhir. Spesifikasi tersebut dengan jelas menyatakan bahwa pernikahan (MARR) adalah antara pria dan wanita. Untuk pernikahan sesama jenis atau inses, tag ASSO harus digunakan (ASSOCIATES), juga digunakan untuk menunjukkan persahabatan atau menjadi tetangga. Jelas pernikahan sesama jenis adalah hubungan kelas dua dalam spesifikasi ini. Spesifikasi yang lebih netral tidak akan menuntut hubungan perempuan laki-laki.
Bert Goethals
1
@Bert Goethals: Anda membingungkan GEDCOM dengan program tertentu yang tidak mendukung pernikahan sesama jenis (PAF, Legacy). GEDCOM tidak menghalangi konstruksi seperti "0 @ F1 @ FAM / 1 HUSB @ I1 @ / 1 HUSB @ I2 @", dan dengan demikian mendukung pernikahan sesama jenis jika perangkat lunak Anda memilih untuk melakukannya.
Pierre
1
@Pierre Anda memang bisa menipu sistem. Ini secara langsung dari dokumen 5.5.1: "MARR {MARRIAGE}: = Acara hukum, hukum adat, atau kebiasaan untuk menciptakan unit keluarga pria dan wanita sebagai suami dan istri." ( homepages.rootsweb.ancestry.com/~pmcbride/gedcom/55gcappa.htm ) Seperti yang Anda lihat, tidak ada pernikahan sesama jenis di sini.
Bert Goethals
563

Santai pernyataan Anda.

Bukan dengan mengubah aturan, yang kemungkinan besar sangat membantu 99,9% pelanggan Anda dalam menangkap kesalahan dalam memasukkan data mereka.

Alih-alih, ubah dari kesalahan "tidak dapat menambahkan hubungan" menjadi peringatan dengan "tambahkan pula".

Ben Voigt
sumber
143
Ketika menghadapi situasi yang sangat tidak mungkin , yaitu, di mana pengguna biasanya hanya akan melakukannya secara tidak sengaja, itu adalah ide yang baik untuk menunjukkan peringatan kepada pengguna. Itu umpan balik yang bagus. Tetapi kemudian biarkan pengguna melanjutkan jika mereka benar - benar yakin mereka mau. Jadi saya pikir ini adalah jawaban yang baik, bahkan jika itu tidak masuk akal.
thomasrutter
15
Jawaban yang bagus! Saya hanya ingin tahu, bagaimana perangkat lunak semacam ini akan menangani situasi "Saya adalah kakek saya sendiri" ( youtube.com/watch?v=eYlJH81dSiw )?
Zaur Nasibov
4
Ini sebenarnya bukan jawaban, karena saya pikir masalahnya berasal dari benar-benar melintasi pohon? Namun, itu saran yang bagus.
bdwakefield
3
@bdwakefield: Pertanyaannya adalah "Bagaimana cara mengatasi kesalahan ini, tanpa menghapus semua pernyataan data?" Saya yakin saya sudah menjawabnya.
Ben Voigt
2
@ Ben Itu tergantung pada apa asersi untuk. Jika mereka mencegah loop tak terbatas atau kesalahan fatal terjadi, maka Anda secara efektif menyarankan untuk menghapus pernyataan. Jika mereka ada di sana untuk memperingatkan pengguna akan kesalahan potensial, maka jawaban Anda adalah yang bagus.
rm999
224

Inilah masalah dengan pohon keluarga: mereka bukan pohon. Mereka diarahkan grafik asiklik atau DAG. Jika saya memahami prinsip-prinsip biologi reproduksi manusia dengan benar, tidak akan ada siklus.

Sejauh yang saya tahu, bahkan orang Kristen menerima pernikahan (dan dengan demikian anak-anak) antara sepupu, yang akan mengubah pohon keluarga menjadi DAG keluarga.

Moral dari cerita ini adalah: pilih struktur data yang tepat.

exDM69
sumber
7
Dibutuhkan pembatasan lebih lanjut dari setiap simpul yang memiliki 1 atau 2 simpul maksimum yang menunjuk padanya untuk reproduksi in vitro dan seksual. Meskipun untuk menjadi lebih benar pada kehidupan nyata, Anda mungkin mengizinkan beberapa garis putus-putus untuk keturunan yang tidak pasti di pihak ayah (selalu jelas siapa ibu itu, tetapi hanya tes DNA yang bisa memastikan siapa ayahnya, dan itu jarang dilakukan bahkan hari ini), atau bahkan untuk keduanya adopsi diperhitungkan.
manixrock
7
@manixrock - karena pertanyaan ini tentang kasus yang jarang terjadi, saya ingin menegaskan bahwa tidak selalu jelas siapa ibunya. adopsi, bayi terlantar, ibu pengganti, dll semuanya dapat memperumit masalah.
Peter Recore
9
Itu belum tentu asiklik, kan? Menikah-nenek-nenek.
Ed Ropple
13
Pria menikahi neneknya tidak akan menjadikan dirinya kakeknya sendiri dan menambahkan siklus. Jika mereka memiliki anak, itu akan menjadi tepi grafik biasa yang tidak dapat bersepeda.
exDM69
11
Sebenarnya DUA ADG. Ada grafik asal dan grafik hubungan hukum. Biasanya sama, tetapi berbeda dari yang mungkin diharapkan.
JSacksteder
115

Saya kira Anda memiliki beberapa nilai yang secara unik mengidentifikasi seseorang di mana Anda dapat mendasarkan cek Anda.

Ini yang sulit. Dengan asumsi Anda ingin menjaga struktur pohon, saya sarankan ini:

Asumsikan ini: Apunya anak dengan putrinya sendiri.

Amenambahkan dirinya ke program sebagai Adan sebagai B. Begitu berperan sebagai ayah, sebut saja pacarnya.

Tambahkan is_same_for_out()fungsi yang memberi tahu bagian penghasil output dari program Anda bahwa semua tautan akan dilihat secara Binternal Apada presentasi data.

Ini akan membuat beberapa pekerjaan tambahan bagi pengguna, tapi saya kira TI akan relatif mudah diimplementasikan dan dipelihara.

Membangun dari itu, Anda dapat bekerja pada sinkronisasi kode Adan Buntuk menghindari inkonsistensi.

Solusi ini tentu saja tidak sempurna, tetapi merupakan pendekatan pertama.

Eduard Thamm
sumber
9
Mungkin simpul "proxy" semacam itu memang solusi yang cocok. Namun saya tidak tahu bagaimana mereka bisa dimasukkan ke dalam antarmuka pengguna tanpa menyinggung pengguna. Saya dapat memberitahu Anda bahwa menulis perangkat lunak yang berhubungan dengan orang sungguhan (terutama pelanggan Anda) tidak mudah.
Partick Höse
6
Itu tidak pernah berakhir - putra baru B akan menjadi pamannya sendiri. Saya akan mempertimbangkan pengembalian dana penuh untuk program ini!
Bo Persson
3
@Apakah A: Dan kemudian menyadari bahwa dia juga ibunya sendiri, dan merekrut dirinya yang lebih muda ke dalam agensi waktu?
Null Set
2
Duplikasi (dan sinkronisasi) data dalam satu sistem adalah praktik yang buruk. Ini menunjukkan bahwa solusi tersebut kurang optimal dan harus dipertimbangkan kembali. Jika perlu membuat node (duplikat) tambahan, tunjukkan sebagai proxy dan delegasikan data tersebut untuk membaca dan menulis ke node asli.
Bert Goethals
84

Anda harus fokus pada apa yang benar-benar membuat nilai untuk perangkat lunak Anda . Apakah waktu yang dihabiskan untuk membuatnya bekerja untuk SATU konsumen sepadan dengan harga lisensi? Mungkin tidak.

Saya menyarankan Anda untuk meminta maaf kepada pelanggan ini, katakan kepadanya bahwa situasinya di luar cakupan untuk perangkat lunak Anda dan berikan pengembalian uang kepadanya.

christopheml
sumber
3
Sangat benar. Tetapi juga menimbang masalah potensial lainnya dengan masalah serupa yang diajukan orang lain.
Kontrak Prof. Falken dilanggar
2
Tentu saja. Alasannya adalah: jika ini merupakan kasus tepi yang jarang terjadi pada aplikasi yang tidak kritis, Anda tidak perlu memperbaiki atau mengimplementasikan apa pun. Jika itu benar-benar melukai pengguna Anda, ada nilai dalam mengerjakannya.
christopheml
10
Mungkin setiap orang memiliki kasus inses di suatu tempat di nenek moyangnya. Jadi, Anda akan menemui kesulitan jika seseorang menggali sejarah keluarga (terlalu dalam).
datenwolf
1
Membuat pohon silsilah dari beberapa situasi aneh (royalti inbreed, Fritzl dll) adalah penggunaan perangkat lunak yang valid.
Bulwersator
1
Perangkat lunak silsilah keluarga yang tidak akan mengizinkan sepupu kedua menikah tidak berguna. Hampir semua keluarga memiliki setidaknya satu kasus ini. Itulah sebabnya saya pikir contoh aslinya dibuat untuk efek.
Fuzzy76
79

Anda harus mengatur keluarga Atreides (baik modern, Dune , atau kuno, Oedipus Rex ) sebagai kasus pengujian. Anda tidak menemukan bug dengan menggunakan data yang disanitasi sebagai kasing.

pengguna779752
sumber
2
Sayangnya, terlalu banyak orang pertama-tama memikirkan data 'ok' alih-alih kasus tepi yang merusak sistem mereka.
sjas
59

Ini adalah salah satu alasan mengapa bahasa seperti "Go" tidak memiliki asersi. Mereka terbiasa menangani kasus yang mungkin tidak Anda pikirkan, terlalu sering. Anda seharusnya hanya menegaskan yang mustahil, bukan sekadar yang tidak mungkin . Melakukan yang terakhir inilah yang memberi reputasi buruk pada pernyataan. Setiap kali Anda mengetik assert(, berjalanlah selama sepuluh menit dan benar - benar memikirkannya.

Dalam kasus Anda yang sangat mengganggu, dapat dibayangkan dan mengejutkan bahwa pernyataan seperti itu akan palsu dalam situasi yang jarang tetapi mungkin terjadi. Oleh karena itu, tangani di aplikasi Anda, jika hanya mengatakan "Perangkat lunak ini tidak dirancang untuk menangani skenario yang Anda sajikan".

Menegaskan bahwa kakekmu yang hebat, hebat, dan hebat menjadi ayahmu adalah hal yang wajar untuk dilakukan.

Jika saya bekerja untuk perusahaan pengujian yang disewa untuk menguji perangkat lunak Anda, tentu saja saya akan menyajikan skenario itu. Mengapa? Setiap 'pengguna' remaja namun cerdas akan melakukan hal yang sama persis dan menikmati 'laporan bug' yang dihasilkan.

Pos Tim
sumber
5
Setuju dengan argumen 'kapan harus menggunakan pernyataan'; tidak melihat kaitannya dengan 'beberapa bahasa menegaskan, Go tidak.'
phooji
2
@Red Hue - terkadang kompiler membuat yang tidak mungkin ... menjadi mungkin. Beberapa versi gcc think -10 == 10 dalam implementasi abs ().
Tim Post
2
@Red Hue: Inti pernyataan adalah untuk mendokumentasikan dan menguji kondisi yang harus selalu benar (atau salah). Ini membantu menjaga Anda (dan orang lain) dari "memperbaiki" hal-hal sedemikian rupa sehingga kasus-kasus yang mustahil muncul, karena mereka secara eksplisit (bukan secara halus) merusak aplikasi. Jika ada alasan yang sah untuk kasus "tidak mungkin" muncul, maka Anda telah menyatakan terlalu banyak.
cHao
1
@cHao @Tim Posting Saya hanya mencoba memahami mengapa Go tidak memiliki pernyataan adalah hal yang baik karena sebagian besar dari Anda setuju bahwa pernyataan penting untuk dimiliki.
Arlen
5
Memiliki pernyataan (atau kode seperti pernyataan) tidak relevan. Kode dalam bahasa seperti Go dapat dan akan membuat asumsi tentang struktur data; tidak bisa mendokumentasikan dan menegakkan asumsi-asumsi itu dengan tegas. Intinya: aplikasi memiliki bug.
Tommy McGuire
41

Saya benci mengomentari situasi kacau seperti itu, tetapi cara termudah untuk tidak menyatukan kembali semua invarian Anda adalah dengan membuat simpul hantu di grafik Anda yang bertindak sebagai proxy kembali ke ayah inses.

Sean
sumber
37

Jadi, saya telah melakukan beberapa pekerjaan pada perangkat lunak tree keluarga. Saya pikir masalah yang Anda coba selesaikan adalah Anda harus dapat berjalan di pohon tanpa harus berada di loop yang tak terbatas - dengan kata lain, pohon tersebut harus bersifat asiklikal.

Namun, sepertinya Anda menegaskan bahwa hanya ada satu jalan antara seseorang dan salah satu leluhur mereka. Itu akan menjamin bahwa tidak ada siklus, tetapi terlalu ketat. Secara biologis, keturunan adalah grafik asiklik terarah (DAG). Kasing yang Anda miliki tentu saja kasing, tetapi hal semacam itu selalu terjadi di pohon yang lebih besar.

Misalnya, jika Anda melihat leluhur ke-2 yang Anda miliki pada generasi ke-n, jika tidak ada tumpang tindih, maka Anda akan memiliki lebih banyak leluhur pada 1000 AD daripada ada orang yang masih hidup. Jadi, harus ada tumpang tindih.

Namun, Anda juga cenderung mendapatkan siklus yang tidak valid, hanya data yang buruk. Jika Anda melintasi pohon, maka siklus harus ditangani. Anda dapat melakukan ini di setiap algoritma individu, atau saat memuat. Saya melakukannya dengan beban.

Menemukan siklus sejati di pohon dapat dilakukan dengan beberapa cara. Cara yang salah adalah menandai setiap leluhur dari individu yang diberikan, dan ketika melintasi, jika orang yang akan Anda tuju berikutnya sudah ditandai, maka potong tautannya. Ini akan memutuskan hubungan yang berpotensi akurat. Cara yang benar untuk melakukannya adalah mulai dari masing-masing individu, dan tandai setiap leluhur dengan jalan menuju individu itu. Jika jalur baru berisi jalur saat ini sebagai subpath, maka itu adalah siklus, dan harus diputus. Anda dapat menyimpan jalur sebagai vektor <bool> (MFMF, MFFFMF, dll.) Yang membuat perbandingan dan penyimpanan sangat cepat.

Ada beberapa cara lain untuk mendeteksi siklus, seperti mengirimkan dua iterator dan melihat apakah mereka pernah bertabrakan dengan tes subset, tetapi saya akhirnya menggunakan metode penyimpanan lokal.

Perhatikan juga bahwa Anda tidak perlu memutus tautan, Anda bisa mengubahnya dari tautan normal ke tautan 'lemah', yang tidak diikuti oleh beberapa algoritme Anda. Anda juga harus berhati-hati saat memilih tautan mana yang akan ditandai sebagai lemah; kadang-kadang Anda dapat mengetahui di mana siklus harus diputus dengan melihat informasi tanggal lahir, tetapi seringkali Anda tidak dapat menemukan apa pun karena begitu banyak data yang hilang.

tinninniga
sumber
Hati-hati dengan asumsi tersebut; satu orang tua laki-laki dan satu perempuan tidak diberikan ketika orang beradaptasi, atau lesbian yang menganggap diri mereka sebagai orang tua, dalam waktu dekat mereka bahkan dapat benar - benar menjadi orang tua secara biologis, setidaknya anak perempuan. Dalam hal ini, jika kita berlaku boneka pada manusia, bahkan asumsi "seseorang memiliki dua orang tua yang berbeda" tidak ada.
Agrajag
1
@ Agrajag, ya itu sebabnya saya menentukan "berbicara secara biologis" untuk deteksi siklus. Bahkan secara biologis, ada banyak masalah yang mungkin terjadi, seperti ibu pengganti dan inseminasi buatan. Jika Anda juga mengizinkan adopsi dan metode non-biologis lainnya untuk mendefinisikan orang tua, maka dimungkinkan untuk memiliki siklus sejati yang valid di pohon - misalnya, mungkin seseorang mengadopsi kakek-nenek mereka ketika mereka menjadi tua dan tidak lagi dapat mengurus diri sendiri . Membuat asumsi tentang kehidupan keluarga seseorang selalu rumit. Tetapi ketika menulis perangkat lunak Anda perlu membuat beberapa asumsi ..
tfinniga
36

Jawaban serius lain yang mengejek untuk pertanyaan konyol:

Jawaban sebenarnya adalah, gunakan struktur data yang sesuai. Silsilah manusia tidak dapat sepenuhnya diekspresikan menggunakan pohon murni tanpa siklus. Anda harus menggunakan semacam grafik. Juga, berbicaralah dengan seorang antropolog sebelum melangkah lebih jauh dengan ini, karena ada banyak tempat lain kesalahan serupa dapat dibuat dengan mencoba memodelkan silsilah, bahkan dalam kasus paling sederhana "perkawinan monogami patriarkal Barat."

Bahkan jika kita ingin mengabaikan hubungan tabu secara lokal seperti yang dibahas di sini, ada banyak cara yang benar-benar legal dan sama sekali tidak terduga untuk memperkenalkan siklus ke pohon keluarga.

Misalnya: http://en.wikipedia.org/wiki/Cousin_marriage

Pada dasarnya, pernikahan sepupu tidak hanya umum dan diharapkan, itu adalah alasan manusia beralih dari ribuan kelompok keluarga kecil ke populasi dunia sebesar 6 miliar. Tidak bisa dengan cara lain.

Sebenarnya ada sangat sedikit hal universal dalam hal silsilah, keluarga, dan garis keturunan. Hampir semua asumsi ketat tentang norma yang menunjukkan siapa bibi, atau siapa yang bisa menikahi siapa, atau bagaimana anak-anak dilegitimasi untuk tujuan pewarisan, dapat dikecewakan oleh beberapa pengecualian di suatu tempat di dunia atau sejarah.

clvrmnky
sumber
9
Komentar Anda membuat saya berpikir tentang poligami. Perangkat lunak silsilah yang hanya memodelkan reproduksi seksual mungkin memerlukan nama yang melekat pada sperma dan sel telur tetapi definisi yang lebih luas dari struktur keluarga tidak.
Steve Kalemkiewicz
Perangkat lunak silsilah sering memungkinkan lebih dari satu pasangan dalam model. Cara Anda menampilkan model dalam tampilan sangat bervariasi, bahkan dalam satu program, tergantung pada "mode" yang telah disediakan.
Todd Hopkinson
20

Selain potensi implikasi hukum, tampaknya Anda perlu memperlakukan 'simpul' pada silsilah keluarga sebagai orang pendahulunya alih-alih mengasumsikan bahwa simpul tersebut dapat menjadi satu-satunya orang.

Mintalah simpul pohon menyertakan seseorang dan juga penerusnya - dan kemudian Anda dapat memiliki simpul lain yang lebih dalam di bawah pohon yang mencakup orang yang sama dengan penerus yang berbeda.

Will A
sumber
13

Beberapa jawaban telah menunjukkan cara untuk mempertahankan asersi / invarian, tetapi ini tampaknya seperti penyalahgunaan asersi / invarian. Penegasan untuk memastikan sesuatu yang seharusnya benar itu benar, dan invarian harus memastikan sesuatu yang tidak boleh berubah tidak berubah.

Apa yang Anda tegaskan di sini adalah bahwa hubungan inses tidak ada. Jelas mereka memang ada, jadi pernyataan Anda tidak valid. Anda dapat mengatasi pernyataan ini, tetapi bug sebenarnya ada di pernyataan itu sendiri. Pernyataan itu harus dihapus.

kerkeslager
sumber
8

Silsilah keluarga Anda harus menggunakan hubungan terarah. Dengan cara ini Anda tidak akan memiliki siklus.

Patrick Cornelissen
sumber
5

Data silsilah adalah siklik dan tidak cocok dengan grafik asiklik, jadi jika Anda memiliki pernyataan yang menentang siklus Anda harus menghapusnya.

Cara untuk menangani ini dalam tampilan tanpa membuat tampilan kustom adalah memperlakukan orangtua siklik sebagai orangtua "hantu". Dengan kata lain, ketika seseorang adalah ayah dan kakek dari orang yang sama, maka simpul kakek ditampilkan secara normal, tetapi simpul ayah diterjemahkan sebagai simpul "hantu" yang memiliki label sederhana seperti ("lihat kakek" ) dan menunjuk ke kakek.

Untuk melakukan perhitungan, Anda mungkin perlu meningkatkan logika untuk menangani grafik siklik sehingga sebuah simpul tidak dikunjungi lebih dari sekali jika ada siklus.

Tyler Durden
sumber
4

Yang paling penting adalah avoid creating a problem, jadi saya percaya Anda harus menggunakan hubungan langsung untuk menghindari siklus.

Seperti @markmywords katakan, #sertakan "fritzl.h".

Akhirnya harus saya katakan recheck your data structure. Mungkin ada yang tidak beres di sana (mungkin daftar yang dwi-link memecahkan masalah Anda).

Nasser Hadjloo
sumber
4

Pernyataan tidak bertahan dari kenyataan

Biasanya pernyataan tidak bertahan dari kontak dengan data dunia nyata. Ini adalah bagian dari proses rekayasa perangkat lunak untuk memutuskan, dengan data mana yang ingin Anda tangani dan yang di luar jangkauan.

Grafik keluarga siklik

Mengenai "pohon" keluarga (sebenarnya itu adalah grafik yang lengkap, termasuk siklus), ada anekdot yang bagus:

Saya menikahi seorang janda yang memiliki anak perempuan yang sudah dewasa. Ayah saya, yang sering mengunjungi kami, jatuh cinta dengan putri tiriku dan menikahinya. Akibatnya, ayah saya menjadi putra saya, dan putri saya menjadi ibu saya. Beberapa waktu kemudian, saya memberi istri saya seorang putra, yang merupakan saudara lelaki ayah saya, dan paman saya. Istri ayah saya (yang juga anak perempuan saya dan ibu saya) mendapatkan seorang putra. Akibatnya, saya memiliki saudara lelaki dan cucu laki-laki yang sama. Istri saya sekarang adalah nenek saya, karena dia adalah ibu ibu saya. Jadi saya adalah suami dari istri saya, dan pada saat yang sama adalah cucu dari istri saya. Dengan kata lain, saya adalah kakek saya sendiri.

Hal-hal menjadi lebih aneh, ketika Anda mempertimbangkan pengganti atau "ayah kebal" ke dalam akun.

Bagaimana menghadapinya

Tentukan siklus sebagai di luar cakupan

Anda dapat memutuskan bahwa perangkat lunak Anda tidak boleh menangani kasus yang jarang terjadi. Jika hal seperti itu terjadi, pengguna harus menggunakan produk yang berbeda. Ini membuat berurusan dengan kasus-kasus yang lebih umum jauh lebih kuat, karena Anda dapat mempertahankan lebih banyak pernyataan dan model data yang lebih sederhana.

Dalam hal ini, tambahkan beberapa fitur impor dan ekspor yang baik ke perangkat lunak Anda, sehingga pengguna dapat dengan mudah bermigrasi ke produk yang berbeda bila perlu.

Izinkan hubungan manual

Anda dapat mengizinkan pengguna untuk menambahkan hubungan manual. Hubungan ini bukan "warga negara kelas satu", yaitu perangkat lunak mengambil apa adanya, tidak memeriksa mereka dan tidak menangani mereka dalam model data utama.

Pengguna kemudian dapat menangani kasus yang jarang terjadi dengan tangan. Model data Anda akan tetap sederhana dan pernyataan Anda akan tetap bertahan.

Hati-hati dengan hubungan manual. Ada godaan untuk membuatnya benar-benar dapat dikonfigurasi dan karenanya membuat model data yang sepenuhnya dapat dikonfigurasi. Ini tidak akan berfungsi: Perangkat lunak Anda tidak akan skala, Anda akan mendapatkan bug aneh dan akhirnya antarmuka pengguna menjadi tidak dapat digunakan. Anti-pola ini disebut "soft coding" , dan "The WTF daily" penuh dengan contoh untuk itu.

Jadikan model data Anda lebih fleksibel, lewati asersi, uji invarian

Pilihan terakhir adalah membuat model data Anda lebih fleksibel. Anda harus melewati hampir semua asersi dan mendasarkan model data Anda pada grafik lengkap. Seperti yang ditunjukkan contoh di atas, mudah untuk menjadi kakek Anda sendiri, sehingga Anda bahkan dapat memiliki siklus.

Dalam hal ini, Anda harus menguji perangkat lunak Anda secara ekstensif. Anda harus melewati hampir semua pernyataan, jadi ada peluang bagus untuk bug tambahan.

Gunakan generator data uji untuk memeriksa kasus uji yang tidak biasa. Ada cek perpustakaan cepat untuk Haskell , Erlang atau C . Untuk Java / Scala ada ScalaCheck dan Nyaya . Satu ide tes adalah mensimulasikan populasi acak, biarkan kawin silang secara acak, lalu biarkan perangkat lunak Anda terlebih dahulu mengimpor dan kemudian mengekspor hasilnya. Harapannya adalah, bahwa semua koneksi dalam output juga dalam input dan sebaliknya.

Kasing, di mana properti tetap sama disebut invarian. Dalam hal ini, invarian adalah set "hubungan romantis" antara individu dalam populasi yang disimulasikan. Cobalah untuk menemukan invarian sebanyak mungkin dan mengujinya dengan data yang dihasilkan secara acak. Invarian dapat berfungsi, misalnya:

  • seorang paman tetap seorang paman, bahkan ketika Anda menambahkan lebih banyak "hubungan romantis"
  • setiap anak memiliki orang tua
  • populasi dengan dua generasi memiliki setidaknya satu grand-parent

Atau mereka dapat bersifat teknis:

  • Perangkat lunak Anda tidak akan macet pada grafik hingga 10 miliar anggota (tidak peduli berapa banyak interkoneksi)
  • Perangkat lunak Anda menskala dengan O (jumlah node) dan O (jumlah edge ^ 2)
  • Perangkat lunak Anda dapat menyimpan dan memuat ulang setiap grafik keluarga hingga 10 miliar anggota

Dengan menjalankan tes simulasi, Anda akan menemukan banyak kasus sudut aneh. Memperbaikinya akan membutuhkan banyak waktu. Juga Anda akan kehilangan banyak optimasi, perangkat lunak Anda akan berjalan jauh lebih lambat. Anda harus memutuskan, apakah itu layak dan apakah ini dalam lingkup perangkat lunak Anda.

stefan.schwetschke
sumber
3

Alih-alih menghapus semua pernyataan, Anda masih harus memeriksa hal-hal seperti seseorang menjadi orang tuanya sendiri atau situasi tidak mungkin lainnya dan menyajikan kesalahan. Mungkin mengeluarkan peringatan jika tidak memungkinkan sehingga pengguna masih dapat mendeteksi kesalahan input umum, tetapi akan berfungsi jika semuanya benar.

Saya akan menyimpan data dalam vektor dengan bilangan bulat permanen untuk setiap orang dan menyimpan orang tua dan anak-anak di objek orang di mana int mengatakan adalah indeks dari vektor. Ini akan cukup cepat untuk dilakukan antar generasi (tetapi lambat untuk hal-hal seperti pencarian nama). Benda-benda akan berada di urutan kapan mereka dibuat.

ctype.h
sumber
-3

Gandakan ayah (atau gunakan symlink / referensi).

Misalnya, jika Anda menggunakan basis data hierarkis:

$ #each person node has two nodes representing its parents.
$ mkdir Family
$ mkdir Family/Son
$ mkdir Family/Son/Daughter
$ mkdir Family/Son/Father
$ mkdir Family/Son/Daughter/Father
$ ln -s Family/Son/Daughter/Father Family/Son/Father
$ mkdir Family/Son/Daughter/Wife
$ tree Family
Family
└── Son
    ├── Daughter
       ├── Father
       └── Wife
    └── Father -> Family/Son/Daughter/Father

4 directories, 1 file
numerik
sumber
3
The ln -sperintah tidak bekerja seperti itu; resolusi tautan Family/Son/Fatherakan dicari Family/Son/Daughter/Fatherdari bawah Family/Son, tempat tautan berada, bukan dari .tempat Anda mengeluarkan ln -sperintah.
musiphil
48
kloning dilarang oleh konvensi geneva
MikeIsrael