实训总结报告

时间:2022-11-07 05:56:09

实训总结报告

中山大学2017软件工程中级实训

15331023 陈康怡

这篇总结报告主要记录一些自己在实训过程中的收获,以及自己觉得相对重要的知识点

阶段2

这一阶段主要针对Gridworld编程,主要为控制各种Actor的行为,以及对Grid的数据结构的构建。这一阶段所写的代码基本都是一些比较基础的逻辑,但是对于一门全新的、从未接触过的语言而言,完成这些练习有助于我们快速熟悉java语言。

重要知识点:

1.java的接口(interface)

java的接口的作用,是从类中抽象出类的方法。一个接口可以被多个类所继承,一个类可以实现多个接口。接口包含了类的方法的定义,并且这些方法都会被指定为public abstract类型。这也是我所理解的「接口」含义:对外通用的方法。实现了某一接口的类都能按照接口的定义去调用这些实现方法。

接口的声明方法:

[可见度] interface 接口名称 [extends 其他的类名] {
// 声明变量
// 抽象方法
}

一个简单的实例:

Animal.java(接口)

interface Animal {
public void eat();
public void travel();
}

MammalInt.java(接口的实现)

public class MammalInt implements Animal{

public void eat(){
System.out.println("Mammal eats");
}

public void travel(){
System.out.println("Mammal travels");
}

public int noOfLegs(){
return 0;
}

public static void main(String args[]){
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}

参考资料:菜鸟教程 - Java接口

2.对于java.util的综合使用

java.util是java中一个十分常用的包。使用该包可以方便地生成日期(Date)、日历 (Calendar)、随机数(Random),也可以使用堆栈(Stack)、向量 (Vector) 、位集合(Bitset)以及哈希表(Hashtable)等类去实现不同的数据结构。

在这次实训阶段2的Part5使用到了这样的数据结构:

ArrayList<LinkedList<OccupantInCol>> SparseArray

其中OccupantInCol的定义如下:

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

通过LinkedList和Arraylist的组合可以构造出许多不同的数据结构,并且提供了许多简单易用的方法,大大方便了编程。当然使用复杂数据结构时也要相应地考虑其代价。

参考资料:博客园 - java.util包详解

阶段3

阶段3做了3个蛮有意思的任务,第一个是一个bmp图像读取/处理装置。通过二进制流读取bmp图像并通过代码的处理,在java的gui程序上将图片显示出来,并且通过对图像数据的处理得到RGB单通道图和灰度图。这里主要学到的是对二进制数据的读取、处理、写入操作。使用Bytes类型的数组储存二进制数据,用二进制流从文件中读取、写入,使用移位、与或非等操作对数据进行处理。这些练习更多的是在培养我们对抽象的数据的处理能力。

相关资料:CSDN - Bitmap文件结构探讨

第二个任务是做一个迷宫自动寻路的算法。这里用到的算法是DFS(深度优先搜索),并且在其之上进行优化。DFS并不难,只要按照基本步骤,耐心细致地写就可以了。

深度优先搜索算法的基本步骤

此算法对应无环路迷宫的树结构。

(1) 先将树的所有节点标记为"未访问"状态。

(2) 输出起始节点,将起始节点标记为"已访问"状态。

(3) 将起始节点入栈。

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

① 取当前栈顶节点。

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

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

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

第三个任务是做一个拼图自动完成的算法。

对于运算量相对较少的拼图而言,可以使用BFS(广度优先搜索)来找到最优解。其基本步骤如下。

BFS算法步骤

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

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

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

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

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

而对于大规模的运算而言,需要更高效率的算法。这次实训接触到了A*算法,它的主要思想是对于接下来可行的选择进行评估,收集当前的信息对这些选择的代价作出动态判断,从而缩小搜索范围,大大减少求解的时间。

对于这个拼图游戏的例子,可以参考的信息有:

1) 所有 放错位的数码 个数

2) 所有 放错位的数码与其正确位置的距离 之和

3) 后续节点不正确的数码个数

同时使用多个估价方法时,要注意它们各自在估价中的权重。

心得体会

这次实训相比之前的初级实训简单了不少,而且压力也比较轻。虽然接触的是新的语言,但是在原有的基础下还是可以很快地掌握。其次是Gridworld提供的可视化的界面可以让我们对我们所编的程序有一个比较直观的呈现。我觉得这种做法对于学习编程还是很不错的。最后谢谢各位TA大大在实训过程中的辛勤付出,谢谢你们~