coursera 算法二 week 1 wordnet
这周的作业可谓是一波三折,但是收获了不少,熟悉了广度优先搜索还有符号图的建立。此外还知道了Integer.MAX_VALUE。
SAP:
求v和w的大概思路是对v和w分别广度优先搜索,然后遍历图中每一个顶点,如果v和w都可以到达一个顶点,就计算v和w到这一顶点的距离和,最后求出最短的距离以及对应的顶点便是所求length和ancestor。
至于Iterable<Integer> v和Iterable<Integer> w,开始我是求v中每一个顶点和w中的每一个顶点的距离,然后求出最短距离,但提交后时间测试通不过。参考了其他人的一些博客后发现可以遍历一次完成对v或w的广度优先搜索,于是自己写了一个BFS类。然而这次提交出现了OperationCountLimitExceededException,最后检查了半天才发现bfs时丢了一句 ' if(!marked[w]) '。。。后来发现官方提供的BreadthFirstDirectedPaths类可以完成Iterable<Integer> v的广度优先搜索,于是干脆直接调用这个。
但是提交后还是有问题。。。对于没有共同祖先的情况判断不正确,不能返回-1,检查了半天发现每次求length或ancestor都应该在前面加上 anc = -1; 否则这次求返回的是上次的anc。
import edu.princeton.cs.algs4.*;
import edu.princeton.cs.algs4.In; public class SAP {
private Digraph G;
private int anc = -1;
// constructor takes a digraph (not necessarily a DAG)
public SAP(Digraph G) {
if(G == null) throw new IllegalArgumentException();
this.G = new Digraph(G);
} // length of shortest ancestral path between v and w; -1 if no such path
public int length(int v, int w) {
if(v < 0 || v > G.V() - 1 || w < 0 || w > G.V() - 1)
throw new IllegalArgumentException();
anc = -1; BreadthFirstDirectedPaths bv = new BreadthFirstDirectedPaths(G, v);
BreadthFirstDirectedPaths bw = new BreadthFirstDirectedPaths(G, w); int minLength = Integer.MAX_VALUE; for(int i = 0; i < G.V(); i++) {
if(bv.hasPathTo(i) && bw.hasPathTo(i)) {
int l = bv.distTo(i) + bw.distTo(i);
if(l < minLength) {
minLength = l;
anc = i;
}
}
} if(minLength == Integer.MAX_VALUE) return -1;
else return minLength; } // a common ancestor of v and w that participates in a shortest ancestral path; -1 if no such path
public int ancestor(int v, int w) {
length(v, w);
return anc;
} // length of shortest ancestral path between any vertex in v and any vertex in w; -1 if no such path
public int length(Iterable<Integer> v, Iterable<Integer> w) {
if(v == null || w == null)
throw new IllegalArgumentException();
anc = -1; for(int i : v) {
if(i < 0 || i > G.V() - 1)
throw new IllegalArgumentException();
}
for(int i : w) {
if(i < 0 || i > G.V() - 1)
throw new IllegalArgumentException();
} BreadthFirstDirectedPaths bv = new BreadthFirstDirectedPaths(G, v);
BreadthFirstDirectedPaths bw = new BreadthFirstDirectedPaths(G, w); int minLength = Integer.MAX_VALUE; for(int i = 0; i < G.V(); i++) {
if(bv.hasPathTo(i) && bw.hasPathTo(i)) {
int l = bv.distTo(i) + bw.distTo(i);
if(l < minLength) {
minLength = l;
anc = i;
}
}
} if(minLength == Integer.MAX_VALUE) return -1;
else return minLength;
} // a common ancestor that participates in shortest ancestral path; -1 if no such path
public int ancestor(Iterable<Integer> v, Iterable<Integer> w) {
length(v, w);
return anc;
} // do unit testing of this class
public static void main(String[] args) { }
}
WordNet:
wordnet涉及到符号图的问题,开始用ST<String, Integer>来完成noun到id的索引,后来发现一个noun可能对应多个id,于是改为ST<String, Bag<Integer>>。
需要检查有向图是否合格:1.不能有环。通过类DirectedCycle完成。 2.只能有一个root。经参考别人的博客发现一个很巧妙的方法,如果一个顶点是根,那么它不指向其它顶点,所以它不会出现在hypernyms每行的第一个id。
方法sap需要通过id得到noun,用数组的话不能提前知道数组大小,于是参考网上用ArrayList<String>完成id到noun的索引。
import edu.princeton.cs.algs4.*;
import java.util.ArrayList; public class WordNet {
private ST<String, Bag<Integer>> st;
private ArrayList<String> idList;
private Digraph G; // constructor takes the name of the two input files
public WordNet(String synsets, String hypernyms) {
if(synsets == null || hypernyms == null) throw new IllegalArgumentException(); st = new ST<String, Bag<Integer>>();
idList = new ArrayList<String>(); int count = 0;
In in1 = new In(synsets);
while(in1.hasNextLine()) {
String[] a = in1.readLine().split(",");
String[] a2 = a[1].split(" "); for(int i = 0; i < a2.length; i++) {
if(st.contains(a2[i])) st.get(a2[i]).add(Integer.parseInt(a[0]));
else {
Bag<Integer> b = new Bag<Integer>();
b.add(Integer.parseInt(a[0]));
st.put(a2[i], b);
}
}
count++;
idList.add(a[1]);
} G = new Digraph(count);
In in2 = new In(hypernyms);
boolean[] isNotRoot = new boolean[count];
int rootNumber = 0; while(in2.hasNextLine()) {
String[] a = in2.readLine().split(",");
isNotRoot[Integer.parseInt(a[0])] = true;
for(int i = 1; i < a.length; i++)
G.addEdge(Integer.parseInt(a[0]), Integer.parseInt(a[i]));
} for(int i = 0; i < count; i++) {
if(!isNotRoot[i]) rootNumber++;
}
DirectedCycle d = new DirectedCycle(G);
if(rootNumber > 1 || d.hasCycle()) throw new IllegalArgumentException();
} // returns all WordNet nouns
public Iterable<String> nouns() {
return st.keys();
} // is the word a WordNet noun?
public boolean isNoun(String word) {
if(word == null) throw new IllegalArgumentException();
return st.contains(word);
} // distance between nounA and nounB (defined below)
public int distance(String nounA, String nounB) {
if(nounA == null || nounB == null || !isNoun(nounA) || !isNoun(nounB))
throw new IllegalArgumentException();
SAP s = new SAP(G);
Bag<Integer> ida = st.get(nounA);
Bag<Integer> idb = st.get(nounB); return s.length(ida, idb);
} // a synset (second field of synsets.txt) that is the common ancestor of nounA and nounB
// in a shortest ancestral path (defined below)
public String sap(String nounA, String nounB) {
if(nounA == null || nounB == null || !isNoun(nounA) || !isNoun(nounB))
throw new IllegalArgumentException();
SAP s = new SAP(G);
Bag<Integer> ida = st.get(nounA);
Bag<Integer> idb = st.get(nounB); int root = s.ancestor(ida, idb);
return idList.get(root);
} // do unit testing of this class
public static void main(String[] args) { }
}
Outcast:
public class Outcast {
private WordNet wordnet;
// constructor takes a WordNet object
public Outcast(WordNet wordnet) {
this.wordnet = wordnet;
}
// given an array of WordNet nouns, return an outcast
public String outcast(String[] nouns) {
int length = nouns.length;
int[][] distance = new int[length][length];
for(int i = 0; i < length; i++) {
for(int j = i; j < length; j++) {
distance[i][j] = wordnet.distance(nouns[i], nouns[j]);
}
}
int maxDistance = 0;
int sum = 0;
int num = 0;
for(int i = 0; i < nouns.length; i++) {
sum = 0;
for(int j = 0; j < nouns.length; j++) {
if(i < j)
sum += distance[i][j];
else
sum += distance[j][i];
}
if(sum > maxDistance) {
maxDistance = sum;
num = i;
}
}
return nouns[num];
}
// see test client below
public static void main(String[] args) {
}
}
coursera 算法二 week 1 wordnet的更多相关文章
- Coursera 算法二 week2 Seam Carving
这周作业设计到的算法是有向无环图的最短路径算法,只需要按照顶点的拓扑顺序去放松顶点即可.而在这个题目中拓扑顺序就是按照行的顺序或列的顺序. 用到的数据结构为一个二维数组picture同来存储每个像素的 ...
- Coursera 算法二 week 5 BurrowsWheeler
本打算周末完成这次作业,但没想到遇到了hard deadline,刚开始看不懂题意,后来发现算法4书上有个类似的问题,才理解了题意.最后晚上加班,上课加班,还好在11:35也就是课程结束前25分钟完成 ...
- Coursera 算法二 week 3 Baseball Elimination
这周的作业不需要自己写算法,只需要调用库函数就行,但是有些难以理解,因此用了不少时间. import edu.princeton.cs.algs4.FlowEdge; import edu.princ ...
- Coursera 算法二 week 4 Boggle
这次的作业主要用到了单词查找树和深度优先搜索. 1.在深度优先搜索中,在当前层的递归调用前,将marked数组标记为true.当递归调用返回到当前层时,应将marked数组标记为false.这样既可以 ...
- TensorFlow 入门之手写识别(MNIST) softmax算法 二
TensorFlow 入门之手写识别(MNIST) softmax算法 二 MNIST Fly softmax回归 softmax回归算法 TensorFlow实现softmax softmax回归算 ...
- 分布式共识算法 (二) Paxos算法
系列目录 分布式共识算法 (一) 背景 分布式共识算法 (二) Paxos算法 分布式共识算法 (三) Raft算法 分布式共识算法 (四) BTF算法 一.背景 1.1 命名 Paxos,最早是Le ...
- Floyd算法(二)之 C++详解
本章是弗洛伊德算法的C++实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3. 弗洛伊德算法的代码说明 4. 弗洛伊德算法的源码 转载请注明出处:http://www.cnblogs.c ...
- Dijkstra算法(二)之 C++详解
本章是迪杰斯特拉算法的C++实现. 目录 1. 迪杰斯特拉算法介绍 2. 迪杰斯特拉算法图解 3. 迪杰斯特拉算法的代码说明 4. 迪杰斯特拉算法的源码 转载请注明出处:http://www.cnbl ...
- Prim算法(二)之 C++详解
本章是普里姆算法的C++实现. 目录 1. 普里姆算法介绍 2. 普里姆算法图解 3. 普里姆算法的代码说明 4. 普里姆算法的源码 转载请注明出处:http://www.cnblogs.com/sk ...
随机推荐
- MVC5手工添加System.Web.Optimization
VS2012web手工添辑一个空的mvC5的项目,添加EF6的支持,在别的项目里复制了母版页_Layout.cshtml过来,发现Styles.Render未引用,这个引用使用的命名空间是System ...
- cinder服务状态up/down的源码梳理
基于ocata版本的,源码梳理 1)用户输入cinder service-list命令行,查看cinder服务的状态时,cinder的入口函数为cinder/api/contrib/services. ...
- Pillow不支持color emoji font!
我想在MAC下面用pillow把一些文本转换成PNG图片,在转普通文字的时候都没问题,但在遇到emoji字符的时候就搞不定了,代码如下: import loggingimport PIL.Image ...
- vue -- 异常处理集合
1.npm run dev 运行出错,报错如下: > webpack-dev-server --inline --progress --config build/webpack.dev.conf ...
- vue-cli目录结构及说明
使用vue-cli有时会出现一些莫名的问题,清楚项目的结构文件及其意义方便更好的开发和解决问题,介绍如下: build/ // 项目构建(webpack)相关代码 build.js // 生产环境构建 ...
- 洛谷P1047 校门外的树
P1047 校门外的树 题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0 ...
- IdentityServer4 学习笔记[1]-客户端授权
前言 本文内容来自IdentityServer4官网,官网有详细的介绍,并且有源码Demo 官网源码例子传送门 建立授权服务端 我们暂时不配置Https,选择空模板建立项目,项目建立后, 为了查看de ...
- Go入门基础手记
1. 配置环境变量(临时) export GOPATH=yourpath 2. 跨平台交叉编译 env GOOS=linux GOARCH=amd64 go build 3. test写法 // 首先 ...
- centos6.6上安装beef
https://rvm.io/https://rvm.io/rvm/securityhttps://www.runoob.com/ruby/ruby-installation-unix.htmlhtt ...
- $.store.book[?(@.title =~ /^.*Honour.*$/i)]
{ "store": { "book": [ { "category": "reference", "auth ...