<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>::SinRain&#039;s Blog:: &#187; 算法</title>
	<atom:link href="http://www.sinrain.cn/tag/%e7%ae%97%e6%b3%95/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sinrain.cn</link>
	<description>Simple Dream Easy Go~</description>
	<lastBuildDate>Wed, 28 Jul 2010 09:30:52 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>再说Common Sub-sequence</title>
		<link>http://www.sinrain.cn/2009/09/04/%e5%86%8d%e8%af%b4common-sub-sequence/</link>
		<comments>http://www.sinrain.cn/2009/09/04/%e5%86%8d%e8%af%b4common-sub-sequence/#comments</comments>
		<pubDate>Fri, 04 Sep 2009 01:15:32 +0000</pubDate>
		<dc:creator>Rain</dc:creator>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[All]]></category>
		<category><![CDATA[赛先生]]></category>
		<category><![CDATA[Code Jam]]></category>
		<category><![CDATA[LCS]]></category>
		<category><![CDATA[算法]]></category>

		<guid isPermaLink="false">http://www.sinrain.cn/2009/09/04/%e5%86%8d%e8%af%b4common-sub-sequence/</guid>
		<description><![CDATA[在之前的一个文里有谈及到过最长公共字序列的问题，这个可以用来衡量俩个序列的相似度。
今年的Goolge Code jam的qualification Round 也有一道类似的问题：
【Sub-Sequence-Match】x=[]是一序列，y=[]是... ]]></description>
			<content:encoded><![CDATA[<p>在之前的一个文里有谈及到过最长公共字序列的问题，这个可以用来衡量俩个序列的相似度。</p>
<p>今年的Goolge Code jam的qualification Round 也有一道类似的问题：</p>
<blockquote><p>【Sub-Sequence-Match】x=[]是一序列，y=[]是另一序列：问x中共有多少个不同的子序列等于y</p>
</blockquote>
<p>和这个问题有一点类似的问题是IJCAI07的一篇文里提到的：</p>
<blockquote><p>【All-Common-Subquence】x=[]是一序列，y=[]是另一序列：问x，y共有多少个不同的公共子序列</p>
</blockquote>
<p>想法还是DP:</p>
<blockquote><p><strong>For S-S-M:</strong></p>
<p>def f(x,y):     <br />&#160;&#160;&#160; if len(x)&lt;len(y):      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return 0      <br />&#160;&#160;&#160; if len(y)==1:      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; count=0      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; for k in x:      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if k==y:      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; count=count+1      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return count      <br />&#160;&#160;&#160; a=len(x)      <br />&#160;&#160;&#160; b=len(y)      <br />&#160;&#160;&#160; if x[a-1]==y[b-1]:      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return f(x[0:a-1],y[0:b-1])+f(x[0:a-1],y[0:b])      <br />&#160;&#160;&#160; if x[a-1]!=y[b-1]:      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return f(x[0:a-1],y[0:b])</p>
</blockquote>
<p>意思就是：   <br />如果x长度比y小，那么返回0；如果长度y=1了，那么就看x串中有几个y，返回这个个数；    <br />不然的话    <br />如果最后一个元素相等，那么让x’为x去掉最后一个元素的序列，y’为y去掉最后一个元素序列：    <br />返回s-s-m(x’,y’)+s-s-m(x’,y)</p>
<p>如果最后一个元素不等，那么直接返回s-s-m(x’,y)</p>
<p>当然可以把上面的递归改写成递推的，这样效率会大大提高，并且不改的话，Code jam的大数据肯定是要会TLE的，改写起来很简单就不写鸟。</p>
<p>再来看看A-C-S的DP，大家基本可以自己想想就可以解决了，和上面的思路很类似</p>
<blockquote><p>N(i, j) = N(i − 1, j − 1) × 2, if Ai = Bj     <br />N(i, j) = N(i − 1, j) + N(i, j − 1) − N(i − 1, j − 1),      <br />if Ai!= Bj</p>
</blockquote>
<p>如果最后的元素相同，实际就是前面的A-C-S(i-1,j-1)×2.（有或没有最后一个item作为CS的一部分）   <br />不然的话等于下面那个，注意要扣除掉重复计算的A-C-S(i-1,j-1)</p>
<p>E-O-F</p>
<p>&copy;2010 <a href="http://www.sinrain.cn">::SinRain&#039;s Blog::</a>. All Rights Reserved.</p>.]]></content:encoded>
			<wfw:commentRss>http://www.sinrain.cn/2009/09/04/%e5%86%8d%e8%af%b4common-sub-sequence/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>说点关联法则</title>
		<link>http://www.sinrain.cn/2009/08/12/association_rule/</link>
		<comments>http://www.sinrain.cn/2009/08/12/association_rule/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 07:04:42 +0000</pubDate>
		<dc:creator>Rain</dc:creator>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[All]]></category>
		<category><![CDATA[赛先生]]></category>
		<category><![CDATA[Data Mining]]></category>
		<category><![CDATA[关联法则]]></category>
		<category><![CDATA[算法]]></category>

		<guid isPermaLink="false">http://www.sinrain.cn/2009/08/12/%e8%af%b4%e7%82%b9%e5%85%b3%e8%81%94%e6%b3%95%e5%88%99/</guid>
		<description><![CDATA[Association Rule Learning是一种用来发掘目前的数据库里的变量之间潜在的关系的例子，这里最有名的例子当属“啤酒与纸尿布”的故事了，实际就是 做了A，然后又会去做B 。
一个直接的应用就是... ]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Association_rule_learning" target="_blank">Association Rule Learning</a>是一种用来发掘目前的数据库里的变量之间潜在的关系的例子，这里最有名的例子当属“啤酒与纸尿布”的故事了，实际就是 做了A，然后又会去做B 。</p>
<p>一个直接的应用就是购物篮分析，或者更流行的，推荐系统( recommendation system )。这些都是能很快想到的应用。可能用到的场所比如沃尔玛（也是之前的啤酒尿布的故事来源）、<a href="http://www.douban.com/" target="_blank">豆瓣</a>儿（我猜，我猜，我猜猜猜）、<a href="http://www.amazon.com" target="_blank">Amazon</a>、<a href="http://www.taobao.com" target="_blank">Taobao</a>或者<a href="http://www.netflixprize.com" target="_blank">NetFlix</a>之类的。</p>
<p>提到关联规则几乎第一个跳出来的要讲的就是Apriori系列的算法，此算法是前IBM Lab的<a href="http://rakesh.agrawal-family.com/" target="_blank">Rakesh Agrawal</a>大牛在94的VLDB的一篇叫《<a href="http://rakesh.agrawal-family.com/papers/vldb94apriori.pdf" target="_blank">Fast Algorithms for Mining Association Rules</a>》的paper里提出来的，该算法在2006年的ICDM里被评选为Top 10 algorithms in data mining. 这个paper也有超过8k的引用，可谓是非常非常的seminal了。</p>
<p>这儿有个八卦，2006年的时候微软偷偷挖走了Rakesh，IBM一看急了，你这个把我们数据组核心专家挖走了以后日子还怎么过啊！而且IBM之前也是给了有超过70万美金的股票期权等来试图以这种方式留人，结果二月份时候Rakesh先是把期权给卖了，然后才加入了M$。IBM就直接一纸诉状给他告上了法庭。结果不了了之，搞技术的挖墙角的事儿见多了。</p>
<p>回到正题，Apriori要解决的是：找出出现的次数大于一个指定的threshold的项集(itemSet)。直接暴力解决的复杂性是不言而喻的，单一个n元素的集合的不同的子集的个数就有{2^n}个，就别说再搭配了。而Apriori的算法的核心思想就是化大为小，从item很小开始做起，慢慢变大。</p>
<blockquote><p>“老鼠的爸爸也是老鼠”原理：非频繁项集的超集也是非频繁的<br />
if an itemset is not frequent, any of its superset is never frequent</p></blockquote>
<p>很容易理解吧，因为超集的support（支撑度def: Freq/Obs）肯定小于等于子集嘛。理解了这么多基本就可以猜出算法啦：</p>
<p><a rel="lightbox" href="http://www.sinrain.cn/wp-content/uploads/138/13847/2009/08/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" src="http://www.sinrain.cn/wp-content/uploads/138/13847/2009/08/image-thumb.png" border="0" alt="image" width="568" height="482" /></a></p>
<p>第三行的函数Apriori-gen函数分两步走：</p>
<ol>
<li> 
<ol>
<li>连接步: R_{k+1}，连接所有的满足前{k-1}个元素相同的P_k和R_k生成一个k+1元的itemset<br />
e.g.:P_k={ a_1, a_2, …a_{k-1}, a_k},  R_k={ a_1, a_2, …a_{k-1}, a_k’ }<br />
      &#8212;&gt; R_{ k+1 }={ a_1, .. a_{k-1}, a_k, a_k’ }</li>
<li>剪枝步: 如果R_{k+1}中有任一k元子集R’不是频繁集，那么直接剪去该枝，如前所言，必须要是所有的自己都是频繁的，那么超集本身才可能是频繁的。</li>
</ol>
</li>
</ol>
<p>与此同时，Apriori的缺点也是一堆啦，频繁的扫描数据库，必然带来算法效率的低下，下篇给一个算法Demo和潜在的改进。</p>
<p>&copy;2010 <a href="http://www.sinrain.cn">::SinRain&#039;s Blog::</a>. All Rights Reserved.</p>.]]></content:encoded>
			<wfw:commentRss>http://www.sinrain.cn/2009/08/12/association_rule/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>春天到，复苏了</title>
		<link>http://www.sinrain.cn/2009/03/14/spring-comes/</link>
		<comments>http://www.sinrain.cn/2009/03/14/spring-comes/#comments</comments>
		<pubDate>Sat, 14 Mar 2009 05:41:55 +0000</pubDate>
		<dc:creator>Rain</dc:creator>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[All]]></category>
		<category><![CDATA[Nankin Story]]></category>
		<category><![CDATA[赛先生]]></category>
		<category><![CDATA[雨先生]]></category>
		<category><![CDATA[0-1背包]]></category>
		<category><![CDATA[DP]]></category>
		<category><![CDATA[算法]]></category>

		<guid isPermaLink="false">http://www.sinrain.cn/2009/03/14/spring-comes/</guid>
		<description><![CDATA[最近一段时间非常慵懒，加上连日阴雨。除了窝在宿舍看看闲书，偶尔出去打打球之外基本没有什么活动，实在是浪费韶华。
今天出门一瞥，竟然花开燕语春欣然而至也！遂决定从连日冬眠里... ]]></description>
			<content:encoded><![CDATA[<p>最近一段时间非常慵懒，加上连日阴雨。除了窝在宿舍看看闲书，偶尔出去打打球之外基本没有什么活动，实在是浪费韶华。</p>
<p>今天出门一瞥，竟然花开燕语春欣然而至也！遂决定从连日冬眠里复苏，重出江湖。</p>
<p>先弄个昨日的题目：</p>
<blockquote><p>Subset SUM Problem<br />
{a[1],a[2]&#8230;a[k]} choose some a[i]s<br />
S.T.<br />
\sum a[i]=T   T is a positive integer.</p></blockquote>
<p>其实就是个简单的<strong>0-1背包问题</strong><br />
可以用DP来解：</p>
<blockquote><p>f(i,x)=Max{  f(i-1,x-a[i])+a[i]   f(i-1,x) }</p></blockquote>
<p>这个是背包的变种。。i.e.  重量w[i]和价值c[i]是一样的。<br />
采取非递归算法（只需要从f(1,x)开始往上推就好了），复杂度 O(KT)</p>
<p>那如果这个背包的解是f(k,T)=T那么问题就解决了。</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>不了解0-1背包的同志，可以看看这个<a target="_blank" href="http://en.wikipedia.org/wiki/Knapsack_problem">Zero One Knapsack Problem</a></p>
<p>&copy;2010 <a href="http://www.sinrain.cn">::SinRain&#039;s Blog::</a>. All Rights Reserved.</p>.]]></content:encoded>
			<wfw:commentRss>http://www.sinrain.cn/2009/03/14/spring-comes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
