Jgrapht: علة في NaiveLcaFinder

تم إنشاؤها على ١٤ فبراير ٢٠١٨  ·  13تعليقات  ·  مصدر: jgrapht/jgrapht

مرحبًا بالجميع ، أثناء محاولتي تحليل ملف نقطي ، استخدمت رسمًا بيانيًا يجب أن تكون جميع LCAs الخاصة به Robert و Cersei ولكن بدلاً من ذلك ، لم أتلق شيئًا. يرجى التحقق مما إذا كانت حقاً خطأ. يحدث هذا الخطأ ليكون في وظيفة findLcas من 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"));
    }

ال 13 كومينتر

ماذا فعلت لتصحيح هذه المشكلة؟

نظرًا لأن مُنشئ فئة NaiveLcaFinder يضمن فقط أنه يجب توجيه الرسم البياني ولكنه لا يتحقق مما إذا كان يحتوي على دورة. يجب العثور على LCAs في DAGs ولكن بالنسبة للاختبار المحدد ، أدركت لاحقًا أنه لم يكن DAG. كان من المفترض أن تكون DAG لكنها لم تكن كذلك. هل يجب علي المضي قدمًا وتنفيذ هذا الفحص؟

لا ، لن يكون من الجيد إضافة هذا كشيك. هناك دائمًا مفاضلة بين: إنفاق الجهد الحسابي على التحقق من صحة الإدخال ، وفقط افتراض أن المستخدم يوفر المدخلات الصحيحة. لا يمكنني حاليًا الوصول إلى الرمز ، ولكن ما يمكنك فعله هو:

  1. تحقق مما إذا كانت اختبارات الرسم البياني تحتوي على طريقة هيDirectedAcyclicGraph. إذا لم يكن كذلك ، قم بإضافته.
  2. في التعليمات البرمجية NaiveLCAs ، أضف تأكيدًا: تأكيد GraphTests.isDirectedAcyclicGraph (g) ؛ ربما في NaiveLCA يجب على المرء أن يجعل الأمر أكثر وضوحًا في مواصفات التوثيق / المعلمة أن الرسم البياني للإدخال يحتاج إلى DAG.
  3. هناك الكثير من الخوارزميات في jgrapht والتي يمكن استخدامها لتأكيد ما إذا كان الرسم البياني غير دوري ، لذلك لا داعي لتطبيق ذلك.

ومع ذلك ، تحقق مرة أخرى مما إذا كان لا توجد بالفعل طريقة معادلة لاختبار isDirectedAcyclicGraph (لا أعرف هذا عن ظهر قلب).

بالنسبة لمشروعي مبدئيًا ، قمت بتعديل المُنشئ NaiveLcaFinder لطلب DAG. سأعمل على كتابة الطريقة isDirectedAcyclicGraph . لدينا بالفعل تنفيذ كلاهما إذا تم توجيه الرسم البياني وإذا كان الرسم البياني يحتوي على دورات ، فهل يمكنني المضي قدمًا في تنفيذ isDirectedAcyclicGraph ؟

@ hulk-baba توجد مشكلة في ملف الإدخال. أحصل على Cersei عندما أقوم بتشغيل تطبيقي باستخدام "Robert Cersei" (وهو ليس صحيحًا حقًا ولكن هناك ميزة من Cersei إلى Robert ؛ كما هو الحال من Robert إلى Cersei في ملف الإدخال) كمدخل لها مع نسختي من الإدخال ملف.

يرجى التحقق من ملف الإدخال الخاص بك مرة أخرى وإخباري إذا وجدت شيئًا ما (أو ربما جرب رسمًا بيانيًا أصغر يحاكي جزءًا من الرسم البياني الفرعي Lannister / Baratheon ويسهل تصحيحه).

AlexandruValeanu يرجى المحاولة بنفس ملف الإدخال مع وسائط مختلفة Joffrey Tommen كما في الكود checkLcas(graphFinder, "Joffrey", "Tommen", Arrays.asList("Robert"));

@ hulk-baba أنت على حق. إنه لا يعمل في هذه الحالة.

مجموعة الأجداد المشتركة ستكون [Robert, Cersei, Jaime] . ولكن بعد ذلك يحدث هذا. هذا الجزء من الكود يزيل جميع العقد التي لديها طفل في مجموعة الأجداد. نظرًا لوجود حواف من Cersei إلى Robert و Jaime ومن روبرت إلى Cersei ، يمكن (وسيتم) التخلص من الثلاثة من مجموعة الأجداد المشتركين (يتم التخلص من Cersei بسبب Robert و Jaime بسبب Cersei و Robert بسبب Cersei) .

