实训总结报告

实训总结报告

阶段 1 :项目启动

学习使用 vi, JAVA, Ant, Junit ,配置 SonarQube ,并熟悉 GridWorld 的使用。

详见GridWorld 阶段一学习报告

vi/vim 编辑器

vi 编辑器是所有 Unix 及 Linux 系统下标准的编辑器, vim 编辑器是 vi 的升级版,增加了一些功能,同时完全兼容 vi 命令。

vi/vim 编辑器有三种模式:

(1) 一般模式

打开 vi/vim 编辑器后的默认模式。

在一般模式中可以进行删除、复制、粘贴,但是无法编辑文件内容。

(2) 编辑模式

在编辑模式中可以编辑文件内容。

(3) 命令行模式

在命令行模式下可以进行查找数据、读取、保存、大量替换字符、离开编辑器、显示行号等操作。

JAVA 语言

java是一门面向对象编程语言,吸收了C/C++的优点,摒弃了C/C++复杂的指针等内容,也不需要用户手动释放内存空间。java本身还具备了很强的可移植性,通过将源代码编译成二进制字节码,然后通过不同平台的java虚拟机来解释执行字节码,从而实行了“一次编译,到处执行”的跨平台特性。

Java的应用领域非常广泛。可以做应用系统、互联网网站、以及移动端的安卓等。

Java 编写计算器小程序

实现加减乘除运算,调用 swing 库实现 GUI ,并在 Eclipse 集成环境下编译运行。

项目结构如下:

运行结果如下:

Ant 环境

Ant 是 JAVA 的生成工具,是 Apache 的核心项目。

Ant 类似于与 Unix 中的 Make 工具,都是用来编译、生成。

可以在 Eclipse 中集成 Ant 环境。

Junit

Junit 是一个 Java 单元测试的工具,可以用来检验程序中的方法是否符合预期。

可以在 Eclipse 中简单地导入 Junit。

Junit 的一个测试类形如:

import org.junit.Test;

public class Test {
    @Test
    public void test1() {
        assertEquals(expected_result, new test_class().test_method(args));
    }
}

SonarQube

Sonar 是一个用于代码质量管理的开源平台,用于管理源代码的质量,可以从七个维度检测代码质量。

GridWorld 的使用

编译运行第一个 GridWorld 应用 BugRunner。

命令行进入到项目跟文件夹下 $Gridworld_Project/GridWorldCode/projects/firstProject,通过以下指令引用预先打包好的 gridworld.jar 包,编译运行 BugRunner。

## 编译:
javac -classpath .:./../../gridworld.jar BugRunner.java
## 执行:
java  -classpath .:./../../gridworld.jar BugRunner

运行结果如下:

在这里插入图片描述

阶段 2 :基本任务

学习和使用 GridWorld 中的重要类。

Part 2:Bug Variations

Bug 类的方法有:

// tests whether the bug can move forward into a location that is empty or contains aflower
public boolean canMove()

// moves the bug forward, putting a flower into the location it previously occupied
public void move()

// turns the bug 45 degrees to the right without changing its location
public void turn()
These methods are used in the bug’s act method.

public void act()
{
    if (canMove())
        move();
    else
        turn();
}

拓展 Bug 类:

BoxBug

最大行动轨迹为边长为 sideLength 的正方形的 Bug。

SpiralBug

每次旋转 90 度后 sideLength++ 的 Bug。

ZBug

行走轨迹为各边长 sideLength 的 Z 字的 Bug。

DancingBug

一个数组记录 Bug 的舞步,数组的元素的值表示 Bug 在本次移动前要顺时针旋转 45 度多少次。

Part 3:GridWorld Classes and Interfaces

Location 类

Location 类帮助定位一个 actor 在 grid 中的坐标,并且定义了每个 actor 的方向。

Location 类宏定义了指南针方向以及角度。

	/**
     * The turn angle for turning 90 degrees to the left.
     */
    public static final int LEFT = -90;
    /**
     * The turn angle for turning 90 degrees to the right.
     */
    public static final int RIGHT = 90;
    ...
    
    /**
     * The compass direction for north.
     */
    public static final int NORTH = 0;
    /**
     * The compass direction for northeast.
     */
    public static final int NORTHEAST = 45;
    ...

