999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于Java的騎士游歷問題的預(yù)見算法

2008-12-31 00:00:00
網(wǎng)絡(luò)與信息 2008年9期

摘要:騎士游歷問題是經(jīng)典的NP問題。在騎士游歷問題常規(guī)算法的基礎(chǔ)上,提出一個(gè)新的算法——預(yù)見算法,用Java實(shí)現(xiàn)該算法,提高程序的運(yùn)行效率。

關(guān)鍵詞:騎士游歷;預(yù)見;Java算法

1 騎士游歷問題

在國際象棋的棋盤(8行×8列)上放置一個(gè)馬,按照“馬走日字”的規(guī)則,馬要遍歷棋盤,即到達(dá)棋盤上的每一格,并且每格只到達(dá)一次。若給定起始位置(x0,y0),編程探索出一條路徑,沿著這條路徑馬能遍歷棋盤上的所有單元格。

設(shè)當(dāng)前馬在棋盤的某個(gè)位置(x,y)上,按照規(guī)則,下一步有8個(gè)方向可走。

設(shè)二維數(shù)組mat表示棋盤,每個(gè)元素表示棋盤的一格,其值定義如下:

0表示馬未到達(dá)過

Mat[i,j]= -1表示棋盤邊界

自然數(shù) 表示馬到達(dá)該格的步數(shù)

2 常規(guī)的回溯算法

2.1 設(shè)計(jì)思想

馬從棋盤上的某一初始位置(x0,y0)開始,每次選擇一個(gè)方向k,向前走一格,直到走完64格為止。每走一格,設(shè)置數(shù)組中相應(yīng)格的元素值為馬走的步數(shù)。

如果選擇的方向k=0,表示可能的8種走向都試探不通,不通的原因是走向超出了棋盤范圍,或當(dāng)前位置已經(jīng)被馬訪問過。此時(shí)馬已無路可走,說明前幾步走得不對,應(yīng)該退回去重新?lián)Q一種走法,這種逐步試探的設(shè)計(jì)思想稱為回溯算法。

2.2 性能評價(jià)

回溯算法在每一格上朝一個(gè)方向盲目地進(jìn)行試探,遇到在某一格上所有方向都不能走通時(shí),才回到前一格上來試探另一個(gè)方向。當(dāng)每一格上的所有方向都試探過,不能走通時(shí),才做出“走不通”的結(jié)論。因此該算法在探索時(shí)帶有一定的盲目性和隨機(jī)性,運(yùn)行效率較低。

3 預(yù)見算法

3.1 設(shè)計(jì)思想

回溯算法的思路是可行的,但它的運(yùn)行效率較低,原因在于每步試探的隨機(jī)性和盲目性。如果能夠找到一種克服這種隨機(jī)性和盲目性的辦法,按照一定規(guī)律選擇前進(jìn)的方向,則將增加成功的可能性,運(yùn)行時(shí)間也大為縮短。本文提出的算法在這方面有所突破。

如果在每步選擇方向時(shí),不是任意選擇一個(gè)方向,而是經(jīng)過一定的測試和計(jì)算,“預(yù)見”每條路的“寬窄”,再選擇一條最“窄”的路先走,成功的可能性較大。理由是先走“困難的路”,光明大道留在后面。因?yàn)槊恳桓襁t早都要走到,與其把困難留在后面,不如先走“困難的路”,這樣路就會越走越寬,成功的機(jī)會就越大。這種方法稱為預(yù)見算法。

3.2 實(shí)現(xiàn)手段

為每個(gè)方向測定一個(gè)值——可通路數(shù),它表示該位置上還有多少條通路。在每一格上對8個(gè)方向都進(jìn)行試探,并分析比較,下一步應(yīng)該選擇可通路數(shù)值最小的方向走。

4 用Java實(shí)現(xiàn)算法

