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 ...
随机推荐
- C/C++中的static用法总结
C中: 1. static修饰函数中的变量(栈变量):改变变量的生存期,作用域不变仍为所在函数. 只被初始化一次. 2. static修饰全局变量:限制全局变量只能被模块内访问,不可以在别的模块中用e ...
- surging+EFCore 服务实现入门
准备工作 本篇文章基于上篇基础上进行的,请先了解此篇 surging+CentOS7+docker+rancher2.0 菜鸟部署运行笔记 开发环境 Visual Studio 2017 15.5 ...
- iscsi使用教程(上)
服务端 服务器环境 已经安装过qemu-img的32位ubuntu $ uname -a Linux ubuntu-virtual-machine 3.13.0-46-generic #76-Ubun ...
- Codeforces Round #522 Div2C(思维)
#include<bits/stdc++.h>using namespace std;int a[200007];int b[200007][7];int ans[200007];int ...
- 2017BAPC初赛A(思维,无序图,向量)
#include<bits/stdc++.h>using namespace std;string goods,sister[100010];int x,m;unordered_map&l ...
- SQL SERVER的update select语句的写法
需求: 要根据表A的数据来更新表B的某些字段,A和B要进行条件关联. 常规做法可能写个子查询 简单写法是用SQL Server的update select语法 update T_STOCK_INFO ...
- Mysql实例参数优化15个主要参数讲解(原创)
1.innodb_buffer_pool_size 设置物理内存的60%-80%,反应IO吞吐的最大上限2.innodb_thread_concurrency 线程并发,设置为CPU核心数,如果等于0 ...
- 防止表单submit或按钮button多次连续点击提交
如上例子:当我点击提交按钮触发submitQuartz()函数 防止用户连续点击提交操作 方法一:获取当时点击时间,根据时间差判断 $scope.submitQuartz=function () { ...
- vue 中的.sync语法糖
提到父子组件相互通信,可能大家的第一反应是$emit,最近在学着封装组件,以前都是用的别人封装好的UI组件,对vue中的.sync这个修饰符有很大的忽略,后来发现这个修饰符很nice,官方对她的描述是 ...
- 消息中间件 | 消息协议 | STOPM -- 《分布式 消息中间件实践》笔记
12年,STOMP1.2规范发布 简单的文本消息传输协议,提供一种可互相操作的连接格式,允许客户端与任意消息服务器进行交互 主要的概念 STOMP包含客户端和服务器,其中客户端指生产者或消费 ...