Location 类有以下方法。

	/**
     * Gets the row coordinate.
     * @return the row of this location
     */
    public int getRow();
   
    /**
     * Gets the column coordinate.
     * @return the column of this location
     */
    public int getCol();
   
    /**
     * Gets the adjacent location in any one of the eight compass directions.
     * @param direction the direction in which to find a neighbor location
     * @return the adjacent location in the direction that is closest to
     * <tt>direction</tt>
     */
    public Location getAdjacentLocation(int direction);

    /**
     * Returns the direction from this location toward another location. The
     * direction is rounded to the nearest compass direction.
     * @param target a location that is different from this location
     * @return the closest compass direction from this location toward
     * <code>target</code>
     */
    public int getDirectionToward(Location target);

    /**
     * Indicates whether some other <code>Location</code> object is "equal to"
     * this one.
     * @param other the other location to test
     * @return <code>true</code> if <code>other</code> is a
     * <code>Location</code> with the same row and column as this location;
     * <code>false</code> otherwise
     */
    public boolean equals(Object other);

    /**
     * Generates a hash code.
     * @return a hash code for this location
     */
    public int hashCode();

    /**
     * Compares this location to <code>other</code> for ordering. Returns a
     * negative integer, zero, or a positive integer as this location is less
     * than, equal to, or greater than <code>other</code>. Locations are
     * ordered in row-major order. <br />
     * (Precondition: <code>other</code> is a <code>Location</code> object.)
     * @param other the other location to test
     * @return a negative integer if this location is less than
     * <code>other</code>, zero if the two locations are equal, or a positive
     * integer if this location is greater than <code>other</code>
     */
    public int compareTo(Object other);
Grid 接口

Grid 接口定义了所有包含对象的 grid 的方法,BoundedGrid 和 UnboundedGrid 实现了这个接口。

Grid 接口的方法有:

	/**
     * Returns the number of rows in this grid.
     * @return the number of rows, or -1 if this grid is unbounded
     */
    int getNumRows();

    /**
     * Returns the number of columns in this grid.
     * @return the number of columns, or -1 if this grid is unbounded
     */
    int getNumCols();

    /**
     * Checks whether a location is valid in this grid. <br />
     * Precondition: <code>loc</code> is not <code>null</code>
     * @param loc the location to check
     * @return <code>true</code> if <code>loc</code> is valid in this grid,
     * <code>false</code> otherwise
     */
    boolean isValid(Location loc);

    /**
     * Puts an object at a given location in this grid. <br />
     * Precondition: (1) <code>loc</code> is valid in this grid (2)
     * <code>obj</code> is not <code>null</code>
     * @param loc the location at which to put the object
     * @param obj the new object to be added
     * @return the object previously at <code>loc</code> (or <code>null</code>
     * if the location was previously unoccupied)
     */
    E put(Location loc, E obj);

    /**
     * Removes the object at a given location from this grid. <br />
     * Precondition: <code>loc</code> is valid in this grid
     * @param loc the location of the object that is to be removed
     * @return the object that was removed (or <code>null<code> if the location
     *  is unoccupied)
     */
    E remove(Location loc);

    /**
     * Returns the object at a given location in this grid. <br />
     * Precondition: <code>loc</code> is valid in this grid
     * @param loc a location in this grid
     * @return the object at location <code>loc</code> (or <code>null<code> 
     *  if the location is unoccupied)
     */
    E get(Location loc);

    /**
     * Gets the locations in this grid that contain objects.
     * @return an array list of all occupied locations in this grid
     */
    ArrayList<Location> getOccupiedLocations();

    /**
     * Gets the valid locations adjacent to a given location in all eight
     * compass directions (north, northeast, east, southeast, south, southwest,
     * west, and northwest). <br />
     * Precondition: <code>loc</code> is valid in this grid
     * @param loc a location in this grid
     * @return an array list of the valid locations adjacent to <code>loc</code>
     * in this grid
     */
    ArrayList<Location> getValidAdjacentLocations(Location loc);

    /**
     * Gets the valid empty locations adjacent to a given location in all eight
     * compass directions (north, northeast, east, southeast, south, southwest,
     * west, and northwest). <br />
     * Precondition: <code>loc</code> is valid in this grid
     * @param loc a location in this grid
     * @return an array list of the valid empty locations adjacent to
     * <code>loc</code> in this grid
     */
    ArrayList<Location> getEmptyAdjacentLocations(Location loc);

    /**
     * Gets the valid occupied locations adjacent to a given location in all
     * eight compass directions (north, northeast, east, southeast, south,
     * southwest, west, and northwest). <br />
     * Precondition: <code>loc</code> is valid in this grid
     * @param loc a location in this grid
     * @return an array list of the valid occupied locations adjacent to
     * <code>loc</code> in this grid
     */
    ArrayList<Location> getOccupiedAdjacentLocations(Location loc);

    /**
     * Gets the neighboring occupants in all eight compass directions (north,
     * northeast, east, southeast, south, southwest, west, and northwest).
     * <br />
     * Precondition: <code>loc</code> is valid in this grid
     * @param loc a location in this grid
     * @return returns an array list of the objects in the occupied locations
     * adjacent to <code>loc</code> in this grid
     */
    ArrayList<E> getNeighbors(Location loc);
