您好我正在创建一个程序来查找伦敦地铁两站之间的路线。我使用链接对象来表示网络。因此,一个台站对象包含:名称,台站所在线路的列表,与其相邻的台站列表。我还有行对象,其中包含:行的名称,站点列表。还有一个网络对象,它包含所有站的列表和所有行的列表。
我正在考虑使用广度优先搜索,但对如何在我的数据结构上实现算法感到困惑。任何帮助将不胜感激。
我还使用了一种不同的方法来查找路径,如果它包含目的地,则搜索源的行。如果它没有,那么查看线路中的交叉点,即超过1线的站点。并查看他们的线路,看看目的地是否在那些。但经过一次改变后,我对如何做一个以上的改变感到困惑。下面是我使用的代码:
public void finder(String from, String to)
{
Station source = network.searchStation(from);
Station destination = network.searchStation(to);
ArrayList<Line> sourceLines = source.getLines();
ArrayList<String> routes = new ArrayList<String>();
for(Line line:sourceLines)
{
ArrayList<Station> stations = line.getStations();
if(stations.contains(destination))
{
Station endStart;
if(stations.indexOf(destination) > stations.indexOf(source))
{
endStart = stations.get(stations.size()-1);
}
else{
endStart = stations.get(0);
}
routes.add(endStart.getName());
routes.add(line.getName());
break;
}
}
if(routes.size() != 0)
{
System.out.println("Start: " + from);
System.out.println("Take the " + routes.get(1) + " line towards " + routes.get(0));
System.out.println("End: " + to);
}
else{
routes = search(source, destination, routes);
System.out.println("Start: " + from);
for(int n = 0; n < (routes.size() / 6);n++)
{
System.out.println("Take the " + routes.get(n + 1) + " line towards " + routes.get(n));
System.out.println("Change at: " + routes.get(n + 2) + " to the " + routes.get(n + 3) + " line");
System.out.println("Take the " + routes.get(n + 5) + " line towards " + routes.get(n + 4));
}
System.out.println("End: " + to);
}
}
public ArrayList<String> search(Station source, Station destination, ArrayList routes)
{
ArrayList<Line> sourceLines = source.getLines();
for(Line line:sourceLines)
{
ArrayList<Station> searchList = new ArrayList<Station>();
ArrayList<Station> lineStations = line.getStations();
if(line.getVisited() == false)
{
for(Station station: lineStations)
{
if(station.getLines().size() > 1)
{
searchList.add(station);
}
}
}
for(Station station:searchList)
{
ArrayList<String> stationChanges = new ArrayList<String>();
ArrayList<Line> lines = station.getLines();
Station endLine;
if(lineStations.indexOf(station) > lineStations.indexOf(source))
{
endLine = lineStations.get(lineStations.size()-1);
}
else{
endLine = lineStations.get(0);
}
stationChanges.add(endLine.getName());
stationChanges.add(line.getName());
for(Line stationLine:lines)
{
ArrayList<Station> stations = stationLine.getStations();
if(stations.contains(destination))
{
stationChanges.add(station.getName());
stationChanges.add(stationLine.getName());
Station endStart;
if(stations.indexOf(destination) > stations.indexOf(station))
{
endStart = stations.get(stations.size()-1);
}
else{
endStart = stations.get(0);
}
stationChanges.add(endStart.getName());
stationChanges.add(stationLine.getName());
for(String str:stationChanges)
{
routes.add(str);
}
return routes;
}
else
{
stationLine.markVisited();
search(station,destination,stationChanges);
}
}
}
}
return routes;
}
由于
答案 0 :(得分:5)
路由完全是另一个问题。您需要使用 dijkstra算法或其变体,简单的BFS或回溯类算法而不需要太多考虑可能会让您误入歧途!
答案 1 :(得分:1)
您应该使用Dijkstra's algorithm。广度优先搜索可能会找到一条路线,但不是最佳路线。您可以使用1作为恒定边缘权重,以获得站点数量中的最短路径。
答案 2 :(得分:1)
听起来你没有成本数据所以你应该只使用BFS。
这篇文章可能会给你一些指示:Finding a route on the Underground using pure Java code
答案 3 :(得分:0)
您需要对每个节点进行加权并找到重量较轻的路线。如果您只是做面包首先,那将返回匹配的第一条路线,可能距离最佳路线数英里。
例如,从相同线路上的相邻站点进行权重1,更改为另一个线路权重2.如果您想从Notthing Hill Gate转到Holland Park,则总权重为1.如果您想从Bayswater到荷兰公园,重量为4(车站1个,换线2个,车站1个)
我不是这方面的专家,但对我而言,这听起来像是一种回溯算法,可以找到最佳路线。
答案 4 :(得分:0)
最重要的是,鉴于问题的本质,您可能希望在更换线路时实施额外的惩罚。
毕竟,如果你正在中心线行驶并改为北行以减少几分钟的旅行时间,你可能会发现自己需要花费超过这几分钟才能到达北线平台并等待下一班火车到达那里。 不能将这些成本计入节点的成本中,因为它只适用于该节点上的一些传入/传出顶点组合(如果你想获得真正的想象和测量,对于不同的组合,惩罚甚至可能不同更换电子管线所需的实际时间。)