您的位置:首页 > 编程语言 > Go语言

Algorithms(week 1,普林斯顿大学公开课)

2016-02-02 01:28 609 查看
如需视频,课件资料等,请留言,留下email

设计一个算法的步骤:

Steps to developing a usable algorithm.

・Model the problem.

・Find an algorithm to solve it.

・Fast enough? Fits in memory?

・If not, figure out why.

・Find a way to address the problem.

・Iterate until satisfied.

总结:我们如何使用算法呢?首先,把问题建模,关键是要理解问题是什么?它包含什么元素?然后,找一个可以解决这个问题的算法。如果有很多可用的算法(比如排序算法就有很多),我们要如何选择呢?要空间还是要时间?想明白我们到底要满足什么,然后不断找出最佳解决方法。

动态连接算法:

准备——问题与问题建模:

Given a set of N objects.

・Union command: connect two objects.

・Find/connected query: is there a path connecting the two objects?

问题描述:现在有一堆对象(不重复),可以使用 ”连接命令“,连接相邻的两个对象,那么如何判断任意两个对象之间相连接呢?

问题建模:

1 .我们用0——n个数字代表对象的名称,(比如,int表示数组的索引)。

2.We assume “is connected to” is an equivalence relation:

・Reflexive: p is connected to p.

(任何一个节点与自身都是连接的)

・Symmetric: if p is connected to q, then q is connected to p.

(p可以连接到q,那么q也是可以连接到p的)

・Transitive: if p is connected to q and q is connected to r,then p is connected to r.(p连接q ,q连接r,那么我们说 p可连接r)

3.连接组件:

如下图,这样我们说总共有三个“连接组件”。



也就是说这个算法肯定有两个操作:union操作,queryConnected操作

举个例子,我们事先有如下0——9个数字(对象概念的抽象),执行union命令做连接:

union(4, 3)

union(3, 8)

union(6, 5)

union(9, 4)

union(2, 1)

那么现在 0,7之间是否连接? 否。8,9呢?是。

然后,我们执行连接命令:

union(5, 0)

union(7, 2)

union(1, 0)

union(6, 1)

那么现在0,7是否连接呢?是。



对于海量的数据:



这个算法适用场景? 比如

照片上的像素

- 网络上的节点

- 社交网络中的好友

- 电脑芯片中的晶体管

等等很多

代码实现:

package com.algorithms.week1;

//algorithm     initialize   union  find
//quick-find    N            N      1
public class QuickFindUF {
// id数组的索引代表每个对象的名称,值代表连接情况:如果几个对象连接再在一起,则他们的数组值相同
private int[] id;

/**
* 初始化抽象的数据结构,为节点分配初始id.初始时,所有节点都没有关联
*
* set id of each object to itself (N array accesses)
*
* @param N
*/
public QuickFindUF(int N) {
id = new int
;
for (int i = 0; i < N; i++)
id[i] = i;
}

/**
* check whether p and q are in the same component (2 array accesses)
*
* @param p
* @param q
* @return
*/
public boolean connected(int p, int q) {
return id[p] == id[q];
}

/**
* change all entries with id[p] to id[q] (at most 2N + 2 array accesses)
*
*
* In particular if you just have N union commands on N objects which is
* Unreasonable.
*
* n*n
*
* @param p
* @param q
*/
public void union(int p, int q) {
int pid = id[p];
int qid = id[q];
for (int i = 0; i < id.length; i++)
if (id[i] == pid)
id[i] = qid;
}
}


有个问题,这个 算法会很慢,因为对于union,如果有n个对象,其中每个对象与其他对象连接一次,则会有n*n次运算。这个在海量运算的场景中并不适用!怎么改进呢?待续。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: