みなさん、こんにちは。ドットファイルを解析しようとしているときに、すべてのLCAがRobert
とCersei
であるはずのグラフを使用しましたが、代わりに何も受け取りませんでした。 本当にバグか確認してください。 このバグは、NaiveLcaFinderの関数findLcas
にあります。
<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クラスのコンストラクターは、グラフを方向付ける必要があることを確認するだけであり、グラフにサイクルが含まれているかどうかはチェックしません。 LCAはDAGで検出する必要がありますが、特定のテストで、後でDAGではないことに気付きました。 DAGであるはずでしたが、そうではありませんでした。 先に進んでこのチェックを実装する必要がありますか?
いいえ、これをチェックとして追加するのは良い考えではありません。 入力の検証に計算の労力を費やすことと、ユーザーが正しい入力を提供すると仮定することの間には、常にトレードオフがあります。 私は現在コードにアクセスできませんが、あなたができることは次のとおりです。
それでも、isDirectedAcyclicGraphテストに相当するメソッドがまだ存在しないかどうかを再確認してください(これは心からはわかりません)。
私のプロジェクトでは、暫定的に、DAGを要求するようにNaiveLcaFinder
コンストラクターを変更しました。 メソッドisDirectedAcyclicGraph
の記述に取り組みます。 グラフが指示されている場合とグラフにサイクルが含まれている場合の両方の実装がすでにあるので、 isDirectedAcyclicGraph
の実装に進むことができますか?
@ hulk-baba入力ファイルに問題があります。 「RobertCersei」(実際には正しくありませんが、CerseiからRobertへのエッジがあります。入力ファイルのRobertからCerseiへのエッジがあります)を入力として使用して実装を実行すると、Cerseiが取得されます。ファイル。
入力ファイルをもう一度確認して、何かが見つかった場合はお知らせください(または、Lannister / Baratheonサブグラフの一部をシミュレートした小さなグラフを試してみてください。デバッグが簡単です)。
@AlexandruValeanuコードcheckLcas(graphFinder, "Joffrey", "Tommen", Arrays.asList("Robert"));
のように、異なる引数Joffrey Tommen
を使用して同じ入力ファイルで試してください
@ hulk-babaその通りです。 その場合は機能しません。
共通の祖先のセットは[Robert, Cersei, Jaime]
になります。 しかし、その後、これが起こります。 そのコードは、祖先のセットに子を持つすべてのノードを削除します。 CerseiからRobertとJaime、RobertからCerseiにはエッジがあるため、3つすべてを共通の祖先のセットから削除できます(CerseiはRobertのために削除され、JaimeはCerseiのために、RobertはCerseiのために削除されます) 。
グラフはDAGではないため、これは実際の実装では問題になりません(RobertとCerseiの間のサイクルにより、Lannister / Baratheonサブグラフで問題が発生します)。
考えられる修正:
@AlexandruValeanuでは、与えられたグラフが正しくないと仮定して、 Robert
からCersei
にエッジを削除しているのでしょうか。
コードが現在実行している循環グラフの場合、出力はないはずだと思いますが、 Joffrey
とCersei
を入力すると、出力はCersei
になります。 Cersei
はサイクルの一部であり、そのノードがLCAであるかどうかを確認できないため、これは適切ではないと思います。
したがって、私が提案するのは、関数detectCyclesContainingVertex
を呼び出すことで、入力ノードがサイクルの一部であるかどうかを確認でき、それらのいずれかがtrueの場合、LCAなしで戻ることができるということです。 これは、ウォーミングアップの演習で行っていることです。
私がこれを間違って理解したかどうか私に知らせて、私がそれを正しくするのを手伝ってください。
@ tibrewalpratik17
そのpdfのグラフはDAGではないため、何も想定する必要はありません。 NaiveLcaFinder
への有効な入力ではありません。
ウォームアップの課題については、グラフを変更して、サイクルが含まれないようにすることをお勧めします。 CycleDetector
を使用して、グラフのバージョンにサイクルがあるかどうかを確認できます。
私のfindLcas
の実装では、循環グラフが与えられたときに、循環を検出したり、賢明な答えを生成するために賢明なことをしたりしません(つまり、 undefined behaviour
を取得します)。 したがって、前提条件が破られた場合、出力を分析しても意味がありません。
@AlexandruValeanu大丈夫です...しかし、ユーザーが循環グラフを入力して出力を期待している場合はどうなりますか?その場合の有効な出力は、特定のノードの最近の祖先のいずれか、またはノード自体がサイクルに関与している場合はnullになります正しい?
ユーザーは答えを期待するべきではありません。その場合、ユーザーは入力を検証する必要があります。これは、fの定義域ではなく、入力xのf(x)と同じであり、答えはnullではありませんが定義されていません。
@ tibrewalpratik17
NaiveLcaFinder
は、DAGが渡された場合にのみ、lcasの正しいリストを返します。
入力がDAGでない場合、出力は信頼されるべきではありません。 文字通り何でもかまいません。 この場合、私の実装はサイクルの一部ではないlcasのみを返すと思いますが、答えがどのようにundefined
であるかをテストしていないため、実際にはわかりません。
バグではないので、誰かがこれを閉じてもらえますか?