Actor 类

Actor 类定义有 Getter 方法取得该 actor 对象的属性。

public Color getColor();
public int getDirection();
public Grid<Actor> getGrid();
public Location getLocation();

Actor 类定义有将对象放入 grid 、将对象从 grid 中移除的方法。

public void putSelfInGrid(Grid<Actor> gr, Location loc);
public void removeSelfFromGrid();

Actor 类定义有 Setter 方法设置该 actor 对象的属性。

public void moveTo(Location loc);
public void setColor(Color newColor);
public void setDirection(int newDirection);

Actor 类定义有 act 方法,决定给对象的行动模式,所有 Actor 的子类都可以通过重载 act 方法定义自己的行为,如 Rock 类、Flower 类和 Bug 类。

public void act();

Jumper 类

实现一个 Actor 的子类 Jumper ,在正常情况下 Jumper 每次移动两个,设计特殊情况下的行为,并通过 Junit 测试。

详见 设计文档测试文档

Part 4:Interacting Objects

Critter 是有许多相似行为,但是行为的细节有所不同的一些 actor。

Critter 类的方法有:

ArrayList<Actor> getActors();
void processActors(ArrayList<Actor> actors);
ArrayList<Location> getMoveLocations();
Location selectMoveLocation(ArrayList<Location> locs);
void makeMove(Location loc);

Critter 的 act 方法都相同,流程为:

(1) 调用 getActor 获取一个 Actor 的列表;

(2) 调用 processActors 对列表中的 Actor 作操作;

(3) 调用 getMoveLocations 获取可以移动的位置的列表;

(4) 调用 selectMoveLocation 从列表中选择一个可以移动的位置;

(5) 调用 makeMove 移动到下一位置。

扩展 Critter 类

通过重载 Critter 类的 getActorprocessActorsgetMoveLocationsselectMoveLocationmakeMove 方法中的一个或多个,实现有特定行为的 Critter。

Part 5:Grid Data Structures

AbstractGrid 类

GridWorld 中提供了 BoundedGrid 和 UnboundedGrid 这两种对 Grid 接口的实现,为了不重复相同的代码,定义一个 AbstractGrid 类实现两种具体 Grid 相同的方法。

AbstractGrid 类实现的方法有:

public ArrayList<E> getNeighbors(Location loc);
public ArrayList<Location> getValidAdjacentLocations(Location loc);
public ArrayList<Location> getEmptyAdjacentLocations(Location loc);
public ArrayList<Location> getOccupiedAdjacentLocations(Location loc);
public String toString();
BoundedGrid 类

有界 Grid 有确定的行数和列数,只能访问界限内的位置。

BoundedGrid 类使用一个二维数组存储各个位置上的对象,若位置空闲,数组元素为 null

private Object[][] occupantArray;

UnboundedGrid 类

在无界 Grid 中,所有位置都是有效的。

UnboundedGrid 类使用 Map<Location,E> 数据结构存储位置以及位置上的对象,不存储空闲的位置。

private Map<Location, E> occupantMap;

SparseGrid 类

使用不同的数据结构实现对象稀疏的 Grid。

Sparse Array 数据结构

Sparse Array 是一个链表的数组,链表的每个元素存储有一个对象和对象所在的列索引,数组的每个元素存储一个链表,若该行为空,对应链表为 null

Sparse Array 有两种实现方式:

(1) 可以使用链节点

