A*路徑搜尋算法
- 1、問題
- 2、算法标簽
- 3、實作代碼
-
-
-
-
- 1>接口類
- 2>接口實作類
-
-
-
- 4、代碼運作截圖
1、問題
用A*搜尋算法實作路徑搜尋,并将路徑搜尋的最終結果儲存至檔案中
2、算法标簽
1、A*搜尋
3、實作代碼
1>接口類
package ai;
import java.io.File;
import java.util.List;
class Status{
public char mp[][];
public int tempx,tempy;
public int fromx,fromy;
public int tox,toy;
public Status parent;
public int distance;
Status(){
mp=new char[30][70];
}
}
public interface A_start {
public void getInitStatus(); // 擷取初始狀态
public void showStatus(char mp[][]); //輸出目前狀态内部表示
public int getFValue(Status statu); //擷取目前節點啟發函數值
public boolean isExist(Status now); //是否狀态s與目前狀态相同
public void saveAnswer(char mp1[][],char mp2[][],int flag);
}
2>接口實作類
package ai;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class PathSearch implements A_start{
public List<Status> used = new ArrayList<Status>();
public List<Status> unused = new ArrayList<Status>();
public Status start = new Status();
public void copy(Status newone,Status oldone) {
for(int i=0;i<30;i++) {
for(int j=0;j<70;j++) {
newone.mp[i][j]=oldone.mp[i][j];
}
}
newone.tempx=oldone.tempx;
newone.tempy=oldone.tempy;
newone.fromx=oldone.fromx;
newone.fromy=oldone.fromy;
newone.tox=oldone.tox;
newone.toy=oldone.toy;
}
public void getInitStatus() {
Random random = new Random();
for(int i=0;i<30;i++) {
for(int j=0;j<70;j++) {
this.start.mp[i][j]='=';
}
}
Scanner input=new Scanner(System.in);
System.out.print("請自定義障礙數(0-29998):");
int obstacles=input.nextInt();
if(0>obstacles||obstacles>29998) {
System.out.println("錯誤輸入,自定義為200!");
obstacles=200;
}
for(int t=0;t<obstacles;t++) {
int rx = random.nextInt(30);
int ry = random.nextInt(70);
this.start.mp[rx][ry]='O';
}
this.start.fromx = random.nextInt(30);
this.start.tempx = this.start.fromx;
this.start.fromy = random.nextInt(70);
this.start.tempy = this.start.fromy;
this.start.mp[this.start.fromx][this.start.fromy]='F';
this.start.tox = random.nextInt(30);
this.start.toy = random.nextInt(70);
this.start.mp[this.start.tox][this.start.toy]='T';
this.start.distance=getFValue(this.start);
this.start.parent=this.start;
}
public int getFValue(Status statu) {
return Math.abs(statu.tempx-statu.tox)+Math.abs(statu.tempy-statu.toy);
}
public void showStatus(char mp[][]) {
System.out.println("===============================目前狀态===============================");
System.out.println(" X:障礙,F:起點,T:終點,V:路徑,O:道路");
for(int i=0;i<30;i++) {
for(int j=0;j<70;j++) {
System.out.print(mp[i][j]);
}
System.out.println("");
}
}
public boolean isExist(Status now) {
for(int i=0;i<this.used.size();i++) {
Status temp=this.used.get(i);
int j=0;
for(;j<2100;j++) {
int r=j/70;
int c=j%70;
if(now.mp[r][c]!=temp.mp[r][c]) {
break;
}
}
if(j==2100&&now.tempx==temp.tempx&&now.tempy==temp.tempy) {
return true;
}
}
for(int i=0;i<this.unused.size();i++) {
Status temp=this.unused.get(i);
int j=0;
for(;j<2100;j++) {
int r=j/70;
int c=j%70;
if(now.mp[r][c]!=temp.mp[r][c]) {
break;
}
}
if(j==2100&&now.tempx==temp.tempx&&now.tempy==temp.tempy) {
return true;
}
}
return false;
}
public void saveAnswer(char mp1[][],char mp2[][],int flag) {
try {
String name="E:/Astar路徑搜尋問題解決方案.txt";
BufferedWriter out = new BufferedWriter(new FileWriter(name));
out.write("路徑搜尋問題:");
out.newLine();
out.write("X:障礙,F:起點,T:終點,V:路徑,O:道路");
out.newLine();
for(int i=0;i<30;i++) {
String q="";
for(int j=0;j<70;j++) {
q=q+mp1[i][j];
}
out.write(q);
out.newLine();
}
out.write("解決方案:");
out.newLine();
if(flag==0) {
out.write("此題在移動最大99999999步數内無解");
}
else {
for(int i=0;i<30;i++) {
String q="";
for(int j=0;j<70;j++) {
q=q+mp2[i][j];
}
out.write(q);
out.newLine();
}
}
out.close();
System.out.println("問題解決方案寫入成功,檔案儲存在E盤根目錄");
} catch (IOException e) {
System.out.println("問題解決方案寫入或儲存失敗");
}
}
public static void main(String[] args) {
System.out.println("A* 路徑搜尋算法實作 ————made by 張玉想(計科一班 | 202820240106)");
PathSearch ps = new PathSearch();
ps.getInitStatus();
ps.unused.add(ps.start);
int step=0;
int flag=0;
while(step<99999999&&ps.unused.size()>0) {
Status temp=ps.unused.get(0);
ps.showStatus(temp.mp);
ps.unused.remove(0);
ps.used.add(temp);
if(temp.tempx-1>=0) {
Status news=new Status();
ps.copy(news,temp);
if(news.mp[temp.tempx-1][temp.tempy]=='=') {
news.mp[temp.tempx-1][temp.tempy]='V';
news.tempx=temp.tempx-1;
news.distance=ps.getFValue(news);
ps.showStatus(news.mp);
if(!ps.isExist(news)) {
news.parent=temp;
ps.unused.add(news);
step++;
}
}
else if(news.mp[news.tempx-1][news.tempy]=='T') {
news.tempx=news.tempx-1;
ps.showStatus(news.mp);
ps.unused.clear();
flag=1;
ps.saveAnswer(temp.mp,news.mp,flag);
break;
}
}
if(temp.tempx+1<30) {
Status news=new Status();
ps.copy(news,temp);
if(news.mp[news.tempx+1][news.tempy]=='=') {
news.mp[news.tempx+1][news.tempy]='V';
news.tempx=news.tempx+1;
news.distance=ps.getFValue(news);
if(!ps.isExist(news)) {
news.parent=temp;
ps.unused.add(news);
step++;
}
}
else if(news.mp[news.tempx+1][news.tempy]=='T') {
news.tempx=news.tempx+1;
ps.showStatus(news.mp);
ps.unused.clear();
flag=1;
ps.saveAnswer(temp.mp,news.mp,flag);
break;
}
}
if(temp.tempy-1>=0) {
Status news=new Status();
ps.copy(news,temp);
if(news.mp[news.tempx][news.tempy-1]=='=') {
news.mp[news.tempx][news.tempy-1]='V';
news.tempy=news.tempy-1;
news.distance=ps.getFValue(news);
if(!ps.isExist(news)) {
news.parent=temp;
ps.unused.add(news);
step++;
}
}
else if(news.mp[news.tempx][news.tempy-1]=='T') {
news.tempy=news.tempy-1;
ps.showStatus(news.mp);
ps.unused.clear();
flag=1;
ps.saveAnswer(temp.mp,news.mp,flag);
break;
}
}
if(temp.tempy+1<70) {
Status news=new Status();
ps.copy(news,temp);
if(news.mp[news.tempx][news.tempy+1]=='=') {
news.mp[news.tempx][news.tempy+1]='V';
news.tempy=news.tempy+1;
news.distance=ps.getFValue(news);
if(!ps.isExist(news)) {
news.parent=temp;
ps.unused.add(news);
step++;
}
}
else if(news.mp[news.tempx][news.tempy+1]=='T') {
news.tempy=news.tempy+1;
ps.showStatus(news.mp);
ps.unused.clear();
flag=1;
ps.saveAnswer(temp.mp,news.mp,flag);
break;
}
}
Collections.sort(ps.unused, new Comparator<Status>() {
public int compare(Status u1, Status u2) {
int diff = u1.distance-u2.distance;
if (diff > 0) {
return 1;
}
else if (diff < 0) {
return -1;
}
return 0;
}
});
}
System.out.println(" --------------------------------");
System.out.println(" ---- A*模拟搜尋結束 ----");
System.out.println(" ---- made by 張玉想 ----");
System.out.println(" --------------------------------");
if(flag==0) {
ps.saveAnswer(ps.used.get(0).mp,ps.used.get(0).mp,flag);
}
}
}