分享
 
 
 

根据启发函数解决八数码问题

王朝java/jsp·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

启发函数suggestFunc计算所有棋子到目标位置的距离,又称为曼哈顿距离。

import java.applet.Applet;

import java.awt.*;

import java.awt.Graphics;

import java.util.Vector;

public class EightNumber extends Applet implements Runnable

{

private class State

{

int[] states = new int[9];

int size;

int steps;

public State(int [] s)

{

int i;

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

states[i] = s[i];

}

public boolean equals(State st)

{

int[] s=st.getStates();

int i;

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

if(s[i] != states[i])

return false;

return true;

}

public int judgeMove(State st)

{

int[] s=st.getStates();

int i;

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

{

if(s[i] != states[i] && s[i]!=0)

return i;

}

return -1;

}

public int[] getStates()

{

return states;

}

public int expandSize()

{

if(states[4] == 0)

size = 4;

else if(states[0]==0 || states[2]==0 || states[6]==0 || states[8]==0)

size = 2;

else

size = 3;

return size;

}

public State[] expandState()

{

State[] st;

int [] ex=new int[9];

int i,j,k;

int m=0,n=0;

int a=0,b=0;

st = new State[size];

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

{

for(j=0;j<3;j++)

{

k = i*3+j;

ex[k] = states[k];

if(states[k] == 0)

{

m = i;

n = j;

}

}

}

i = 0;

a = m*3+n;

if(m-1>=0)

{

b = (m-1)*3+n;

ex[a] = ex[b];

ex[b] = 0;

st[i] = new State(ex);

ex[b] = ex[a];

ex[a] = 0;

i++;

}

if(m+1<=2)

{

b = (m+1)*3+n;

ex[a] = ex[b];

ex[b] = 0;

st[i] = new State(ex);

ex[b] = ex[a];

ex[a] = 0;

i++;

}

if(n-1>=0)

{

b = m*3+(n-1);

ex[a] = ex[b];

ex[b] = 0;

st[i] = new State(ex);

ex[b] = ex[a];

ex[a] = 0;

i++;

}

if(n+1<=2)

{

b = m*3+(n+1);

ex[a] = ex[b];

ex[b] = 0;

st[i] = new State(ex);

ex[b] = ex[a];

ex[a] = 0;

i++;

}

return st;

}

}

Image[] stateImg = new Image[10];

Image[] moveImg = new Image[10];

Image stepsImg;

Vector vecClose = new Vector();//记录下已经扩展的节点

Vector vecOpen = new Vector();//记录下未扩展的节点

int[] first = {7,2,4,5,0,6,8,3,1};

int[] aim = {0,1,2,3,4,5,6,7,8};

State nowState = null;

State aimState = new State(aim);

int stepX;

int stepY;

int startX;

int startY;

int steps;

int move;

boolean start;

Thread moveTh = null;

public void init()

{

int i;

Integer tmp;

String fileName;

State st = new State(first);

st.steps = 0;

resize(200,300);

startX = 16;

startY = 19;

stepX = 55;

stepY = 55;

steps = 0;

start = false;

move = -1;

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

{

tmp = new Integer(i);

fileName = "img/";

fileName = fileName + tmp.toString()+"_1.gif";

stateImg[i] = getImage(getCodeBase(),fileName);

waitForImage(stateImg[i]);

fileName = "img/";

fileName = fileName + tmp.toString() + "_2.gif";

moveImg[i] = getImage(getCodeBase(),fileName);

waitForImage(stepsImg);

}

vecOpen.add(st);

fileName = "img/steps.gif";

stepsImg = getImage(getCodeBase(),"img/steps.gif");

waitForImage(stepsImg);

}

public void waitForImage(Image i)

{

MediaTracker tracker = new MediaTracker(this);

try

{

tracker.addImage(i,0);

tracker.waitForID(0);

}

catch(InterruptedException e) {System.err.println("Wait interrupted.");}

}

public void paint(Graphics g)

{

int i,j,k;

int[] state;

Integer tmp;

if(start == false)

return ;

state = nowState.getStates();

g.drawImage(stepsImg,startX+20,startY,this);

tmp = new Integer(steps);

g.drawString(tmp.toString(),startX+80,startY+20);

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

{

for(j=0;j<3;j++)

{

k = i*3+j;

if(move == k)

{

putNumber(g,state[k],i,j,false);

}

else

{

putNumber(g,state[k],i,j,true);

}

}

}

}

public void update(Graphics g)

{

paint(g);

}

private void putNumber(Graphics g,int number,int i,int j,boolean isState )

{

int x,y;

x = startX + j*stepX;

y = startY + i*stepY + stepY;

if(isState)

{

g.drawImage(stateImg[number],x,y,this);

}

else

{

g.drawImage(moveImg[number],x,y,this);

}

}

//启发函数

private int suggestFunc(State st)

{

int i,j,m,n;

int a=0,b=0;

int result=0;

int[] state;

state = st.getStates();

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

{

for(j=0;j<3;j++)

{

a = i*3+j;

if(state[a]==0)

continue;

for(m=0;m<3;m++)

{

for(n=0;n<3;n++)

{

b = m*3+n;

if(state[a] == aim[b])

{

result += (Math.abs(m-i)+Math.abs(n-j));

break;

}

}

if(state[a] == aim[b])

break;

}

}

}

return result;

}

public void start()

{

if(moveTh == null)

{

moveTh = new Thread(this);

moveTh.start();

}

}

public void stop()

{

if(moveTh != null)

{

moveTh = null;

}

}

public void run()

{

searchPath();

}

//寻找路径

private boolean searchPath()

{

int openSize;

State st;

boolean result=false;

start = true;

while(!vecOpen.isEmpty())

{

openSize = vecOpen.size();;

st = (State)vecOpen.elementAt(openSize-1);

if(nowState != null)

{

move = nowState.judgeMove(st);

}

nowState = st;

vecOpen.remove(openSize-1);

vecClose.add(nowState);

if(expandNowState() == 0)

{

result = true;

}

steps++;

repaint();

if(result == true)

break;

try

{

Thread.sleep(1000);

}

catch(InterruptedException e){}

}

return result;

}

private boolean haveContained(State st)

{

int size;

int i;

State tmp;

size = vecClose.size();

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

{

tmp = (State)vecClose.elementAt(i);

if(tmp.equals(st))

return true;

}

return false;

}

//扩展当前节点,1表示扩展成功,0表示找到目标节点,-1表示当前节点不可扩展

private int expandNowState()

{

int[] value = {255,255,255,255};

int size;

int i,j;

int have = -1;

State st[];

State tmpState;

int tmp;

size = nowState.expandSize();

st = nowState.expandState();

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

{

if(!haveContained(st[i]))

{

value[i] = suggestFunc(st[i]);

if(value[i] == 0)

{

move = nowState.judgeMove(st[i]);

nowState = st[i];

return 0;

}

else

have = 1;

}

}

if(have == 1)

{

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

{

for(j=i+1;j<size;j++)

{

if(value[j]>value[i])

{

tmp = value[j];

tmpState = st[j];

value[j] = value[i];

st[j] = st[i];

value[i] = tmp;

st[i] = tmpState;

}

}

}

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

{

if(value[i]!=255)

{

vecOpen.add(st[i]);

}

}

}

return have;

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有