public class SparseGridNode
{
    private Object occupant;
    private int col;
    private SparseGridNode next;
    ... ...
}

(2) 可以使用链表和辅助类

public class OccupantInCol
{
    private Object occupant;
    private int col;
    ... ...
}

HashMap 和 TreeMap 数据结构

存储 (Location,Actor) 的键值对。

private HashMap<Location,E> occupant = new HashMap<Location,E>();

private TreeMap<Location,E> occupant = new TreeMap<Location,E>();

阶段 3:扩展任务

ImageProcessing

图像的本质就是一个存放着每个像素颜色值信息的矩阵。本实验要求利用本实验软装置,实现一个利用二进制流读取 Bitmap 图像,并且能够进行简单地处理和保存的软件。

Bitmap 文件结构

典型的位图文件格式通常包含下面几个数据块:

  • 位图头: 保存位图文件的总体信息。
  • 位图信息: 保存位图图像的详细信息。
  • 调色板: 保存所用颜色的定义。
  • 位图数据: 保存一个又一个像素的实际图像。
ImageReader

实现 IImageIO 接口。

myRead 方法以二进制形式读 Bitmap 图像;myWrite 方法调用 Java API 写 Bitmap 图像。

ImageProcessor

实现 IImageProcessor 接口。

showChanelRshowChanelGshowChanelB方法提取图像的颜色通道;showGray 方法将图像转换为灰度图。

MazeBug

学习、理解和应用深度优先搜索算法。本实验要求在改进的Grid World软件装置中实现深度优先搜索算法,从而使虫子走出迷宫。

深度优先搜索算法

基本步骤:

  1. 先将树的所有节点标记为”未访问”状态。

  2. 输出起始节点,将起始节点标记为”已访问”状态。

  3. 将起始节点入栈。

  4. 当栈非空时重复执行以下步骤:

    a. 取当前栈顶节点。

    b. 如果当前栈顶节点是结束节点(迷宫出口),输出该节点,结束搜索。

    c. 如果当前栈顶节点存在”未访问”状态的邻接节点,则选择一个未访问节点,置为”已访问”状态,并将它入栈,继续步骤a。

    d. 如果当前栈顶节点不存在”未访问”状态的邻接节点,则将栈顶节点出栈,继续步骤a。

改进搜索算法

增加方向的概率估计。在行走正确路径时,对四个方向的选择次数进行统计,从而控制随机选择时选择某个方向的概率。增加方向的概率估计后能有效地提高走有方向偏向性的迷宫的效率。

在这里插入图片描述

N-Puzzle

重排拼图游戏也叫N-数码问题(N-puzzle,N=MxM-1),以3x3拼图(8-数码问题)为例,在3x3的方格棋盘上,放置8个标有1、2、3、4、5、6、7、8数字的方块和1个空白格,空白格可以上下左右移动。要求通过反复移动空白格,寻找一条从某初始状态到目标状态的移动路径。

盲目搜索策略

使用广度优先算法求解 N-数码问题。

广度优先算法基本步骤:

  1. 将起始节点放入一个open列表中。

  2. 如果open列表为空,则搜索失败,问题无解;否则重复以下步骤:

    a. 访问open列表中的第一个节点v,若v为目标节点,则搜索成功,退出。

    b. 从open列表中删除节点v,放入close列表中。

    c. 将所有与v邻接且未曾被访问的节点放入open列表中。

启发式搜索

与盲目搜索不同,启发式搜索(如A*算法)利用问题拥有的启发信息来引导搜索,动态地确定搜索节点的排序,以达到减少搜索范围,降低问题复杂度的目的。

算法基本步骤:

  1. 将起始节点放入一个列表中。

  2. 如果列表为空,则搜索失败,问题无解;否则重复以下步骤:

    a. 访问列表中的第一个节点v,若v为目标节点,则搜索成功,退出。

    b. 从列表中删除节点v。

    c. 利用估价函数,对所有与v邻接且未曾被发现的节点进行估价,按照估价大小(小的在前)插入列表中。

重点在于设计合理有效的估价函数,用于估计下一节点到达目的节点的代价。

在实验中,使用了后续节点不正确的数码个数、曼哈顿距离、欧几里得距离三种估价方法,以 1:2:1 的权重加权求和。在解 5x5 的数码问题时,平均需要搜索 5000 个节点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值