我正在一个通过图表递归执行DFS的项目。
问题是我在两个不同的类(具有不同的名称)中具有完全相同的代码,并且一个设法有效地执行递归,另一个失败并抛出StackOverflowError。这是相同的计算和相同的过程,他们试图解决相同的代码。这有什么理由吗?
修改
以下是代码:
package mundo.ParteA;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.BitSet;
import java.util.Set;
import estructuras.GrafoDirigidoLAdy;
import estructuras.HashTable;
import estructuras.ListaDoble;
import estructuras.Dijkstra.DijkstrasSP;
import mundo.PesosProyecto3;
import mundo.ProcessCSV;
import mundo.Punto;
import mundo.VerticeBogota;
public class ParteAA {
//-----------------------------------------------------------------
// Constantes
//-----------------------------------------------------------------
/**
* Constante que establece la ubicación del archivo kml que se produce al calcular la
* ruta entre dos puntos del grafo
*/
private static final String OUTPUT_FILE = "./data/outputParteA";
//-----------------------------------------------------------------
// Atributos
//-----------------------------------------------------------------
private HashTable<String, String> definitions;
private GrafoDirigidoLAdy<Integer, VerticeBogota> grafoVerticesBogota;
private HashTable<String, Set<Integer>> diccionarioNombres;
private HashTable<Punto, VerticeBogota> diccionarioCoordenadas;
private int numArchivo;
//-----------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------
public ParteAA()
{
numArchivo = 0;
cargarDatos();
}
//-----------------------------------------------------------------
// Métodos
//-----------------------------------------------------------------
public static void main(String... args)
{
ParteAA x = new ParteAA();
for(Integer i : x.centrosAcopioEnRango(4277, 70)){
System.out.println(i);
}
// try {
// for(Integer i: x.calcularRutaMasCortaDistanciaYMostrarlaEnMaps(3077, 123512, 3, 7))
// System.out.println(i);
// } catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
/**
* Método que carga los datos para la inicialización.
*/
public void cargarDatos()
{
ProcessCSV csv = new ProcessCSV(PesosProyecto3.TipoPesos.DISTANCIA);
definitions = csv.getDefinitions();
grafoVerticesBogota = csv.getGrafo();
diccionarioNombres = csv.getDiccionarioNombres();
diccionarioCoordenadas = csv.getDiccionarioCoordenadas();
}
/**
* Método que se encarga de calcular la ruta más corta entre dos nodos y representarla en GoogleMaps
* @param origen
* @param destino
* @param espacioBusquedaOrigen
* @param espacioBusquedaDestino
* @return
*/
public Iterable<Integer> calcularRutaMasCortaDistanciaYMostrarlaEnMaps(int idOrigen, int idDestino, double espacioBusquedaOrigen , double espacioBusquedaDestino) throws Exception
{
VerticeBogota origen = grafoVerticesBogota.getVertice(idOrigen);
VerticeBogota destino = grafoVerticesBogota.getVertice(idDestino);
if(origen==null||destino==null){
System.out.println("No existe alguno de los dos vertices ingresados por parámetro. \nHasta Luego!");
System.exit(0);
}
ListaDoble<Integer> listaSalida = (ListaDoble<Integer>) centrosAcopioEnRango(idOrigen, espacioBusquedaOrigen);
ListaDoble<Integer> listaLlegada = (ListaDoble<Integer>) centrosAcopioEnRango(idDestino, espacioBusquedaDestino);
if(listaSalida.isEmpty() || listaLlegada.isEmpty())
{
throw new Exception("No hay ningún centro de acopio en alguno de los rangos dados. \nPor favor incremente el área de busqueda");
}
double distMenor = Double.POSITIVE_INFINITY;
Iterable<Integer> rutaOptima = null;
for(Integer i : listaSalida)
{
DijkstrasSP sp = new DijkstrasSP(grafoVerticesBogota, i);
for(Integer j : listaLlegada)
{
if(sp.distTo(j)<distMenor)
{
distMenor = sp.distTo(j);
if(distMenor==0)
{
distMenor = 0;
}
rutaOptima = sp.caminoA(j);
}
}
}
System.out.println(distMenor);
getShortestPathFile(rutaOptima);
return rutaOptima;
}
/**
* Calcula la distancia entre dos puntos.
* @param origen - Punto inicial.
* @param destino - Punto de llegada.
* @return distKm - La distancia en kilometros entre los dos puntos.
*/
private static double haversineDist(Punto origen, Punto destino)
{
long radioTierra = 6371;
double rad = Math.PI/180;
return Math.acos(
Math.sin(origen.getLatitude()*rad) * Math.sin(destino.getLatitude()*rad)
+ Math.cos(origen.getLatitude()*rad) * Math.cos(destino.getLatitude()*rad)
* Math.cos(destino.getLongitude()*rad - origen.getLongitude()*rad)
) * radioTierra;
}
/**
* Método que busca los centros de acopio que están dentro del radio de búsqueda dada una ubicación
*/
private Iterable<Integer> centrosAcopioEnRango(int origen, double distKm)
{
BitSet marked = new BitSet(grafoVerticesBogota.getNumVertices());
ListaDoble<Integer> verticesEnRango = new ListaDoble<Integer>();
haversineDFS(verticesEnRango, marked, origen, origen, distKm);
return verticesEnRango;
}
private void haversineDFS(ListaDoble<Integer> verticesEnRango, BitSet marked, int orig, int actual, double distKm) {
marked.set(actual);
if(grafoVerticesBogota.getVertice(actual).isCentroDeAcopio()){ verticesEnRango.add(actual); }
for(GrafoDirigidoLAdy<Integer, VerticeBogota>.Arco arc : grafoVerticesBogota.getAdy(actual))
{
double dis = haversineDist(grafoVerticesBogota.getVertice(orig).getUbicacion(), arc.getTo().getUbicacion());
if(dis<=distKm && !marked.get(arc.getTo().getId()))
{
haversineDFS(verticesEnRango, marked, orig, arc.getTo().getId(), distKm);
}
}
}
//-----------------------------------------------------------------
// KML Output
//-----------------------------------------------------------------
/**
* Escribe el archivo kml de salida con la información de la ruta más corta del nodo idSource al nodo idDestination
* Este archivo se puede importar a google maps para visualizar la ruta
* @param idSource int El identificador de la fuente
* @param idDestination int El identificador del destino
*/
private void getShortestPathFile(Iterable<Integer> ruta) {
numArchivo++;
File f = new File(OUTPUT_FILE+numArchivo+".kml");
try {
if(!f.exists()) {
f.createNewFile();
}
FileWriter fw = new FileWriter(f);
PrintWriter pw = new PrintWriter(fw);
writeKMLHeader(pw);
for(Integer i : ruta)
{
pw.println(" " + grafoVerticesBogota.getVertice(i).getUbicacion().getLongitude() + ", " + grafoVerticesBogota.getVertice(i).getUbicacion().getLatitude());
}
writeKMLFooter(pw);
fw.flush();
fw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Escribe el encabezado de un archivo kml
* @param pw El PrintWriter que escribe al archivo
* @throws IOException En caso de que haya un error a la hora de escribir en el archivo
*/
private void writeKMLHeader(PrintWriter pw) throws IOException
{
pw.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
pw.println("<kml xmlns=\"http://www.opengis.net/kml/2.2\">");
pw.println(" <Document>");
pw.println(" <name>Ruta más corta</name>");
pw.println(" <Placemark>");
pw.println(" <name>Ruta más corta</name>");
pw.println(" <LineString>");
pw.println(" <altitudeMode>absolute</altitudeMode>");
pw.println(" <coordinates>");
}
/**
* Escribe el pie de pagina de un archivo kml
* @param pw El PrintWriter que escribe al archivo
* @throws IOException En caso de que haya un error a la hora de escribir en el archivo
*/
private void writeKMLFooter(PrintWriter pw) throws IOException
{
pw.println(" </coordinates>");
pw.println(" </LineString>");
pw.println(" </Placemark>");
pw.println(" </Document>");
pw.println("</kml>");
}
//-----------------------------------------------------------------
// Getters y Setters
//-----------------------------------------------------------------
public HashTable<String, String> getDefinitions() {
return definitions;
}
public void setDefinitions(HashTable<String, String> definitions) {
this.definitions = definitions;
}
public GrafoDirigidoLAdy<Integer, VerticeBogota> getGrafoVerticesBogota() {
return grafoVerticesBogota;
}
public void setGrafoVerticesBogota(GrafoDirigidoLAdy<Integer, VerticeBogota> grafoVerticesBogota) {
this.grafoVerticesBogota = grafoVerticesBogota;
}
public HashTable<String, Set<Integer>> getDiccionarioNombres() {
return diccionarioNombres;
}
public void setDiccionarioNombres(HashTable<String, Set<Integer>> diccionarioNombres) {
this.diccionarioNombres = diccionarioNombres;
}
public HashTable<Punto, VerticeBogota> getDiccionarioCoordenadas() {
return diccionarioCoordenadas;
}
public void setDiccionarioCoordenadas(HashTable<Punto, VerticeBogota> diccionarioCoordenadas) {
this.diccionarioCoordenadas = diccionarioCoordenadas;
}
}
这是另一个:
package mundo.ParteB;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.BitSet;
import java.util.Set;
import estructuras.GrafoDirigidoLAdy;
import estructuras.HashTable;
import estructuras.ListaDoble;
import estructuras.Dijkstra.DijkstrasSP;
import mundo.PesosProyecto3;
import mundo.ProcessCSV;
import mundo.Punto;
import mundo.VerticeBogota;
public class ParteBB{
//-----------------------------------------------------------------
// Constantes
//-----------------------------------------------------------------
/**
* Constante que establece la ubicación del archivo kml que se produce al calcular la
* ruta entre dos puntos del grafo
*/
private static final String OUTPUT_FILE = "./data/outputParteA";
//-----------------------------------------------------------------
// Atributos
//-----------------------------------------------------------------
private HashTable<String, String> definitions;
private GrafoDirigidoLAdy<Integer, VerticeBogota> grafoVerticesBogota;
private HashTable<String, Set<Integer>> diccionarioNombres;
private HashTable<Punto, VerticeBogota> diccionarioCoordenadas;
private int numArchivo;
//-----------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------
public ParteBB()
{
numArchivo = 0;
cargarDatos();
}
//-----------------------------------------------------------------
// Métodos
//-----------------------------------------------------------------
public static void main(String... args)
{
ParteBB x = new ParteBB();
for(Integer i : x.centrosAcopioEnRango(4277, 70)){
System.out.println(i);
}
// try {
// for(Integer i: x.calcularRutaMasCortaDistanciaYMostrarlaEnMaps(3077, 123512, 3, 7))
// System.out.println(i);
// } catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
/**
* Método que carga los datos para la inicialización.
*/
public void cargarDatos()
{
ProcessCSV csv = new ProcessCSV(PesosProyecto3.TipoPesos.DISTANCIA);
definitions = csv.getDefinitions();
grafoVerticesBogota = csv.getGrafo();
diccionarioNombres = csv.getDiccionarioNombres();
diccionarioCoordenadas = csv.getDiccionarioCoordenadas();
}
/**
* Método que se encarga de calcular la ruta más corta entre dos nodos y representarla en GoogleMaps
* @param origen
* @param destino
* @param espacioBusquedaOrigen
* @param espacioBusquedaDestino
* @return
*/
public Iterable<Integer> calcularRutaMasCortaDistanciaYMostrarlaEnMaps(int idOrigen, int idDestino, double espacioBusquedaOrigen , double espacioBusquedaDestino) throws Exception
{
VerticeBogota origen = grafoVerticesBogota.getVertice(idOrigen);
VerticeBogota destino = grafoVerticesBogota.getVertice(idDestino);
if(origen==null||destino==null){
System.out.println("No existe alguno de los dos vertices ingresados por parámetro. \nHasta Luego!");
System.exit(0);
}
ListaDoble<Integer> listaSalida = (ListaDoble<Integer>) centrosAcopioEnRango(idOrigen, espacioBusquedaOrigen);
ListaDoble<Integer> listaLlegada = (ListaDoble<Integer>) centrosAcopioEnRango(idDestino, espacioBusquedaDestino);
if(listaSalida.isEmpty() || listaLlegada.isEmpty())
{
throw new Exception("No hay ningún centro de acopio en alguno de los rangos dados. \nPor favor incremente el área de busqueda");
}
double distMenor = Double.POSITIVE_INFINITY;
Iterable<Integer> rutaOptima = null;
for(Integer i : listaSalida)
{
DijkstrasSP sp = new DijkstrasSP(grafoVerticesBogota, i);
for(Integer j : listaLlegada)
{
if(sp.distTo(j)<distMenor)
{
distMenor = sp.distTo(j);
if(distMenor==0)
{
distMenor = 0;
}
rutaOptima = sp.caminoA(j);
}
}
}
System.out.println(distMenor);
getShortestPathFile(rutaOptima);
return rutaOptima;
}
/**
* Calcula la distancia entre dos puntos.
* @param origen - Punto inicial.
* @param destino - Punto de llegada.
* @return distKm - La distancia en kilometros entre los dos puntos.
*/
private static double haversineDist(Punto origen, Punto destino)
{
long radioTierra = 6371;
double rad = Math.PI/180;
return Math.acos(
Math.sin(origen.getLatitude()*rad) * Math.sin(destino.getLatitude()*rad)
+ Math.cos(origen.getLatitude()*rad) * Math.cos(destino.getLatitude()*rad)
* Math.cos(destino.getLongitude()*rad - origen.getLongitude()*rad)
) * radioTierra;
}
/**
* Método que busca los centros de acopio que están dentro del radio de búsqueda dada una ubicación
*/
private Iterable<Integer> centrosAcopioEnRango(int origen, double distKm)
{
BitSet marked = new BitSet(grafoVerticesBogota.getNumVertices());
ListaDoble<Integer> verticesEnRango = new ListaDoble<Integer>();
haversineDFS(verticesEnRango, marked, origen, origen, distKm);
return verticesEnRango;
}
private void haversineDFS(ListaDoble<Integer> verticesEnRango, BitSet marked, int orig, int actual, double distKm) {
marked.set(actual);
if(grafoVerticesBogota.getVertice(actual).isCentroDeAcopio()){ verticesEnRango.add(actual); }
for(GrafoDirigidoLAdy<Integer, VerticeBogota>.Arco arc : grafoVerticesBogota.getAdy(actual))
{
double dis = haversineDist(grafoVerticesBogota.getVertice(orig).getUbicacion(), arc.getTo().getUbicacion());
if(dis<=distKm && !marked.get(arc.getTo().getId()))
{
haversineDFS(verticesEnRango, marked, orig, arc.getTo().getId(), distKm);
}
}
}
//-----------------------------------------------------------------
// KML Output
//-----------------------------------------------------------------
/**
* Escribe el archivo kml de salida con la información de la ruta más corta del nodo idSource al nodo idDestination
* Este archivo se puede importar a google maps para visualizar la ruta
* @param idSource int El identificador de la fuente
* @param idDestination int El identificador del destino
*/
private void getShortestPathFile(Iterable<Integer> ruta) {
numArchivo++;
File f = new File(OUTPUT_FILE+numArchivo+".kml");
try {
if(!f.exists()) {
f.createNewFile();
}
FileWriter fw = new FileWriter(f);
PrintWriter pw = new PrintWriter(fw);
writeKMLHeader(pw);
for(Integer i : ruta)
{
pw.println(" " + grafoVerticesBogota.getVertice(i).getUbicacion().getLongitude() + ", " + grafoVerticesBogota.getVertice(i).getUbicacion().getLatitude());
}
writeKMLFooter(pw);
fw.flush();
fw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Escribe el encabezado de un archivo kml
* @param pw El PrintWriter que escribe al archivo
* @throws IOException En caso de que haya un error a la hora de escribir en el archivo
*/
private void writeKMLHeader(PrintWriter pw) throws IOException
{
pw.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
pw.println("<kml xmlns=\"http://www.opengis.net/kml/2.2\">");
pw.println(" <Document>");
pw.println(" <name>Ruta más corta</name>");
pw.println(" <Placemark>");
pw.println(" <name>Ruta más corta</name>");
pw.println(" <LineString>");
pw.println(" <altitudeMode>absolute</altitudeMode>");
pw.println(" <coordinates>");
}
/**
* Escribe el pie de pagina de un archivo kml
* @param pw El PrintWriter que escribe al archivo
* @throws IOException En caso de que haya un error a la hora de escribir en el archivo
*/
private void writeKMLFooter(PrintWriter pw) throws IOException
{
pw.println(" </coordinates>");
pw.println(" </LineString>");
pw.println(" </Placemark>");
pw.println(" </Document>");
pw.println("</kml>");
}
//-----------------------------------------------------------------
// Getters y Setters
//-----------------------------------------------------------------
public HashTable<String, String> getDefinitions() {
return definitions;
}
public void setDefinitions(HashTable<String, String> definitions) {
this.definitions = definitions;
}
public GrafoDirigidoLAdy<Integer, VerticeBogota> getGrafoVerticesBogota() {
return grafoVerticesBogota;
}
public void setGrafoVerticesBogota(GrafoDirigidoLAdy<Integer, VerticeBogota> grafoVerticesBogota) {
this.grafoVerticesBogota = grafoVerticesBogota;
}
public HashTable<String, Set<Integer>> getDiccionarioNombres() {
return diccionarioNombres;
}
public void setDiccionarioNombres(HashTable<String, Set<Integer>> diccionarioNombres) {
this.diccionarioNombres = diccionarioNombres;
}
public HashTable<Punto, VerticeBogota> getDiccionarioCoordenadas() {
return diccionarioCoordenadas;
}
public void setDiccionarioCoordenadas(HashTable<Punto, VerticeBogota> diccionarioCoordenadas) {
this.diccionarioCoordenadas = diccionarioCoordenadas;
}
}
答案 0 :(得分:1)
一种情况是您成功构建代码,然后更改代码并认为它已正确编译,但它没有,所以我猜测您认为相同的代码可能不是&# 39; t实际上是相同的代码。
另外,我假设你两次使用相同的输入。
答案 1 :(得分:1)
好的,我已经弄清楚它是什么,运行配置。对于一个班级设置了更大的堆栈,我花了一段时间才注意到!非常感谢所有帮助过的人!