هذه ليست مشكلة في التنفيذ الفعلي لأن الرسم البياني ليس DAG (الدورة بين روبرت وسيرسي تخلق مشاكل في الرسم البياني الفرعي لانيستر / باراثيون).

الإصلاحات الممكنة:

  • قم بإزالة الحافة من روبرت إلى سيرسي ؛ أحصل على "روبرت" بعد أن أزلت الحافة
  • في هذه الحالة ، يعمل findLca. قد لا يعمل في دورات أخرى ولكن يبدو أنه يعمل على هذه الدورة
  • هناك إصلاح صغير يمكنني إجراؤه بحيث يؤدي بشكل أفضل على الرسوم البيانية ذات الدورات ولكن هذا ليس الغرض من هذا التنفيذ

AlexandruValeanu إذن هل نفترض أن الرسم البياني المحدد غير صحيح ثم نزيل الحافة من Robert إلى Cersei ؟
ما أعتقد أنه لا ينبغي أن تكون هناك مخرجات في حالة الرسوم البيانية الدورية التي تقوم بها الكود في الوقت الحالي ، نعم ولكن عندما نقوم بإدخال Joffrey و Cersei فإن الناتج يكون Cersei وهو ما أعتقد أنه لا ينبغي أن يكون لأن Cersei جزء من دورة وبالتالي لا نتأكد مما إذا كانت هذه العقدة عبارة عن LCA أم لا.
لذا ما أقترحه هو أنه يمكننا التحقق مما إذا كانت عقد الإدخال جزء من دورة أم لا عن طريق استدعاء الوظيفة detectCyclesContainingVertex وإذا كان أي منها صحيحًا ، فيمكننا العودة بدون أي LCA. هذا ما أفعله في تمرين الإحماء.
يرجى إعلامي إذا فهمت هذا بشكل غير صحيح وساعدني في فهمه بشكل صحيح.

@ TibRanalPratik17.
الرسم البياني في ملف pdf هذا ليس DAG لذا لا يتعين عليك افتراض أي شيء: فهو ليس إدخالًا صالحًا لـ NaiveLcaFinder .

بالنسبة لتحدي الإحماء ، من الأفضل تعديل الرسم البياني ببساطة بحيث لا يحتوي على أي دورات. يمكنك استخدام CycleDetector للتحقق مما إذا كانت هناك أي دورات في إصدارك من الرسم البياني.

لا يحاول تطبيقي لـ findLcas اكتشاف الدورات أو القيام بأي شيء ذكي لإنتاج إجابة معقولة عند إعطائك رسمًا بيانيًا دوريًا (أي تحصل على undefined behaviour ). لذلك لا فائدة من تحليل الناتج إذا تم كسر الشرط المسبق.

AlexandruValeanu حسنًا ... ولكن ماذا لو أدخل المستخدم رسمًا بيانيًا دوريًا وتوقع مخرجات ، لذا يجب أن يكون الناتج الصالح في هذه الحالة فارغًا إذا كان أي من الأسلاف الحديثة للعقد المعينة أو قد تكون العقد نفسها متورطة في دورة حق؟

يجب ألا يتوقع المستخدم إجابة ، في هذه الحالة ، يجب على المستخدم التحقق من صحة المدخلات الخاصة به ، فهو مجرد قول ما هو f (x) للإدخال x ، وليس في مجال f ، فإن الإجابة ليست فارغة ولكنها غير محددة.

@ TibRanalPratik17.
يقوم NaiveLcaFinder بإرجاع قائمة lcas الصحيحة فقط إذا تم تمريرها DAG.

إذا لم يكن الإدخال DAG ، فلا ينبغي الوثوق في الإخراج. يمكن أن يكون أي شيء حرفيًا. في هذه الحالة ، أعتقد أن تطبيقي يُرجع فقط lcas التي ليست جزءًا من دورة ولكني لست متأكدًا حقًا لأنني لم أختبر كيف تكون الإجابة undefined .

هل يمكن لأي شخص أن يغلق هذا لأنه ليس خطأ؟

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

jsichi picture jsichi  ·  12تعليقات

nikhilbhardwaj picture nikhilbhardwaj  ·  3تعليقات

jsichi picture jsichi  ·  12تعليقات

haerrel picture haerrel  ·  5تعليقات

simlu picture simlu  ·  14تعليقات