本次实验覆盖课程第3、5、6 章的内容,目标是编写具有可复用性和可维护性的软件,主要使用以下软件构造技术:
⚫ 子类型、泛型、多态、重写、重载
⚫ 继承、代理、组合
⚫ 常见的OO 设计模式
⚫ 语法驱动的编程、正则表达式
⚫ 基于状态的编程
⚫ API设计、API 复用
本次实验给定了五个具体应用(径赛方案编排、太阳系行星模拟、原子结构可视化、个人移动App 生态系统、个人社交系统),学生不是直接针对五个应用分别编程实现,而是通过ADT 和泛型等抽象技术,开发一套可复用的ADT 及其实现,充分考虑这些应用之间的相似性和差异性,使ADT 有更大程度的复用(可复用性)和更容易面向各种变化(可维护性)。
实验环境设置请参见Lab-0 实验指南。
在这里给出你的GitHub Lab3仓库的URL地址(Lab3-学号)。
https://github.com/ComputerScienceHIT/Lab3-1173710111
请仔细对照实验手册,针对每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。
首先请列出你要完成的具体应用场景(至少3个,1和2中选一,3必选,4和5中选一,鼓励完成更多的应用场景)。
分析你所选定的多个应用场景的异同,理解需求:它们在哪些方面有共性、哪些方面有差异。
共性:
差异:
AtomStructure轨道物体彼此之间没有区别,需要实现电子跃迁的功能,并可以实现对跃迁操作的历史记录,以便撤销操作和重做。
SocialNetworkCircle中物体之间存在关系,并能够实现添加和删除的操作,需要计算信息扩散度。
运用正则表达式对读入文件进行信息提取和处理,三个应用数据提取的正则表达式如下:
(1)TrackGame
//提取有效的运动员信息
private Pattern athletePattern=Pattern.compile("Athlete\\s*:\\s*:\\s*=\\s*<\\s*([a-zA-Z]+)\\s*,\\s*(\\d+)\\s*,\\s*([A-Z]{3})\\s*,\\s*(\\d+)\\s*,\\s*(\\d{1,2})(\\.)(\\d{1,2})\\s*>");
//提取有效的比赛项目信息
private Pattern gamePattern=Pattern.compile("Game\\s*:\\s*:\\s*=\\s*([1|2|4]00)");
//提取有效的轨道数目信息
private Pattern tracksPattern=Pattern.compile("NumOfTracks\\s*:\\s*:\\s*=\\s*(([4-9])|(10))");
//提取有效的元素名称信息
private Pattern elementPattern=Pattern.compile("ElementName\\s*:\\s*:\\s*=\\s*([A-Z]{1})([a-z]?)");
//提取有效的轨道数目信息
private Pattern tracksPattern=Pattern.compile("NumberOfTracks\\s*:\\s*:\\s*=\\s*(\\d+)");
//提取有效的电子数目信息(每个轨道对应一个电子数)
private Pattern electronPattern=Pattern.compile("NumberOfElectron\\s*:\\s*:\\s*=\\s*((\\d+)(\\/)(\\d+)(;?)\\s*)+");
//提取有效的中心用户信息
private Pattern centralPattern=Pattern.compile("CentralUser\\s*:\\s*:\\s*=\\s*<([A-Za-z0-9]+)\\s*,\\s*(\\d+)\\s*,\\s*([MF])\\s*>");
//提取有效的其他用户信息
private Pattern friendPattern=Pattern.compile("Friend\\s*:\\s*:\\s*=\\s*<([A-Za-z0-9]+)\\s*,\\s*(\\d+)\\s*,\\s*([MF])\\s*>");
//提取有效的用户关系信息
private Pattern tiePattern=Pattern.compile("SocialTie\\s*:\\s*:\\s*=\\s*<([A-Za-z0-9]+)\\s*,\\s*([A-Za-z0-9]+)\\s*,\\s*([0-1])(\\.[0-9]{1,3})?>");
如上提取出有效信息后,再对提取出的字符串分别按照对应格式再用正则表达式进行提取,根据提取出的信息构造中心物体、轨道物体、建立关系等等。
这一部分的功能由抽象类FileReader类实现,该类有三个实例类,分别对应三个具体应用。
FileReader采用静态工厂模式,根据传入的字符串参数(应用类型)来确定返回哪个具体的实例类。
mutable
CircularOrbit采用静态工厂模式,传入String型的参数type,返回实例类ConcreteCircularOrbit
public ConcreteCircularOrbit(String type) { this.type = type; } |
|
public static CircularOrbit return circularOrbit; } |
/** * 返回给定type对应的多轨道系统。 * given the type,return a instance. * @param type: the type of application->"TrackGame"/"AtomStructure"/"SocialNetworkCircle" * @return a new CircularOrbit instance of type. */
|
* 一个轨道系统,由唯一一个中心物体(不是必需)和以其为圆心的若干同心圆轨道组成,轨道上有若干围绕物体,mutable * AF: * 1.一个轨道系统的中心物体->centralObject,具有唯一性,Immutable * 2.一个轨道系统的圆形轨道->track,每个轨道都是Immutable的,可添加多个轨道 * 3.轨道上的物体->physicalObject,Immutable * 4.轨道物体的关系->Graph,mutable * 5.中心物体与轨道物体的关系->CPGraph,mutable |
L centralObject; |
1. 系统的中心物体:类型只能为centralObject包中的类,或者String、Integer、Double。一个轨道系统只能有唯一不变的中心物体。
|
Listtracks |
2. 系统所有轨道的集合:用List存储,无序 |
MapobjectMap |
3. 轨道->轨道上所有轨道物体 的映射:Track->List |
Map |
4. 轨道物体->所在轨道 的映射 :E->Track的映射,key的集合=系统所有轨道物体的集合,value是当前该物体所在的轨道; |
Graph |
5. 轨道物体之间的关系图:用Graph来表示轨道物体之间的关系,Graph中的点一定是系统中有的轨道物体; |
CentralGraph |
6. 中心物体与轨道物体之间的关系图:新建一个CPGraph对象,以CentralUser为中心点; |
String type |
7. 系统所属的应用类型:只能从三个String--"TrackGame" "AtomStructure" "SocialNetworkCircle"中选择,不区分大小写; |
Map |
8. 轨道物体->在轨道上的位置(角度) 的映射:当前该物体在其对应轨道上的位置。 |
所有rep都为private,部分客户端需要的域(如tracks、objectsGraph等),通过get方法进行返回。 |
public boolean addTrack(Track |
/** * 将给定轨道加入系统。 * add the given track into this system. * @param track:the new track to be added. * @return * if this track has been existed,return false; * if this track is not in this system,return false; * otherwise,add it into the system,and return true. */ |
public boolean removeTrack(Track |
/** * 将给定轨道从系统中删除。 * remove the given track from this system. * @param track:the track to be removed. * @return * if this track is not existed,return false; * otherwise,remove it with all objects on it from the system,and return true. */ |
public boolean addCentralObject(L central); |
/** * 将中心物体加入系统。 * add the central object into system. * @return * if there has been a central object in the system,return false,with nothing to do; * otherwise,add it into the system.return true. */ |
public boolean addOrbitObject(Track |
/** * 向给定轨道加入给定物体,不考虑物理位置. * @param track * @return * if the object has been in the given track,return false; * if the object has been in another track,return false; * otherwise,if the track is not in this system,first add the track,then add and return true. */ |
public boolean removeOrbitObject(E object); |
/** * 将给定物体从轨道系统中移除 * @param object * @return * if the object is not in this system ,return false; * otherwise,remove it and return true. */ |
public int addRelationship(E object1,E object2,int weight); |
/** * 在给定两个轨道物体之间建立一条单向边。 * add an edge between the two objects. * @param object1: source * @param object2: target * @param weight: the value of edge * @return * if there have been an edge between the two objects,update the value,return the old value; * otherwise,add a new edge,and return 0. */ |
public int addCPRelationship(L central,E physical,int weight); |
/** * 在给定的中心物体与轨道物体之间建立一条单向边。 * @param centra * @param physical * @param weight * @return */ |
public int addPCRelationship(E physical,L central,int weight); |
/** * 在给定的轨道物体与中心物体之间建立一条单向边。 * @param physical * @param central * @param weight * @return */ |
public FileReader |
/** * 从外部文件读取数据构造轨道系统对象 * Read data from external files to construct system object * @param file * if the file is non-readable,throw exception and warning. */ |
public boolean transmit(E object,Track |
/** * 将object 从当前所在轨道迁移到给定轨道 * move the object to a new given track from current one * * if the track is not in this system,add this track into it first. * * @param object: the object to be moved * @param track: the track that the object should be moved to * @return * if the object is not on any tracks in this system,add the object into this track,return true. * if the track is the same as where the object is on,return false; * if the object has been in the given track,return false with nothing to do; * otherwise,do the move and return true. */ |
public boolean move (E object,double sitha); |
/** * 将object 从当前位置移动到新的sitha角度所对应的位置,sitha保留3位小数。 * move the object to a new given angle from current one * @param object: the object to be moved * @param sitha: a relative angle between [0,360), stand for where the object should be moved to * @return * if the object is not on any tracks in this system,return false; * if the object is on the position,return true; * otherwise,do the move and return true. */ |
public L centralObject(); |
/** * @return * the central object of this system; */ |
public List |
/** * @return * all tracks of this system,order by radius from small to large */ |
public Graph |
/** * @return * a graph:the relationship between all physical objects */ |
public List |
/** * @param track:the given track must be in this system. * @return * first put all physical objects which are on this track,order by position(angle) from small to large in the list, * then put all no-position objects in it. */ |
public double getPosition(E object,Map |
/** * 给定一个变量object,给定位置映射positionMap,返回object对应的位置信息。 * @param object * @param positionMap * @return如果Map中没有该物体对应的位置信息,返回false,否则返回其对应的Map中的value域 */ ConcreteCircularOrbit类中,需要获取轨道物体的位置信息的行为被委托给Tool的getPosition方法执行。 |
public boolean addPosition(E object,Double sitha,Map |
/** * 给定一个变量object,一个位置信息sitha,建立object->sitha的映射并将其加入给定Map中。 * @param object * @param sitha * @param positionMap * @return * 如果sitha在[0.0,360.0)范围内,建立映射并加入Map中,返回true; * 否则直接返回false */ ConcreteCircularOrbit类中,需要将轨道物体固定在某个位置的行为被委托给Tool的addPosition方法执行。 |
public List |
/** * 给定一个轨道Track,给定位置映射Map,将Track上的所有轨道物体按照其在Map中的绝对位置从小到大排序,然后返回排好序的物体集合。 * @param track * @param positionMap * @return */ ConcreteCircularOrbit类中,需要获取拥有绝对位置的轨道物体集合,并将其按从大到小排序,的行为被委托给Tool的该方法执行。 |
(6).2 UseForComparator
class UseForComparator private E label; private double position;
public UseForComparator(E object,double sitha) { this.label=object; this.position=sitha; }
E getLable() { E label=this.label; return label; }
double getPosition() { double position=this.position; return position; } } |
/** * 用于辅助排序的辅助类,提供两个域,将泛型的physicalObject与其在轨道上对应的位置封装到一起,以便于构造Comparator * @author 1173710111 * * @param */ |
6.(3) ObjectComparator
class ObjectComparator
@Override public int compare(UseForComparator if (o1.getPosition()>o2.getPosition()) return 1; else if(o1.getPosition()==o2.getPosition()) return 0; else return -1; }
} |
排序接口 |
public Track(L belong,int label,double radius) { this.belong=belong; this.label=label; this.radius=radius; } |
/** * AF:Immutable * 1.轨道所属的系统->belong,类型只能为centralObject包里定义的类,唯一确定,Immutable * 2.轨道的标签->label,Immutable * 3.轨道的半径->radius,Immutable * @author 1173710111 * */ |
private L belong; |
1.轨道所属的系统:用系统的centralObject表示 |
private int label; |
2.轨道的标签:用一个整型变量表示,代表轨道的序号,在一个系统里每个轨道的标签是唯一且独一无二的。 |
private double radius; |
3.轨道的半径:用一个大于等于0.0的双精度浮点数表示,轨道的半径决定了轨道之间的次序。 |
Track类的所有rep都为private标识的,客户端只能通过constructor为其赋初始值,再次调用时只能通过getter方法获取,不能修改。 |
三个rep的getter方法 |
public String toString(){ String string = "< " + this.belong.toString() + ", " + this.label + ", "+this.radius+">"; return string; } |
public boolean equals(Track if (this.toString().equals(track.toString())) return true; else return false; } |
rep:
private String elementName; private int numberOfTracks; |
function:
三个域的getter |
public boolean equals(Nucleus e) { if (this.elementName.equals(e.getElementName())) return true; else return false; } |
rep:
private String name; private int age; private char sex; |
function:
三个域的getter |
public String toString() { String string="<"+this.name+", "+this.age+", "+this.sex+">"; return string; } |
public boolean equals(CentralUser user) { if (this.toString().equals(user.toString())) return true; else return false; } |
(1)抽象类PhysicalObject,包含了三个应用的PhysicalObject公有的域和方法:
rep:
protected String name; |
|
protected int x; |
PhysicalObject在画布上的横坐标 |
protected int y; |
PhysicalObject在画布上的纵坐标 |
function:
//各子类按照自己的域对toString方法进行重写 public String toString() { String string=""; string=string+"<"+this.getName()+">"; return string; } |
public boolean equals(PhysicalObject o) { if (this.toString().equals(o.toString())) return true; else return false; } |
Athlete:
rep:
private int age; |
private int number; |
private String nationality; |
private double bestScore; |
function:
@Override public String toString() { String string=new String("<"); string=string+this.getName()+","; string=string+this.getNumber()+","; string=string+this.getNationality()+","; string=string+this.getAge()+","; string=string+this.getBestScore()+">"; return string; } |
Electron:
电子可以认为彼此之间没有区别,不需要添加其他域和方法。
User:
rep:
private char sex; |
private int age; |
function:
@Override public String toString() { String string="<"+this.name+", "+this.age+", "+this.sex+">"; return string; } |
CircularOrbitAPIs
基于所选定的三个应用构造的具体的多轨道结构,可在其上开展一系列共性计算
public double getObjectDistributionEntropy(CircularOrbit |
/** * 计算多轨道系统中各轨道上物体分布的熵值. * 每一条轨道上的物体数目/轨道系统所有物体数目作为p,使用entropy=-sigma(pi*log2(pi))公式计算轨道系统熵值。 * @param system * @return */ |
public int getLogicalDistance(CircularOrbit |
/** * 使用BFS算法计算给定的两个物体之间的逻辑距离:这里的逻辑距离是指:两个object 之间通过最少多少条边(relation)即可连接在一起。 * 两个物体之间若无关系,则距离无穷大。 * 给出的两个object必须是在给定system中的。 * @param system * @param object1 * @param object2 * @return * 如果两个object之间不连通,返回-1表示距离无穷大,否则返回两点间的最短路长。 */ |
在三个应用中不考虑物理位置,不需要实现 |
获取物理距离 |
Different |
/** * 计算两个多轨道系统之间的差异。两个system必须为同类型的轨道系统。 * @param system1 * @param system2 * @return * 一个Different变量,内部保存了两个系统差异的相关信息。 */ |
Different类:
public Different(CircularOrbit this.system1 = system1; this.system2 = system2; setTrackNumberDifferent(); setObjectNumberDifferent(); setObjectDifferent(); } |
/** * 表示两个系统之间差异的类,需要表达出: * 1.轨道数的差异->trackNumberDifferent * 2.有相同次序的轨道上物体数量的差异->objectNumberDifferentMap * 3.物体的差异(如果物体不需要区分,则无需给出物体的差异)->objectDifferentMap * 两个系统必须为同类型的轨道系统才可以比较。 * @author 1173710111 * * @param * @param */ |
private CircularOrbit
|
* 1.用于比较的两个轨道系统:由构造器根据读入参数赋值,两个系统必须具有相同的类型参数。
|
private CircularOrbit
|
|
private int trackNumberDifferent = 0;
|
* 2.轨道数的差异:用系统1的轨道数-系统2的轨道数得到,可正、可负、可为0,整型变量
|
private Map
|
* 3.轨道标签(序号)->两个系统对应的轨道上物体数量的差:key集合为两个集合的所有轨道标签的并集,value值可正可负可为0 |
private Map |
* 4.轨道标签(序号)->两个系统对应的轨道上表示物体的差异的字符串:key集合如上。 |
(4)Safety from rep exposure
1.所有rep都为private标识的,客户端只能通过constructor为两个system赋初始值 2.另外三个rep是通过三个private标识的set方法进行计算和赋值,客户端只能通过getter方法获取,不能修改。 3.getter方法内部根据rep构建一个新的变量,使其与原rep值相同但内存不同,这样客户端就不能对rep进行修改。 |
private void setTrackNumberDifferent() |
/** * 计算两个系统轨道数的差异=系统1的轨道数-系统2的轨道数。 */ |
private void setObjectNumberDifferent() |
/** * 计算两个系统中有相同次序的轨道上物体数量的差异(系统1-系统2)。 * 如果序号为x的轨道只在系统1中出现,则对应的差异值=系统1中x对应轨道的物体数-0; * 如果序号为y的轨道只在系统2中出现,则对应的差异值=0-系统2中x对应轨道的物体数; */ |
private void setObjectDifferent() |
/** * 一个轨道上有多个物体且需要区分,这种情况下表达“物体差异”可以用类似于集合的形式, * 例如{a,b,c}-{d,f}意味着前者的该轨道上有a\b\c 三个物体没有在后者的同序号轨道上出现, * 而后者有d\f 两个物体没有在前者出现。 */ |
private String setToString(Set |
/** * 给定一个集合,将集合中的所有元素串成一个字符串 * 字符串的两端加大括号,各元素以“,”分隔。 * @param set * @return */ |
本实验中使用Swing实现可视化功能。同时,在简单的轨道系统可视化基础上,添加了一部分简单控件用于优化交互体验。
程序入口主函数在applications包的application.java文件中生命,调用并创建一个新的gui包的Menu类,在这个类里调用三个具体应用类,来实现可视化功能。
(1)主界面
单击下三角,选择应用类型
鼠标点击“交换”按钮:
跃迁:
查询:
添加:
删除:
(1)CircularOrbit等对象使用静态工厂方法实现,在类中设计empty静态方法获得对象。
(2)TrackGame
实现strategy设计模式。设计接口类TrackGame,声明编排分组、交换道次、获取系统三个方法,具体实现交给不同编排策略的实例类完成。
分别实现具体策略类,随机编排TrackGameRandom,按bestscore排序编排TrackGameOrder。
(3)AtomStructure
实现Memento设计模式管理电子跃迁的状态。
设计Record类,保存电子轨道跃迁信息,分别保存跃迁电子electron,源轨道fromTrack,目标轨道toTrack。
设计Memento类,负责保存所有的跃迁操作列表,撤销信息列表,提供如下功能: * 1.判断两个列表是否为空 * 2.添加一个新的跃迁/撤销操作 * 3.弹出上一个跃迁/撤销操作
(4)SocialNetworkCircle
构造使用builder设计模式,设计辅助类Tool包括addUsers,getTrackNumber,buildTracks,通过传入的参数添加轨道系统组成。
利用上述设计和实现的ADT,实现手册里要求的各项功能。
以下各小节,只需保留和完成你所选定的应用即可。
* TrackGame:功能1:给定n 个运动员,自动编排比赛方案(分组、排道次),
* 实现2 种方案(方案1:完全随机;方案2:根据运动员的本年度最好成绩从高到低排序,排名越靠前,则出场越晚,且更占据中央的赛道);
* 功能2:手工调整比赛方案(为两个选手更换赛道、更换组)
TrackGame类设计为接口,根据传入参数来确定返回哪个实例类,对应相对的编排方案。
public static TrackGame switch (type.toLowerCase()) { case "order": trackGame=new TrackGameOrder break; default: trackGame=new TrackGameRandom break; } return trackGame; } |
/** * AF: * 1.跑道->轨道->Track * 2.运动员->轨道物体->PhysicalObject->Athlete * 3.跑道数->每个系统的轨道数 * 4.跑道的内外->半径的大小 * 5.编排比赛方案->构造轨道系统->divideGroups() * (1)分组->构造多个轨道系统 * (2)排道次->将每个PhysicalObject安排到合适的Track上 */ |
public List |
/** * get the circular orbit systems. * @return |
public void divideGroups(); |
/** * 对运动员进行分组,除了最后一组,每组的人数与赛道数相同,每个赛道只有一个人。 * 最后一组的运动员按赛道从内到外分布。 * Make those athletes grouped, with the exception of the last group, each group has the same number of tracks, with only one person per track. * The final group of athletes were distributed from inside to outside by track. */ |
public boolean change(Athlete athlete1, Athlete athlete2); |
/** * 给出两个运动员,将两个人的道次进行交换。 * pre-condition:给定的两个运动员必须是参加同一个比赛的(同一个文件读入),可以属于不同小组,可以是同一个人。 * post-condition:给定的两个运动员是同一个人时不进行交换;否则,如果他们在同一个组,仅交换道次;否则,交换两个人的小组和在小组中的道次。 * @param athlete1 * @param athlete2 * @return * if the given athletes are the same one, return false; * else return true. */ |
两个实例类:
1. TrackGameRandom
public TrackGameRandom (String filename) { reader= system.readAndBuild(filename); } |
private FileReader
|
|
private List
|
存储分好的组,即构造好的轨道系统 |
private CircularOrbit |
用来获取处理文件用的FileReader |
@Override public void divideGroups() |
/** * 分组方案1:随机分组 */ |
2. TrackGameOrder
(1)constructor:
public TrackGameRandom (String filename) { reader= system.readAndBuild(filename); } |
(2)RI:
private FileReader
|
|
private List
|
存储分好的组,即构造好的轨道系统 |
private CircularOrbit |
用来获取处理文件用的FileReader |
(3)function:
@Override public void divideGroups() |
/** * 按方案2进行分组,除了最后一组,每组的人数与赛道数相同,每个赛道只有一个人。 * 最后一组的运动员按赛道从内到外分布。 * Grouped by scenario 2, with the exception of the last group, each group has the same number of tracks, with only one person per track. * The final group of athletes were distributed from inside to outside by track. */ |
* 根据文件提取到的信息构造一个轨道系统来表示一个元素的原子,并可实现下述功能:
* 给定源轨道、目标轨道,模拟电子跃迁。
* 实现Memento设计模式管理电子跃迁的状态。
/** AF: * 1.原子核->CentralObject->Nucleus * 2.电子->PhysicalObject->Electron * 3.电子层->Track * 4.电子跃迁->physicalObject改变所在轨道->transmit */ |
private CircularOrbit |
* 1.构造的原子系统:类型为atomstructure,所有跃迁和相关的操作都在这个系统中完成。 |
private MapvolumMap=new HashMap |
* 2.轨道->对应电子数 的映射:文件信息中给出的轨道和对应电子数是在builder中建立map,如果有电子跃迁到其他轨道,则在跃迁时建立新的映射。 |
private FileReader |
* 3.读文件、构造系统用的FileReader |
private Memento memento=new Memento(); |
* 4.保存这个系统与跃迁有关的所有操作的Memento对象:每个原子系统拥有唯一的memento
|
public CircularOrbit |
/** * 获取构造好的轨道系统 * @return */ |
public void builder() |
/** * 根据提供的文件,读入相关信息,构造原子系统 */ |
public Track |
/** * 给定一个电子层数,获取对应的电子层(轨道) * @param index * @return * 如果给定的index非法(系统中不存在对应的轨道),返回空指针null */ |
public int getVolum(Track |
/** * 给定一个电子层轨道,获取当前该电子层含有的电子数 * @param track * @return * 如果给定的轨道不在该系统内,返回值为0 */ |
public boolean transmit(Track |
/** * 给定源轨道、目标轨道,模拟电子跃迁。 * @param track1 * @param track2 * @return * 如果源轨道没有电子,返回false; * 否则,模拟跃迁,记录这一操作并返回true */ |
public void undoTyping() |
/** * 撤销上一步的跃迁操作 */ |
public void undoTyping(int step) |
/** * 撤销上n步的跃迁操作 * @param step */ |
public void redoTyping() |
/** * 重做上一次撤销的跃迁操作 */ |
public void redoTyping(int step) |
/** * 重做上n次撤销的跃迁操作 * @param step */ |
/** * 保存所有的跃迁操作列表,撤销操作列表,提供如下功能: * 1.判断两个列表是否为空 * 2.添加一个新的跃迁/撤销操作 * 3.弹出上一个跃迁/撤销操作 */ |
/** * 记录一次跃迁操作的信息:跃迁的电子,源轨道和目标轨道 */ |
public SocialNetworkCircle(String filename) { reader = system.readAndBuild(filename); } |
private CircularOrbit |
private FileReader |
public void builder() |
/** * 从社交关系日志中恢复该结构 */ |
public CircularOrbit |
/** * 获取构造好的社交关系系统 * @return */ |
protected void addUsers() |
/** * 从文件中读取中心用户信息,并作为中心物体加入系统 * 从文件中读取用户信息,并作为轨道物体加入系统 */ |
protected void buildGraph() |
/** * 根据文件中提取的信息构造社交关系图 */ |
protected Map |
/** * 根据提供的人物关系图,确定每个用户应在的轨道次序 * @param graph * @return */ |
protected void buildTracks() |
/** * 根据每个用户对应的轨道次序的映射,构造系统的外层轨道,并将轨道物体放置在正确的轨道上 */ |
public double diffusance(User user0) |
/** * 计算某个处于第一条轨道上的某个好友的“信息扩散度”(即通过该好友可以间接认识多少个朋友) * @param user0 * @return */ |
public void addRelationship(User user, double weight) |
* 在中心用户与给定用户之间建立权值为weight的双向边
|
public void addRelationship(User user1, User user2, double weight) |
* 在给定用户之间建立权值为weight的双向边 |
public void removeRelationship(CentralUser centralUser, User user) |
* 删除给定中心用户与给定用户之间的边 |
public int getDistance(User user1, User user2) |
* 计算给定两个用户之间的逻辑距离 |
addUsers,buildGraph,getTrackNumber,buildTracks方法委托给Tool的同名方法实现
以下各小节,只需保留和完成你所选定的应用即可。
请在完成全部实验要求之后,利用Git log指令或Git图形化客户端或GitHub上项目仓库的Insight页面,给出你的仓库到目前为止的Object Graph,尤其是区分清楚312change分支和master分支所指向的位置。