Java 源与源之间的有向图中的所有非循环路径;使用记忆的目的地
我正在研究一个问题,这个问题涉及到在一般有向图中存储从源顶点到目标顶点的所有非循环路径(可能是循环的,也可能不是循环的)。输入由一个有向图、一个源顶点和一个目标顶点组成 我已经用Java编写了一个方法来执行这个操作。我使用了记忆的概念,通过存储从源顶点到目标顶点的所有非循环路径,这样,如果我在方法的递归调用期间到达同一个顶点,我就可以使用存储的“路由”,并节省大量计算 在我的算法的递归步骤中(我想)我出了问题,我花了一些时间思考可能是什么错误,但我无法找到答案。我非常感谢在这方面的任何帮助。提前谢谢 哦,如果有人想澄清任何代码块的用途,请发表评论 我基本上在解决问题的方法中使用了DFS。我的代码如下:Java 源与源之间的有向图中的所有非循环路径;使用记忆的目的地,java,algorithm,optimization,recursion,graph-theory,Java,Algorithm,Optimization,Recursion,Graph Theory,我正在研究一个问题,这个问题涉及到在一般有向图中存储从源顶点到目标顶点的所有非循环路径(可能是循环的,也可能不是循环的)。输入由一个有向图、一个源顶点和一个目标顶点组成 我已经用Java编写了一个方法来执行这个操作。我使用了记忆的概念,通过存储从源顶点到目标顶点的所有非循环路径,这样,如果我在方法的递归调用期间到达同一个顶点,我就可以使用存储的“路由”,并节省大量计算 在我的算法的递归步骤中(我想)我出了问题,我花了一些时间思考可能是什么错误,但我无法找到答案。我非常感谢在这方面的任何帮助。提前
//'allEdges' is an ArrayList of all edges of the input graph
/*'Route' is a class that stores the 'src', 'dest' and 'edgeIndices' of 'allEdges'
that comprise the route from 'src' to 'dest'*/
/*'hashMap' is a HashMap<Integer, ArrayList<Route>>. It maps an integer source vertex
to a list of all routes from that vertex to the actual destination vertex to which
the method is initialized from main()*/
static void findPaths(int source, int dest)
{
int i,j,k;
for(i=0;i<allEdges.size();i++)
{
if(allEdges.get(i).getStartNode()==source)
{
ArrayList stack = new ArrayList();
stack.add(i); //pushing edge index to stack
if(allEdges.get(i).getEndNode()==dest)
{
ArrayList<Route> list1 = hashMap.get(source);
if(list1!=null)
{
list1.add(new Route(source,dest,stack));
hashMap.put(source, list1);
}
else
{
ArrayList<Route> list2 = new ArrayList();
list2.add(new Route(source,dest,stack));
hashMap.put(source, list2);
}
}
else
{
int nextNode = allEdges.get(i).getEndNode();
ArrayList<Route> temp = hashMap.get(nextNode);
if(temp!=null)
{
for1: for(j=0;j<temp.size();j++)
{
ArrayList path = temp.get(j).getEdgeIndices();
for(k=0;k<path.size();k++)
{
int edgeIndex = (int)path.get(k);
Edge ed = allEdges.get(edgeIndex);
if(ed.getStartNode()==source)
{
continue for1;
}
}
stack.addAll(path);
ArrayList<Route> list3 = hashMap.get(source);
if(list3!=null)
{
list3.add(new Route(source,dest,stack));
hashMap.put(source,list3);
}
else
{
ArrayList<Route> list4 = new ArrayList();
list4.add(new Route(source,dest,stack));
hashMap.put(source,list4);
}
stack.removeAll(path);
}
}
else
{
findPaths(nextNode, dest);
}
}
}
}
}
现在将上述块修改为以下内容:
if(temp==null)
{
if(!inProcess.contains(nextNode))
{
inProcess.add(nextNode);
findPaths(nextNode,dest);
inProcess.remove(inProcess.indexOf(nextNode));
temp = hashMap.get(nextNode);
}
else
{
continue main_for1; //main_for1 labels the very first for() loop of this method
}
}
我觉得这种修改在某种程度上是不够的。谁能告诉我出了什么问题并纠正我吗?我想你的问题可能是主要陈述的第一行: int nextNode=allEdges.get(i).getEndNode()
这到底是干什么的?在我看来,当您第一次通过路径时,当您还没有找到i的结束节点时,它将返回null。我想我已经修复了它!我发现了两个问题。第一:在递归调用之前(在if-else之前),我们有以下代码:
int nextNode = allEdges.get(i).getEndNode();
ArrayList<Route> temp = hashMap.get(nextNode);
我发现的第二个问题是:
stack.addAll(path);
ArrayList<Route> list3 = hashMap.get(source);
if(list3!=null) {
list3.add(new Route(source,dest,stack));
hashMap.put(source,list3);
} else {
ArrayList<Route> list4 = new ArrayList();
list4.add(new Route(source,dest,stack));
hashMap.put(source,list4);
}
stack.removeAll(path);
stack.addAll(路径);
ArrayList list3=hashMap.get(源代码);
if(list3!=null){
列表3.添加(新路由(源、目标、堆栈));
put(源代码,列表3);
}否则{
ArrayList list4=新的ArrayList();
列表4.添加(新路由(源、目标、堆栈));
hashMap.put(源代码,列表4);
}
stack.removeAll(路径);
请注意,堆栈是在将路由插入hashmap之前添加的,之后从中删除。在if-else语句中创建的route对象引用相同的堆栈,以便更改保存在那里的内容。您想要的是制作一个这样的副本:
ArrayList<Route> list3 = hashMap.get(source);
ArrayList<Integer> copy = new ArrayList<Integer>(stack);
if(list3!=null) {
list3.add(new Route(source, dest,copy));
hashMap.put(source,list3);
} else {
ArrayList<Route> list4 = new ArrayList<Route>();
list4.add(new Route(source, dest, copy));
hashMap.put(source,list4);
}
stack.removeAll(path);
arraylistlist3=hashMap.get(源代码);
ArrayList copy=新的ArrayList(堆栈);
if(list3!=null){
列表3.添加(新路由(源、目标、副本));
put(源代码,列表3);
}否则{
ArrayList list4=新的ArrayList();
列表4.添加(新路由(源、目标、副本));
hashMap.put(源代码,列表4);
}
stack.removeAll(路径);
下面列出了整个函数。很抱歉弄乱了格式
static void findPaths(int source, int dest) {
int i, j, k;
for (i = 0; i < allEdges.size(); i++) {
Edge currentEdge = allEdges.get(i);
if (currentEdge.getStartNode() == source) {
ArrayList<Integer> stack = new ArrayList<Integer>();
stack.add(i); // pushing edge index to stack
if (currentEdge.getEndNode() == dest) {
ArrayList<Route> list1 = hashMap.get(source);
if (list1 != null) {
list1.add(new Route(source, dest, stack));
} else {
ArrayList<Route> list2 = new ArrayList<Route>();
list2.add(new Route(source, dest, stack));
hashMap.put(source, list2);
}
} else {
int nextNode = currentEdge.getEndNode();
ArrayList<Route> temp = hashMap.get(nextNode);
if (temp == null) {
findPaths(nextNode, dest);
temp = hashMap.get(nextNode);
}
if (temp != null) {
for1: for (j = 0; j < temp.size(); j++) {
ArrayList<Integer> path = temp.get(j)
.getEdgeIndices();
for (k = 0; k < path.size(); k++) {
int edgeIndex = (int) path.get(k);
Edge ed = allEdges.get(edgeIndex);
if (ed.getStartNode() == source) {
continue for1;
}
}
stack.addAll(path);
ArrayList<Integer> copy = new ArrayList<Integer>(stack);
ArrayList<Route> list3 = hashMap.get(source);
if (list3 != null) {
list3.add(new Route(source, dest,copy));
} else {
ArrayList<Route> list4 = new ArrayList<Route>();
list4.add(new Route(source, dest, copy));
hashMap.put(source, list4);
}
stack.removeAll(path);
}
}
}
}
}
}
静态void findpath(int源、int目标){
int i,j,k;
对于(i=0;i
有人吗?至少,有人能建议更好的标签以获得更快的回复吗?它会做什么来向您表明它没有按照您希望的方式工作?最好有一个输入和预期输出与实际输出的示例。@Brainstorm进行了编辑:)不是真的allEdges
只是存储所有边的ArrayList
,这些边是我创建的名为Edge
的类的对象。我已经通过打印测试了它是否包含所有的边缘,它们都在那里。索引i
从0运行到allEdges.size()-1
。因此,getEndNode()
将始终返回一些值。从来没有空值。我只是用前面提到的输入测试了你的函数。它现在给出了正确的输出,但是给我一些时间来阅读你的答案。事实上,该方法不适用于循环图<代码>java.lang.StackOverflowerError在运行程序时。确定。也许我误解了输出应该是什么。我得到这个输出,w
ArrayList<Route> list3 = hashMap.get(source);
ArrayList<Integer> copy = new ArrayList<Integer>(stack);
if(list3!=null) {
list3.add(new Route(source, dest,copy));
hashMap.put(source,list3);
} else {
ArrayList<Route> list4 = new ArrayList<Route>();
list4.add(new Route(source, dest, copy));
hashMap.put(source,list4);
}
stack.removeAll(path);
static void findPaths(int source, int dest) {
int i, j, k;
for (i = 0; i < allEdges.size(); i++) {
Edge currentEdge = allEdges.get(i);
if (currentEdge.getStartNode() == source) {
ArrayList<Integer> stack = new ArrayList<Integer>();
stack.add(i); // pushing edge index to stack
if (currentEdge.getEndNode() == dest) {
ArrayList<Route> list1 = hashMap.get(source);
if (list1 != null) {
list1.add(new Route(source, dest, stack));
} else {
ArrayList<Route> list2 = new ArrayList<Route>();
list2.add(new Route(source, dest, stack));
hashMap.put(source, list2);
}
} else {
int nextNode = currentEdge.getEndNode();
ArrayList<Route> temp = hashMap.get(nextNode);
if (temp == null) {
findPaths(nextNode, dest);
temp = hashMap.get(nextNode);
}
if (temp != null) {
for1: for (j = 0; j < temp.size(); j++) {
ArrayList<Integer> path = temp.get(j)
.getEdgeIndices();
for (k = 0; k < path.size(); k++) {
int edgeIndex = (int) path.get(k);
Edge ed = allEdges.get(edgeIndex);
if (ed.getStartNode() == source) {
continue for1;
}
}
stack.addAll(path);
ArrayList<Integer> copy = new ArrayList<Integer>(stack);
ArrayList<Route> list3 = hashMap.get(source);
if (list3 != null) {
list3.add(new Route(source, dest,copy));
} else {
ArrayList<Route> list4 = new ArrayList<Route>();
list4.add(new Route(source, dest, copy));
hashMap.put(source, list4);
}
stack.removeAll(path);
}
}
}
}
}
}