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

设计一个算法的步骤:

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[N];
		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次运算。这个在海量运算的场景中并不适用!怎么改进呢?待续。。。。

评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值