本例聲明Horse類,成員變量mat以二維數(shù)組表示棋盤,show表示是否顯示中間結(jié)果,內(nèi)部類Position中的成員變量x和y表示棋盤上一格的位置,x和y從1開始計(jì)數(shù)。

public class Horse

{private int mat[][]; //二維數(shù)組表示棋盤

boolean show; //是否顯示中間結(jié)果

class Position//內(nèi)部類

{int x,y;//表示棋盤上一格的位置

Position (int x,int y)

{this.x=x;

this.y=y;}

Position ()

{this(1,1);}

Position (Position p)

{this.x=p.x;

this.y=p.y;}

}

public Horse(int n,int x,int y,boolean show)//數(shù)組比實(shí)際棋盤多兩行兩列

{mat=new int[n+2*2][n+2*2]:

this.show=show;

inition(); //棋盤初始化

play(x,y);}

public Horse(int n,int x,int y)

{this(n,x,y,1);}

public Horse(int n)

{this(n,1,1);}

public Horse()

{this(8,1,1);}

public void inition()//棋盤初始化

{int i,j;

for(i=0;i<=1;i++)

{for(j=0;j

mat[i][j]=-1;

for(j=0;j

mat[mat.length-1-i][j]=-1;

for(j=0;j

mat[j][i]=-1;

for(j=o;j

mat[j][mat.length-1-i]=-1;}

}

public int get(Position p) //獲得p格的值

{return mat[p.x+1][p.y+1];}

public void set(Position p,int i) //設(shè)置p格的值為i

{mat[p.x+1][p.y+1]=i];}

public void play(int x,int y) //從(x,y)格開始遍歷

{int n=mat.length-4;

Position current=new Position(x,y);

int count=1;

int i,j,k=1;

while(count<=n*nk!=0)

{set(current,count);

if(this.show)

System.out.print(”第”+count+”步 ”);

k=select(current);//試探,選擇一個(gè)方向

if(k==0count

System.out.println(”第”+count+”步無路可通!”);

else

{count++;

corrent=goaStep(current,k);}

}

}

public boolean isValid(Position p)//判斷p是否在棋盤內(nèi)且未被訪問過

{int n=mat.length-4;

if(p!=1p.x>=1p.x<=np.y>=1p.y<=nget(p)==0)

return true;}

else

return 1;}

public Position goaStep(Position p,int k) //返回p位置按k方向的下一位置

{int x=p.x;

int y=p.y;

switch(k)

{case 1:x-=2;y++;break;

case 2:x--;y+=2;break;

case 3:x++;y+=2;break;

case 4:x+=2;y++;break;

case 5:x+=2;y--;break;

case 6:x++;y-=2;break;

case 7:x--;y-=2;break;

case 8:x-=2;y--;break;}

return new Position(x,y);

}

public int select(Position p)//選擇p位置到達(dá)下一位置next1應(yīng)走的方向k

//試探next1的8個(gè)方向位置next2的可通路數(shù)road,road的最小值為minroad

{int i=0,j=0,k=0,road=0,minroad=8;

Position next1=1,next2=1;

if(this.show)

{System.out.println(“當(dāng)前位置:(”+p.x+”,”+p.y+”)”);

this.output();

System.out.println(”方向下一位置可通方向可通路數(shù)”);}

for(i=1;i<8;i++)

{road=0;

next1=goaStep(p,i);

if(isValid(next1))

{if(this.show)

system.out.print(“ “+i+”\(“+next1.x+”,”+next1.y+”)\”);

for(j=1;j<=8;j++)

{next2=goaStep(next1,j);

if(isValid(next2))

{road++;

if(this.show)

System.out.print(j+”,”);}

}

if(road

{minroad=road;

k=i;}

if(this.show)

System.out.println(“\”+road);}

}

if(this.show)

System.out.println(“選定下一個(gè)方向 k=”+k+”\\r\”);

return k;}

public void output()

{int i,j,n=mat.length;

for(i=0;i

{for(j=0;j

{if(mat[i][j]mat[i][j]<10)

System.out.print(””+mat[i][j]);

else

System.out.print(“ “+mat[i][j]);}

System.out.println();}

System.out.println();}

public static void main(String args[])

{ Horse h1=new Horse(8,1,1,1);

h1.output();}

}

5 結(jié)論

該算法在Java環(huán)境下通過了測試,證明了算法的正確性。

預(yù)見算法雖然在每一格上選擇下一步的方向需要花費(fèi)一定的時(shí)間,但它針對性強(qiáng),減少了許多盲目的試探,總的選擇次數(shù)少,從而縮短了運(yùn)行時(shí)間。

參考文獻(xiàn)

[1]張居敏,石禮娟,龍翔. Java程序設(shè)計(jì)經(jīng)典教程(融合上機(jī)操作實(shí)例) [M].北京: 電子工業(yè)出版社,2008.

[2]Bruce Eckel.Java編程思想(第4版) [M].北京:機(jī)械工業(yè)出版社,2007.

[3]葉核亞 . 數(shù)據(jù)結(jié)構(gòu)(Java版)[M].北京:電子工業(yè)出版社,2004.

[4] 黃曉東 . JAVA課程設(shè)計(jì)案例精編[M].北京:中國水利水電出版社,2004.

主站蜘蛛池模板: 十八禁美女裸体网站| 欧美在线一二区| 狠狠亚洲五月天| 久久国产拍爱| 国内熟女少妇一线天| 黄色一及毛片| 亚洲日韩Av中文字幕无码| 国产成人乱无码视频| 精品国产一区二区三区在线观看| 欧美一道本| 中文无码精品A∨在线观看不卡| 午夜福利亚洲精品| 国产成人乱无码视频| 中文字幕永久视频| 亚洲综合日韩精品| 免费观看亚洲人成网站| 亚洲成人动漫在线观看| 国产精品美女网站| 欧美一级99在线观看国产| 少妇精品网站| 女同国产精品一区二区| 欧美日韩免费| 成人在线亚洲| 久久精品亚洲热综合一区二区| 亚洲第一视频免费在线| 国产内射一区亚洲| 91久久精品日日躁夜夜躁欧美| 欧美日韩国产高清一区二区三区| 日韩黄色在线| 国产精品浪潮Av| 久久国产精品77777| 精品中文字幕一区在线| 欧美在线网| 青草国产在线视频| 超清无码一区二区三区| 成年人久久黄色网站| 日韩无码视频专区| 蜜臀av性久久久久蜜臀aⅴ麻豆 | 国产91全国探花系列在线播放 | AV熟女乱| 欧美国产成人在线| 男女性午夜福利网站| 伦精品一区二区三区视频| 久久人搡人人玩人妻精品| 激情无码视频在线看| 欧日韩在线不卡视频| 亚洲欧美日韩动漫| 国产大片黄在线观看| 国产91透明丝袜美腿在线| 日韩在线视频网| 久久香蕉国产线| 亚洲欧美日韩动漫| 久久久久久尹人网香蕉 | 久久五月天综合| 国产真实乱了在线播放| 丰满少妇αⅴ无码区| 国产乱子伦视频三区| 国产精品无码AⅤ在线观看播放| 日韩福利在线观看| 免费 国产 无码久久久| 国产三级国产精品国产普男人 | 亚洲成人福利网站| 无码视频国产精品一区二区| 在线欧美日韩国产| 亚洲黄色激情网站| 久久人人妻人人爽人人卡片av| 99re热精品视频国产免费| 尤物特级无码毛片免费| 亚洲熟女偷拍| 国产免费网址| 爆乳熟妇一区二区三区| 99久久99视频| 亚洲乱伦视频| 精品黑人一区二区三区| 乱人伦中文视频在线观看免费| 999精品色在线观看| 欧美成人一级| 久久久久无码精品| 国产青榴视频在线观看网站| 无码一区中文字幕| 亚洲欧洲日韩综合| 国产无吗一区二区三区在线欢|