一个房间里,天花板上挂有一串香蕉,有一只猴子可在房间里任意活动(到处走动,推移箱子,攀登箱子等)。设房间里还有一只可被猴子移动的箱子,且猴子登上箱子时才能摘到香蕉,问猴子在某一状态下(设猴子位置为A,香蕉位置在B,箱子位置为C),如何行动可摘取到香蕉
2.1 猴子摘香蕉问题PEAS
性能 |
环境 |
执行器 |
感知器 |
猴子站在箱子上 |
香蕉 |
Move |
Site |
猴子摘到香蕉 |
箱子 |
Climb |
Hold |
位置 |
Push |
On |
|
Grasp |
Hang |
||
Jump |
2.2定义谓词
Site(x,w):物体x的位置是w
Hold(z):z手中拿着香蕉
On(z):z站在了箱子上
Hang(y,w):y悬挂在位置w
2.3定义变元定义域:
x∈{猴子,箱子}
y∈{香蕉}
z∈{猴子}
w∈{a,b,c}
2.4定义操作:
Move(u,v):猴子从u走到v
Climb():猴子爬上了箱子
Push(u,v):猴子推着箱子从u走到v
Grasp():猴子拿到了香蕉
Jump():猴子从箱子上跳下来
2.5定义初始状态与目标状态
S0=Site(Monkey,a)
^Hang(Banana,b)
^Site(Box,c)
^¬On(Monkey)
^¬Holds(Monkey)
Sg=Site(Monkey,b)
^¬Hang(Banana,b)
^Site(Box,b)
^¬On(Monkey)
^Holds(Monkey)
2.6各操作条件与动作
Move(u,v)
条件:¬On(Monkey),Site(Monkey,u)
动作:删除表:Site(Monkey,u) 添加表Site(Monkey,v)
Push(v,u)
条件:¬On(Monkey),Site(Monkey,v),Site(Box,v)
动作:删除表:Site(Monkey,v);Site(Box,v)
添加表:Site(Monkey,w);Site(Box,w)
Climb()
条件:¬On(Monkey),Site(Monkey,v),Site(Box,v)
动作:删除表:¬On(Monkey)
添加表:On(Monkey)
Grasp()
条件:On(Monkey),Site(Box,b),Hang(Banana,b)
动作:删除表: ¬Holds(Monkey),Hang(Banana,b)
添加表:Holds(Monkey),¬Hang(Banana,b)
Jump()
条件:Hold(Monkey),On(Monkey)
动作:删除表:On(monkey)
添加表:¬On(monkey)
2.7求解过程
S0=Site(Monkey,a)
^Hang(Banana,b)
^Site(Box,c)
^¬On(Monkey)
^¬Holds(Monkey)
——执行Move(u,v)
S1=Site(Monkey,c)
^Hang(Banana,b)
^Site(Box,c)
^¬On(Monkey)
^¬Holds(Monkey)
——执行Push(v,w)
S2=Site(Monkey,b)
^Hang(Banana,b)
^Site(Box,b)
^¬On(Monkey)
^¬Holds(Monkey)
——执行Climb()
S3=Site(Monkey,b)
^Hang(Banana,b)
^Site(Box,b)
^On(Monkey)
^¬Holds(Monkey)
——执行Grasp()
S4=Site(Monkey,b)
^¬Hang(Banana,b)
^Site(Box,b)
^On(Monkey)
^Holds(Monkey)
——执行Jump()
Sg=Site(Monkey,b)
^¬Hang(Banana,b)
^Site(Box,b)
^¬On(Monkey)
^Holds(Monkey)
3.1 实验代码
Banana类
package monkey;
public class Banana {
private final Position banana_position=new Position();
private boolean Hang=true;
public Position getBanana_position() {
return banana_position;
}
public void setBanana_position(int x,int y){
banana_position.setPosition(x,y);
}
public boolean isHang() {
return Hang;
}
public void Grasp(){
Hang=false;
}
}
Box类
package monkey;
public class Box {
private final Position box_position=new Position();
private boolean OnBox=false;
public void setBox_position(int x,int y){
box_position.setPosition(x,y);
}
public void Push(Monkey monkey,int x,int y){
monkey.Move(x,y);
System.out.println("the box is being pushed from("+box_position.getX()+','
+box_position.getY()+")to("+x+','+y+")");
box_position.setPosition(x,y);
}
public void Jump(){
if(OnBox){
OnBox=false;
System.out.println("the monkey has jumped off the box");
}
else{
System.out.println("the monkey is standing under the box");
}
}
public void Climb(){
if(!OnBox){
OnBox=true;
System.out.println("the monkey has climbed on the box");
}
else{
System.out.println("the monkey is standing on the box");
}
}
public Position getBox_position() {
return box_position;
}
public boolean isOnBox() {
return OnBox;
}
}
Monkey类
package monkey;
public class Monkey {
private final Position monkey_position=new Position();
public void setMonkey_position(int x,int y) {
monkey_position.setPosition(x,y);
}
public void Move (int x,int y){
System.out.println("the monkey is going from("+monkey_position.getX()+','
+monkey_position.getY()+")to("+x+','+y+")");
monkey_position.setPosition(x,y);
}
public Position getMonkey_position(){
return monkey_position;
}
}
Position类
package monkey;
import java.util.Objects;
public class Position {
private int x;
private int y;
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setPosition(int x,int y){
this.x=x;
this.y=y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Position position = (Position) o;
return x == position.x && y == position.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
}
Main类
package monkey;
import java.util.Scanner;
import static java.lang.System.exit;
public class main {
public static void main(String[] args) {
int x,y;
Monkey monkey = new Monkey();
Banana banana = new Banana();
Box box = new Box();
Scanner sc =new Scanner(System.in);
System.out.println("Please Enter the position of the banana(x,y):");
x=sc.nextInt();
y=sc.nextInt();
banana.setBanana_position(x,y);
System.out.println("the banana is hanging at ("+banana.getBanana_position().getX()+','
+banana.getBanana_position().getY()+')');
System.out.println("Please Enter the position of the box(x,y):");
x=sc.nextInt();
y=sc.nextInt();
box.setBox_position(x,y);
System.out.println("the box is at ("+box.getBox_position().getX()+','
+box.getBox_position().getY()+')');
System.out.println("Please Enter the position of the monkey(x,y):");
x=sc.nextInt();
y=sc.nextInt();
monkey.setMonkey_position(x,y);
System.out.println("the monkey is at ("+monkey.getMonkey_position().getX()+','
+monkey.getMonkey_position().getY()+')');
if(!monkey.getMonkey_position().equals(box.getBox_position())){
monkey.Move(box.getBox_position().getX(),box.getBox_position().getY());
}
if(!monkey.getMonkey_position().equals(banana.getBanana_position())){
box.Push(monkey,banana.getBanana_position().getX(),banana.getBanana_position().getY());
}
box.Climb();
banana.Grasp();
if(!banana.isHang())
System.out.println("the monkey has grasped the banana.");
exit(0);
}
}
环境可理解为java的对象类,动作器可理解为方法,感受器可理解为参数,我们要尽可能防止表示泄露,因此设置参数用private、setter、getter的组合来传递以及更改参数,而且要时刻记得checkRep,此外猴子摘香蕉问题,猴子会主动搬箱子,抓取香蕉,以及爬上或跳下箱子。那我们在构造方法时应该在哪一个类中构建呢?我们主观印象会觉得猴子是主语,他做出了这些动作,应该将方法都添加到猴子类中,但事实上,我们会发现将方法添加到宾语,也就是箱子、香蕉这些类会更加方便,这是因为虽然猴子爬上或搬箱子,别的动物甚至某种类也可以完成这些动作,可以被搬,可以被攀爬或跳下是箱子的属性,因此我们在构造方法时要先判断好对谁创建一个方法,入参、返回值,规约,检查入口。这些对编写java程序至关重要。
参考文献
注:报告中图的下方要有图题(如图1. XXXX),表格需要用三线表,表头需列在表的上方(如表1. XXXX)。图表居中排列。