Dijsktra
import java.io.File;
import java.net.ServerSocket;
import java.util.*;
public class Dijkstra {
LinkedHashSet<String> set;//去除重复元素用
HashMap<String,Integer> map1;
HashMap<Integer,String> map2;
public Dijkstra() {
set=new LinkedHashSet<>();
map1=new HashMap<>();
map2=new HashMap<>();
}
public void ID(Train t, Plane p){
for(int i=0;i<t.ll.size();i++){
this.set.add(t.ll.get(i).site);
}
for(int i=0;i<p.ll.size();i++){
this.set.add(p.ll.get(i).l_site);
this.set.add(p.ll.get(i).a_site);
}
Iterator it=this.set.iterator();
int m=0;
for(String str:set){
this.map1.put(str,m);
//把所有的站点都依次排好编号
this.map2.put(m,str);
//方便回传到文件中的时候流传递
m++;
}
}
public void MinPrice(Train t,Plane p,String l_site,String a_site,int op,File file){
ID(t, p);
int l=map1.get(l_site);
int a=map1.get(a_site);
int [][]price_map=new int[set.size()][set.size()];
for (int i=0;i<set.size();i++){
for(int j=0;j<set.size();j++){
if(i==j){
price_map[i][j]=0;
}else {
price_map[i][j]=-1;
}
}
}
//高铁的动态化初始价格二维数组
for(int i=0;i<t.ll.size();i++){
for(int j=0;j<t.ll.size();j++){
if(j>=i){
price_map[i][j]=t.ll.get(j).price-t.ll.get(i).price;
}
}
}
//飞机的初始化价格二维数组
for(int j=0;j<p.ll.size();j++){
int t1=map1.get(p.ll.get(j).l_site);
int t2=map1.get(p.ll.get(j).a_site);
if (price_map[t1][t2]>p.ll.get(j).price||price_map[t1][t2]==-1){
price_map[t1][t2]=p.ll.get(j).price;
}
}
String[] str= set.toArray(new String[0]);
test T=new test(set.size());
T.dijkstra(price_map,str,l,a,op,file);
}
public void MinTime(Train t,Plane p,String l_site,String a_site,int op,File file){
ID(t, p);
int l=map1.get(l_site);
int a=map1.get(a_site);
int [][]time_map=new int[set.size()][set.size()];
for (int i=0;i<set.size();i++){
for(int j=0;j<set.size();j++){
if(i==j){
time_map[i][j]=0;
}else {
time_map[i][j]=-1;
}
}
}
//高铁的动态化初始时间二维数组
for(int i=0;i<t.ll.size();i++){
for(int j=1;j<t.ll.size()-i;j++){
int temp=0;
Time t1=new Time(t.ll.get(i).l_time);
Time t2=new Time(t.ll.get(i+j).a_time);
temp=t2.subtractTime(t1);
time_map[i][i+j]=temp;
}
}
//飞机的初始化时间二维数组
for(int j=0;j<p.ll.size();j++){
int m1=map1.get(p.ll.get(j).l_site);
int m2=map1.get(p.ll.get(j).a_site);
Time t1=new Time(p.ll.get(j).l_time);
Time t2=new Time(p.ll.get(j).a_time);
int temp=t1.subtractTime(t2);
if (time_map[m1][m2]>temp||time_map[m1][m2]==-1){
time_map[m1][m2]=temp;
}
}
String[] str= set.toArray(new String[0]);
test T=new test(set.size());
T.dijkstra(time_map,str,l,a,op,file);
}
public void MinFreq(Train t,Plane p,String l_site,String a_site,int op,File file){
ID(t, p);
int l=map1.get(l_site);
int a=map1.get(a_site);
int [][]freq_map=new int[set.size()][set.size()];
for (int i=0;i<set.size();i++){
for(int j=0;j<set.size();j++){
if(i==j){
freq_map[i][j]=0;
}else {
freq_map[i][j]=-1;
}
}
}
//高铁的动态化转乘次数二维数组
for(int i=0;i<t.ll.size();i++){
for(int j=0;j<t.ll.size();j++){
if (j>=i){
freq_map[i][j]=j-i;
}
}
}
//飞机的初始化转乘次数二维数组
for(int j=0;j<p.ll.size();j++){
int m1=map1.get(p.ll.get(j).l_site);
int m2=map1.get(p.ll.get(j).a_site);
if (freq_map[m1][m2]>1||freq_map[m1][m2]==-1){
freq_map[m1][m2]=1;
}
}
String[] str= set.toArray(new String[0]);
test T=new test(set.size());
T.dijkstra(freq_map,str,l,a,op,file);
}
public void search(Train t,Plane p,String l_site,String a_site,int op,File file){
List<Node> nodes=new ArrayList<>();
for(int i=0;i<t.ll.size()-1;i++){
String string=t.ll.get(i).site+"通过高铁到"+t.ll.get(i+1).site+"\n";
nodes.add(new Node(t.ll.get(i).site,t.ll.get(i+1).site,string));
}
Set<Node>set=new HashSet<>();
for (int i=0;i<p.ll.size();i++){
String string=p.ll.get(i).l_site+"通过飞机到"+p.ll.get(i).a_site+"\n";
set.add(new Node(p.ll.get(i).l_site,p.ll.get(i).a_site,string));
}
for(Node node:set){
nodes.add(node);
}
PointsPath.findAllPath(nodes,l_site,a_site);
}
}
MAIN
import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
import java.io.File;
import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Scanner;
public class MAIN {
public static void main(String[] args) throws IOException {
Scanner sc=new Scanner(System.in);
File file_train=new File("D:\\Java_IO\\Train.txt");
//用于导入和追加高铁数据的文件地址
File file_plane=new File("D:\\Java_IO\\Plane.txt");
//用于导入和追加航班数据的文件地址
File file_routes=new File("D:\\Java_IO\\Routes.txt");
Train t=new Train();
t.Creat(file_train);
Plane p=new Plane();
p.Creat(file_plane);
boolean flag=true;
//指示标志
Meau.meau();
while(flag){
System.out.print("请输入你的选择:");
int i=sc.nextInt();
//System.in.read()读取的是字符类型,input:1 output:49 **下次注意**
/*System.out.println(i);*/
switch (i){
case 1:
t.ll.forEach(System.out::println);
p.ll.forEach(System.out::println);
break;
case 2:{
System.out.println("请输入要添加的票类型为:1.高铁票 2.飞机票");
int temp=sc.nextInt();
sc.nextLine();
/*
这个sc.nextLine用于吃掉换行符,否则下面的有效输入会被换行符直接跳过
*/
if(temp==1) {
t.ll.forEach(System.out::println);
System.out.println("请输入你要添加到的位置行数:");
int op=sc.nextInt();
sc.nextLine();
System.out.println("请依次输入车次,站点,到站时间, 发车时间,票价");
String cur = sc.nextLine();
String res[]=cur.split(" ");
t.ll.add(op-1,new TrainTicket(res[0],res[1],res[2],res[3],Integer.parseInt(res[4].trim())));
t.Write_back(file_train,t.ll,2);
/*t.Write_back(file_train,new TrainTicket(res[0],res[1],res[2],res[3],Integer.parseInt(res[4].trim())));*/
}else {
p.ll.forEach(System.out::println);
System.out.println("请输入你要添加到的位置行数:");
int op=sc.nextInt();
sc.nextLine();
System.out.println("请依次输入航班号,起点站,终点站,起飞时间,到达时间,票价=");
String cur = sc.nextLine();
String res[]=cur.split(" ");
p.ll.add(op-1,new PlaneTicket(res[0],res[1],res[2],res[3],res[4],Integer.parseInt(res[5].trim())));
p.Write_back(file_plane,p.ll,2);
/*p.Write_back(file_plane,new PlaneTicket(res[0],res[1],res[2],res[3],res[4],Integer.parseInt(res[5].trim())));*/
}
break;
}
case 3:{
System.out.println("请输入要删除的票类型为:1.高铁票 2.飞机票");
int temp=sc.nextInt();
sc.nextLine();
if(temp==1) {
System.out.println("请依次输入车次,站点,到站时间, 发车时间,票价");
String cur = sc.nextLine();
String res[]=cur.split(" ");
TrainTicket tt=new TrainTicket(res[0],res[1],res[2],res[3],Integer.parseInt(res[4].trim()));
t.ll.remove(tt);
t.Write_back(file_train,t.ll,3);
}else {
System.out.println("请依次输入航班号,起点站,终点站,起飞时间,到达时间,票价");
String cur = sc.nextLine();
String res[]=cur.split(" ");
PlaneTicket pt=new PlaneTicket(res[0],res[1],res[2],res[3],res[4],Integer.parseInt(res[5].trim()));
p.ll.remove(pt);
p.Write_back(file_plane,p.ll,3);
}
break;
}
case 4:{
System.out.println("请输入要修改的票类型:1.高铁票,2.飞机票");
int temp=sc.nextInt();
sc.nextLine();
if(temp==1) {
t.ll.forEach(System.out::println);
System.out.println("请输入你要修改的行数:");
int index=sc.nextInt();
sc.nextLine();
t.ll.remove(index-1);
//大多数人习惯从1开始,所以这里把指示减一处理
System.out.println("请依次输入修改后的车次,站点,到站时间, 发车时间,票价");
String cur = sc.nextLine();
String res[]=cur.split(" ");
TrainTicket tt=new TrainTicket(res[0],res[1],res[2],res[3],Integer.parseInt(res[4].trim()));
t.ll.add(index-1,tt);
t.Write_back(file_train,t.ll,4);
}else {
p.ll.forEach(System.out::println);
System.out.println("请输入你要修改的行数:");
int index=sc.nextInt();
sc.nextLine();
p.ll.remove(index-1);
System.out.println("请依次输入航班号,起点站,终点站,起飞时间,到达时间,票价");
String cur = sc.nextLine();
String res[]=cur.split(" ");
PlaneTicket pt=new PlaneTicket(res[0],res[1],res[2],res[3],res[4],Integer.parseInt(res[5].trim()));
p.ll.add(index-1,pt);
p.Write_back(file_plane,p.ll,4);
}
break;
}
case 5:{
System.out.println("请输入你要查询的最优路线种类:1.最低价格2.最短时间3.最少转乘次数");
int op=sc.nextInt();
System.out.println("请输入你的起点与终点:(ps请用空格隔开两地)");
sc.nextLine();
String str=sc.nextLine();
String[]cur=str.split(" ");
Dijkstra dijkstra=new Dijkstra();
if(op==1){
dijkstra.MinPrice(t,p,cur[0],cur[1],op,file_routes);
}else if(op==2){
dijkstra.MinTime(t,p,cur[0],cur[1],op,file_routes);
}else {
dijkstra.MinFreq(t,p,cur[0],cur[1],op,file_routes);
}
/* System.out.println(dijkstra.set.size());*/
break;
}
case 6:{
Dijkstra dijkstra=new Dijkstra();
System.out.println("请输入你的出发城市与目的地城市:(ps用空格分开)");
sc.nextLine();
String site=sc.nextLine();
String s[]=site.split(" ");
dijkstra.search(t,p,s[0],s[1],1,file_routes);
break;
}
case 0:
flag=false;
System.out.println("已成功退出系统,欢迎下次继续使用");
break;
default:
System.out.println("输入的选项有误,请重新输入0~5之间的选项");
break;
}
}
}
}
该程序实现了从给定的高铁和飞机数据中,通过Dijkstra算法找到起点到终点的最优路径。用户可以选择最低价格、最短时间和最少转乘次数作为优化目标,并将结果写入文件。同时,程序还提供了添加、删除、修改票务信息以及查询所有可能路径的功能。

1755

被折叠的 条评论
为什么被折叠?



