Jgrapht: Bug di NaiveLcaFinder

Dibuat pada 14 Feb 2018  ·  13Komentar  ·  Sumber: jgrapht/jgrapht

Halo semua, ketika mencoba mengurai file titik, saya menggunakan grafik yang semua LCA-nya harus Robert dan Cersei tetapi sebaliknya, tidak menerima apa pun. Silakan periksa apakah itu benar-benar bug. Bug ini kebetulan berada di fungsi findLcas dari NaiveLcaFinder.

<strong i="9">@Test</strong>
    public void testPseudoLcas(){
     public final String NL = "\n";
        String input = "digraph GOT {"+NL+
            "graph [ bgcolor = whitesmoke ]"+NL+
            "subgraph cluster_stark {"+NL+
                "style = filled ;"+NL+
                "color = lightblue ;"+NL+
                "label = \" House Stark \" ;"+NL+
                "node [ style = filled , color = white ];"+NL+
                "Rickard ;"+NL+
                "Brandon ; Eddard ; Benjen ; Lyanna ;"+NL+
                "Robb ; Sansa ; Arya ; Brandon ; Rickon ;"+NL+
                "node [ shape = doublecircle , style = filled , color = white ];"+NL+
                "Jon ;"+NL+
                "Rickard -> Brandon ;"+NL+
                "Rickard -> Eddard ;"+NL+
                "Rickard -> Benjen ;"+NL+
                "Rickard -> Lyanna ;"+NL+
                "Eddard -> Robb ;"+NL+
                "Eddard -> Sansa ;"+NL+
                "Eddard -> Arya ;"+NL+
                "Eddard -> Brandon ;"+NL+
                "Eddard -> Rickon ;"+NL+
                "Eddard -> Jon [ label = \" bastard \" , color = azure4 ];"+NL+
            "}"+NL+
            "subgraph cluster_baratheon {"+NL+
                "style = filled ;" +NL+
                "color = chocolate3 ;" +NL+
                "label = \" House Baratheon \" ;" +NL+
                "node [ style = filled , color = white ];" +NL+
                "Ormund ; Steffon ; Robert ; Stannis ; Renly ; Shireen ; Joffrey ; Myrcellar ; Tommen ;" +NL+
                "Ormund -> Steffon ;" +NL+
                "Rhaelle -> Steffon ;" +NL+
                "Ormund -> Rhaelle ;" +NL+
                "Rhaelle -> Ormund ;" +NL+
                "Steffon -> Robert ;" +NL+
                "Steffon -> Stannis ;" +NL+
                "Steffon -> Renly ;" +NL+
                "Stannis -> Shireen ;" +NL+
                "Robert -> Joffrey ;" +NL+
                "Robert -> Myrcellar ;" +NL+
                "Robert -> Tommen ;" +NL+
            "}" +NL+
            "subgraph cluster_lannister {"+NL+
                "style = filled ;"+NL+
                "color = cornsilk3 ;"+NL+
                "label = \" House Lannister \" ;"+NL+
                "node [ style = filled , color = white ];"+NL+
                "Tywin ; Joanna ; Jaime ; Cersei ; Tyrion ;"+NL+
                "Tywin -> Joanna ;"+NL+
                "Joanna -> Tywin ;"+NL+
                "Joanna -> Jaime ;"+NL+
                "Joanna -> Cersei ;"+NL+
                "Joanna -> Tyrion ;"+NL+
                "Tywin -> Jaime ;"+NL+
                "Tywin -> Cersei ;"+NL+
                "Tywin -> Tyrion ;"+NL+
                "Jaime -> Cersei ;"+NL+
                "Cersei -> Jaime ;"+NL+
                "Robert -> Cersei ;"+NL+
                "Cersei -> Robert ;"+NL+
                "Cersei -> Joffrey ;"+NL+
                "Cersei -> Myrcellar ;"+NL+
                "Cersei -> Tommen ;"+NL+
                "Jaime -> Joffrey [ style = dashed ];"+NL+
                "Jaime -> Myrcellar [ style = dashed ];"+NL+
                "Jaime -> Tommen [ style = dashed ];"+NL+
            "}"+NL+
            "Lyanna -> Rhaegar [ style = dashed , label = \" ? \" ];"+NL+
            "Rhaegar -> Lyanna [ style = dashed , label = \" ? \" ];"+NL+
            "Lyanna -> Jon [ style = dashed , label = \" ? \" ];"+NL+
            "Rhaegar -> Jon [ style = dashed , label = \" ? \" ];"+NL+
            "labelloc = \" t \" ;"+NL+
            "fontsize =50;"+NL+
            "fontcolor = lightslategrey ;"+NL+
            "fontname = \" Bookman Old Style Bold Italic \" ;"+NL+
            "label = \" Game of Thrones Family Tree \""+NL+
            "}" ; 

            VertexProvider<String> vp = (a, b) -> a;
        EdgeProvider<String, DefaultEdge> ep = (f, t, l, a) -> new DefaultEdge();
        GraphImporter<String, DefaultEdge> importer = new DOTImporter<String, DefaultEdge>(vp, ep);
        DirectedPseudograph<String, DefaultEdge> graph = new DirectedPseudograph<String, DefaultEdge>(DefaultEdge.class);
        try {
            importer.importGraph(graph, new StringReader(input));
        } catch (ImportException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    NaiveLcaFinder<String, DefaultEdge> graphFinder = new NaiveLcaFinder<>(graph);
        checkLcas(graphFinder, "Joffrey", "Tommen", Arrays.asList("Robert"));
    }

Semua 13 komentar

Apa yang Anda lakukan untuk men-debug masalah ini?

Karena konstruktor kelas NaiveLcaFinder hanya memastikan bahwa grafik harus diarahkan tetapi tidak memeriksa apakah itu berisi siklus. LCA harus ditemukan di DAG tetapi untuk tes yang diberikan, saya kemudian menyadari bahwa itu bukan DAG. Itu seharusnya menjadi DAG tetapi tidak. Haruskah saya melanjutkan dan menerapkan pemeriksaan ini?

Tidak, bukan ide yang baik untuk menambahkan ini sebagai tanda centang. Selalu ada trade-off antara: menghabiskan upaya komputasi pada validasi input, dan hanya dengan asumsi bahwa pengguna memberikan input yang benar. Saat ini saya tidak memiliki akses ke kode, tetapi yang dapat Anda lakukan adalah:

  1. Periksa apakah GraphTests berisi metode isDirectedAcyclicGraph. Jika tidak, tambahkan.
  2. dalam kode NaiveLCA, tambahkan pernyataan: assert GraphTests.isDirectedAcyclicGraph(g); Mungkin di NaiveLCA seseorang harus membuatnya lebih eksplisit dalam spesifikasi dokumentasi/parameter bahwa grafik input harus berupa DAG.
  3. Ada banyak algoritma di jgrapht yang dapat digunakan untuk menegaskan apakah suatu grafik asiklik, jadi tidak perlu mengimplementasikannya.

Namun demikian, periksa kembali apakah sudah ada beberapa metode yang setara dengan tes isDirectedAcyclicGraph (saya tidak hafal ini).

Untuk proyek saya untuk sementara, saya memodifikasi konstruktor NaiveLcaFinder untuk meminta DAG. Saya akan bekerja menulis metode isDirectedAcyclicGraph . Kami sudah memiliki implementasi keduanya jika grafik diarahkan dan jika grafik berisi siklus, jadi, Bolehkah saya melanjutkan untuk mengimplementasikan isDirectedAcyclicGraph ?

@hulk-baba Ada masalah dengan file input Anda. Saya mendapatkan Cersei ketika saya menjalankan implementasi saya dengan "Robert Cersei" (yang tidak terlalu benar tetapi ada keunggulan dari Cersei ke Robert; seperti dari Robert ke Cersei di file input) sebagai inputnya dengan versi input saya mengajukan.

Silakan periksa file input Anda lagi dan beri tahu saya jika Anda menemukan sesuatu (atau mungkin coba grafik yang lebih kecil yang Anda simulasikan sebagai bagian dari subgraf Lannister/Baratheon dan lebih mudah untuk di-debug).

@AlexandruValeanu silakan coba dengan file input yang sama dengan argumen yang berbeda Joffrey Tommen seperti pada kode checkLcas(graphFinder, "Joffrey", "Tommen", Arrays.asList("Robert"));

@hulk-baba Anda benar. Ini tidak bekerja dalam kasus itu.

Satu set nenek moyang yang sama adalah [Robert, Cersei, Jaime] . Tapi kemudian ini terjadi. Sepotong kode itu menghapus semua node yang memiliki anak di set leluhur. Karena ada tepi dari Cersei ke Robert dan Jaime dan dari Robert ke Cersei, ketiganya dapat (dan akan) dihilangkan dari himpunan nenek moyang yang sama (Cersei dihilangkan karena Robert, Jaime karena Cersei dan Robert karena Cersei) .

Ini bukan masalah dengan implementasi sebenarnya karena grafiknya bukan DAG (siklus antara Robert dan Cersei menciptakan masalah di subgraf Lannister/Baratheon).

Kemungkinan perbaikan:

  • Hapus tepi dari Robert ke Cersei; Saya mendapatkan "Robert" setelah saya menghapus tepinya
  • Dalam hal ini, findLca berfungsi. Ini mungkin tidak berfungsi pada siklus lain tetapi tampaknya berhasil pada siklus ini
  • Ada perbaikan kecil yang bisa saya lakukan sehingga kinerjanya lebih baik pada grafik dengan siklus tetapi ini bukan tujuan dari implementasi ini

@AlexandruValeanu Jadi, apakah kita berasumsi bahwa grafik yang diberikan salah dan kemudian menghapus tepi dari Robert menjadi Cersei ?
Apa yang saya pikir seharusnya tidak ada output dalam kasus grafik siklik yang dilakukan kode saat ini, Ya tetapi ketika kita memasukkan Joffrey dan Cersei maka outputnya adalah Cersei yang menurut saya tidak boleh karena Cersei adalah bagian dari siklus sehingga tidak membuat kami yakin apakah simpul itu adalah LCA atau bukan.
Jadi yang saya sarankan adalah kita dapat memeriksa apakah node input adalah bagian dari siklus atau tidak dengan memanggil fungsi detectCyclesContainingVertex dan jika salah satunya benar maka kita dapat kembali tanpa LCA apa pun. Inilah yang saya lakukan dalam latihan pemanasan saya.
Tolong beri tahu saya jika saya salah memahami ini dan bantu saya untuk memperbaikinya.

@tibrewalpratik17
Grafik dalam pdf itu bukan DAG sehingga Anda tidak perlu berasumsi apa pun: ini bukan input yang valid untuk NaiveLcaFinder .

Untuk tantangan pemanasan, lebih baik hanya memodifikasi grafik sehingga tidak lagi mengandung siklus apa pun. Anda dapat menggunakan CycleDetector untuk memeriksa apakah ada siklus dalam versi grafik Anda.

Implementasi findLcas saya tidak mencoba mendeteksi siklus atau melakukan sesuatu yang cerdas untuk menghasilkan jawaban yang masuk akal ketika diberikan grafik siklik (yaitu Anda mendapatkan undefined behaviour ). Oleh karena itu, tidak ada gunanya menganalisis output jika prasyaratnya rusak.

@AlexandruValeanu oke... tapi bagaimana jika pengguna memasukkan grafik siklik dan mengharapkan output sehingga output yang valid dalam kasus itu harus nol jika ada nenek moyang terbaru dari node yang diberikan atau mungkin node itu sendiri terlibat dalam siklus Baik?

Pengguna tidak boleh mengharapkan jawaban, dalam hal ini, pengguna harus memvalidasi input mereka, itu seperti mengatakan apa f(x) untuk input x, tidak dalam domain f, jawabannya tidak nol tetapi tidak didefinisikan.

@tibrewalpratik17
NaiveLcaFinder mengembalikan daftar lcas yang benar jika dan hanya jika melewati DAG.

Jika inputnya bukan DAG maka outputnya tidak boleh dipercaya. Secara harfiah bisa apa saja. Dalam hal ini, saya percaya bahwa implementasi saya hanya mengembalikan lcas yang bukan bagian dari siklus tetapi saya tidak begitu yakin karena saya belum menguji bagaimana undefined jawabannya.

Bisakah seseorang tolong tutup ini karena ini bukan bug?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

io7m picture io7m  ·  53Komentar

simlu picture simlu  ·  14Komentar

IngerMathilde picture IngerMathilde  ·  5Komentar

haerrel picture haerrel  ·  5Komentar

jsichi picture jsichi  ·  12Komentar