مرحبًا بالجميع ، أثناء محاولتي تحليل ملف نقطي ، استخدمت رسمًا بيانيًا يجب أن تكون جميع 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"));
}
ماذا فعلت لتصحيح هذه المشكلة؟
نظرًا لأن مُنشئ فئة NaiveLcaFinder يضمن فقط أنه يجب توجيه الرسم البياني ولكنه لا يتحقق مما إذا كان يحتوي على دورة. يجب العثور على LCAs في DAGs ولكن بالنسبة للاختبار المحدد ، أدركت لاحقًا أنه لم يكن DAG. كان من المفترض أن تكون DAG لكنها لم تكن كذلك. هل يجب علي المضي قدمًا وتنفيذ هذا الفحص؟
لا ، لن يكون من الجيد إضافة هذا كشيك. هناك دائمًا مفاضلة بين: إنفاق الجهد الحسابي على التحقق من صحة الإدخال ، وفقط افتراض أن المستخدم يوفر المدخلات الصحيحة. لا يمكنني حاليًا الوصول إلى الرمز ، ولكن ما يمكنك فعله هو:
ومع ذلك ، تحقق مرة أخرى مما إذا كان لا توجد بالفعل طريقة معادلة لاختبار 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 (الدورة بين روبرت وسيرسي تخلق مشاكل في الرسم البياني الفرعي لانيستر / باراثيون).
الإصلاحات الممكنة:
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
.
هل يمكن لأي شخص أن يغلق هذا لأنه ليس خطأ؟