Java递归搜索中的路径堆栈
我编写了一个简单的深度优先搜索算法,虽然有效,但无法正确构建补丁。我很难理解为什么——所以,基本上,我需要你们的帮助,伙计们:) 代码如下:Java递归搜索中的路径堆栈,java,search,recursion,Java,Search,Recursion,我编写了一个简单的深度优先搜索算法,虽然有效,但无法正确构建补丁。我很难理解为什么——所以,基本上,我需要你们的帮助,伙计们:) 代码如下: public void Search(String from, String to) { String depart = from; String destin = to; if ( (NoChildren(depart) == false) && (!depart.equalsIgnoreCase(destin))
public void Search(String from, String to) {
String depart = from;
String destin = to;
if ( (NoChildren(depart) == false)
&& (!depart.equalsIgnoreCase(destin)) ) {
while (!depart.equalsIgnoreCase(to)) {
closeStack.push(depart);
depart = getChildren(depart);
}
}
}
public boolean NoChildren(String from) {
boolean noChildren = false;
int counter = 0;
for(int j = 0; j < Flights.size(); j++) {
FlightInfo flight = (FlightInfo)Flights.elementAt(j);
if (flight.from().equalsIgnoreCase(from)) {
counter++;
}
}
if (counter == 0) {
noChildren = true;
}
return noChildren;
}
public String getChildren(String from) {
for(int j = 0; j < Flights.size(); j++) {
FlightInfo flight = (FlightInfo)Flights.elementAt(j);
if (flight.from().equalsIgnoreCase(from)) {
openStack.push(flight.to().toString());
}
}
return openStack.pop().toString();
}
public void搜索(字符串从,字符串到){
字符串偏离=从;
字符串destin=to;
如果((无子女(离开)=假)
&&(!出发同等信号(目的地))){
当(!出发等信号情况(至)){
关闭堆栈。推动(离开);
离开=得到孩子(离开);
}
}
}
公共布尔NoChildren(字符串来自){
布尔noChildren=false;
int计数器=0;
对于(intj=0;j
我把它做得更长只是为了清理,并计划对它进行优化-只需要让它首先正常工作:))
好的,主要的问题是closeStack,它本来应该包含从开始到结束的路径,但是现在,它包含了算法检查的任何内容:-[
Thanx提前!!Maxim,你的代码中有一大堆错误。看起来你对你想做的事情有了一个想法,然后扔了一些代码,直到有东西出现并起到了作用,但这里没有明确的概念,因此难怪它没有真正起作用 这个程序的核心是Flights集合(为什么
Flights
uppercased?),很有可能围绕它构建一个工作的路由查找器。我不确定给你一些提示或者简单地为你构建程序是否会对你有更大的帮助
更新:与此同时,我找到了一家波兰航空公司的航班时刻表(不要问!),其中有203条不同的航线,我可以用它们来填充和测试航班连接结构。我将开始黑客攻击,我们将看看如何进行
更新:以下是代码 为了对您的明显目的有所帮助,仅查找路线(即访问的机场的行程)可能是不够的;您可能需要一份航班列表。当然,请注意,可能有多个航班组合具有相同的行程-此代码只查找第一个 如果你有旅行时间,你可能想修改算法,在旅行时间上加一个权重(=成本),这样你的乘客就不会只得到最少的航段(=从一个机场到下一个机场的跳跃)但同时也是最短的组合旅行时间。这种更普遍的算法形式将被称为Dijkstra算法,维基百科中也有描述 有趣的是,BFS似乎并不真正适合递归解决方案。与您的原始代码一样,我的代码本质上是必需的,只有几个循环。请注意,执行BFS的正确“主”数据结构不是堆栈,而是队列
public class Maxim {
/**
* Create a Maxim instance and run a search on it.
*/
public static void main(String[] args) {
try {
Maxim maxim = new Maxim();
Route r = maxim.findRoute("FCO", "DNV"); // tests a single origin/destination pair
if (r == null) {
System.out.println("No route found");
} else {
System.out.println(Arrays.deepToString(r.toArray()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* A simple Flight. Contains a flight number and only a single leg.
* number: Flight number
* dep: Departure airport
* arr: Arrival airport
*/
class Flight {
final String number, dep, arr;
public Flight(String number, String departure, String arrival) {
this.number = number; this.dep = departure; this.arr = arrival;
}
public String toString() {
return "Flight [number=" + this.number + ", dep=" + this.dep + ", arr=" + this.arr + "]";
}
}
/**
* Airport: A city and a list of Flights originating from it.
*/
class Airport {
public final String city;
public List<Flight> flights = new ArrayList<Flight>();
public Airport(String city) {
this.city = city;
}
public String toString() {
return "Airport [city=" + this.city + ", flights=" + this.flights + "]";
}
}
/**
* Route: A list of flights that get a traveller from a given origin to a destination.
*/
static class Route extends ArrayList<Flight> { }
/**
* Our known list of flights. It's not really needed after initialization.
*/
private List<Flight> flights = new ArrayList<Flight>();
/**
* List of airports. These constitute the graph we search.
*/
private Map<String, Airport> airports = new HashMap<String, Airport>();
/**
* Constructor. Constructs the "airports" graph from a list of "flights" read from a file.
*/
public Maxim() throws Exception {
// Read flights from file into list "flights".
// The file contains strings like " 696KGDWAW" = flight number, departure airport, arrival airport
BufferedReader flightReader = new BufferedReader(new FileReader("/home/carl/XX.flights"));
while (true) {
String flt = flightReader.readLine();
if (flt == null) break;
flights.add(new Flight(flt.substring(0,4), flt.substring(4, 7), flt.substring(7, 10)));
}
flightReader.close();
// Create a map of each airport to a list of Flights departing from it.
// This is the graph we'll be doing BFS on.
for (Flight flight : flights) {
String from = flight.dep;
if (!airports.containsKey(from)) {
Airport port = new Airport(from);
port.flights.add(flight);
airports.put(from, port);
} else {
Airport port = airports.get(from);
port.flights.add(flight);
}
}
}
/**
Algorithm (from Wikipedia):
1. Enqueue the root node.
2. Dequeue a node and examine it.
If the element sought is found in this node, quit the search and return a result.
Otherwise enqueue any successors (the direct child nodes) that have not yet been discovered.
3. If the queue is empty, every node on the graph has been examined – quit the search and return "not found".
4. Repeat from Step 2.
*/
public Route findRoute(String origin, String destination) {
Queue<Airport> queue = new LinkedList<Airport>();
Map<Airport, Flight> backtrack = new HashMap<Airport, Flight>();
Airport oriApt = this.airports.get(origin);
if (oriApt == null) return null; // origin airport not found - no solution
queue.add(oriApt);
while (!queue.isEmpty()) {
Airport apt = queue.remove();
if (apt == null) break;
if (apt.city.equals(destination)) { // Made it to destination; create the route and return it
Route toHere = new Route();
while (apt != oriApt) {
Flight flt = backtrack.get(apt);
toHere.add(flt);
apt = airports.get(flt.dep);
}
Collections.reverse(toHere);
return toHere;
}
// enqueue all new airports reachable from this airport.
// record the flight that got us there in backtrack.
for (Flight flt: apt.flights) {
Airport destApt = airports.get(flt.arr);
if (backtrack.containsKey(destApt)) continue; // we've been to this destination before - ignore
backtrack.put(destApt, flt);
queue.add(destApt);
}
}
// if we're here, we didn't find anything.
return null;
}
}
公共类格言{
/**
*创建一个Maxim实例并在其上运行搜索。
*/
公共静态void main(字符串[]args){
试一试{
Maxim Maxim=新的Maxim();
Route r=maxim.Findulote(“FCO”、“DNV”);//测试一个源/目的地对
if(r==null){
System.out.println(“未找到路由”);
}否则{
System.out.println(Arrays.deepToString(r.toArray());
}
}捕获(例外e){
e、 printStackTrace();
}
}
/**
*一个简单的航班。包含一个航班号,只有一条航段。
*号码:航班号
*副:离境机场
*到达机场
*/
班机{
最终字符串编号,dep,arr;
公共航班(航班号、航班起飞、航班到达){
this.number=编号;this.dep=出发;this.arr=到达;
}
公共字符串toString(){
return“Flight[number=“+this.number+”,dep=“+this.dep+”,arr=“+this.arr+””;
}
}
/**
*机场:一个城市和一份从该城市出发的航班列表。
*/
头等机场{
公共城市;
public List flights=new ArrayList();
公共机场(字符串城市){
this.city=城市;
}
公共字符串toString(){
返回“Airport[city=“+this.city+”,flights=“+this.flights+””;
}
}
/**
*航线:使旅客从给定的起点到达目的地的航班列表。
*/
静态类路由扩展ArrayList{}
/**
*我们已知的航班列表。初始化后并不需要它。
*/
private List flights=new ArrayList();
/**
*机场列表。这些构成了我们搜索的图表。
*/
私有地图机场=新HashMap();
/**
*构造器。从文件中读取的“航班”列表构造“机场”图。
*/
public Maxim()引发异常{
//将文件中的航班读取到“航班”列表中。
//该文件包含“696KGDWAW”=航班号、出发机场、到达机场等字符串
BufferedReader flightReader=新的BufferedReader(新文件阅读器(“/home/carl/XX.flights”);
while(true){
字符串flt=flightReader.readLine();
如果(flt==null)中断;
航班添加(新航班(航班子串(0,4)、航班子串(4,7)、航班子串(7,10));
}
flightReader.close();
//创建每个机场的地图,以列出离开机场的航班。
//这是我们将要进行BFS的图表。
适用于(航班:航班){
字符串from=flight.dep;
如果(!airports.contai)