<?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>阅微堂 &#187; 复杂度</title>
	<atom:link href="http://zhiqiang.org/blog/tag/%e5%a4%8d%e6%9d%82%e5%ba%a6/feed" rel="self" type="application/rss+xml" />
	<link>http://zhiqiang.org/blog</link>
	<description>理工科背景的证券从业人员</description>
	<lastBuildDate>Sun, 05 Feb 2012 03:59:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>素数筛法的复杂度</title>
		<link>http://zhiqiang.org/blog/science/computer-science/complexity-of-prime-sieve.html</link>
		<comments>http://zhiqiang.org/blog/science/computer-science/complexity-of-prime-sieve.html#comments</comments>
		<pubDate>Sun, 30 Mar 2008 15:32:45 +0000</pubDate>
		<dc:creator>zhiqiang</dc:creator>
				<category><![CDATA[计算机科学]]></category>
		<category><![CDATA[复杂度]]></category>
		<category><![CDATA[复杂性]]></category>
		<category><![CDATA[算法]]></category>
		<category><![CDATA[素数]]></category>

		<guid isPermaLink="false">http://zhiqiang.org/blog/posts/complexity-of-prime-sieve.html</guid>
		<description><![CDATA[博客 » 计算机科学 » 算法 » Xie Xie给我看了一个链接性能调优--永远超乎想象，里面提到了素数筛法的复杂度，作者用实验发现此筛法是线形的。 所谓素数筛法就是那个求小于n的所有素数最简单的算法： bool* prime(int n) { bool *p = new bool[n]; memset(p, 0, sizeof p); for (int i = 2; i &#60; n; i++) if (!p[i]) for (int j = 2*i; j &#60; n; j+=i) p[j] = true; return p; } 此算法复杂度实际为 。在可以测试的范围内...]]></description>
			<content:encoded><![CDATA[<p id="breadcrumb" class="breadcrumb"><a href="http://zhiqiang.org/blog/">博客</a> » <a href="http://zhiqiang.org/blog/category/science/computer-science">计算机科学</a> » <a href='http://zhiqiang.org/blog/tag/%e7%ae%97%e6%b3%95'>算法</a>  » </p><p>Xie Xie给我看了一个链接<a href="http://blog.csdn.net/rmartin/article/details/1132312" target="_blank">性能调优--永远超乎想象</a>，里面提到了素数筛法的复杂度，作者用实验发现此筛法是线形的。</p>
<p>所谓素数筛法就是那个求小于n的所有素数最简单的算法：</p>
<pre><span style="color: #0000ff;">bool</span>* prime(<span style="color: #0000ff;">int</span> n) {
  <span style="color: #0000ff;">bool</span> *p = <span style="color: #0000ff;">new</span> <span style="color: #0000ff;">bool</span>[n];
  memset(p, 0, <span style="color: #0000ff;">sizeof</span> p);
  <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 2; i &lt; n; i++)
    <span style="color: #0000ff;">if</span> (!p[i])
      <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> j = 2*i; j &lt; n; j+=i)
        p[j] = <span style="color: #0000ff;">true</span>;
  <span style="color: #0000ff;">return</span> p;
}</pre>
<p>此算法复杂度实际为 <span class='MathJax_Preview'><img src='http://zhiqiang.org/blog/wp-content/plugins/latex/cache/tex_f2da6587b781ab2b425b98951869fec0.gif' style='vertical-align: middle; border: none; ' class='tex' alt="O(\sum_{p<n}n/p) = O(n\log\log n)" /></span><script type='math/tex'>O(\sum_{p<n}n/p) = O(n\log\log n)</script>。在可以测试的范围内，的确是接近线形的，虽然实际上不是。下面是如何估计<span class='MathJax_Preview'><img src='http://zhiqiang.org/blog/wp-content/plugins/latex/cache/tex_342199c907543038fcb45ba4e9a10a96.gif' style='vertical-align: middle; border: none; ' class='tex' alt="\sum\frac1p" /></span><script type='math/tex'>\sum\frac1p</script>:</p>
<p><p style='text-align:center;'><span class='MathJax_Preview'><img src='http://zhiqiang.org/blog/wp-content/plugins/latex/cache/tex_7bff06ba2ae02e98fe00f203deeb4072.gif' style='vertical-align: middle; border: none;' class='tex' alt="\begin{eqnarray}\log\log\infty&=&\ln \left( \sum_{n=1}^\infty \frac{1}{n}\right) = \ln \left( \prod_{p} \frac{1}{1-p^{-1}}\right) = \sum_{p} \ln \left( \frac{1}{1-p^{-1}}\right) = \sum_{p} - \ln(1-p^{-1}) \\&=&\sum_{p} \left( \frac{1}{p} + \frac{1}{2p^2} + \frac{1}{3p^3} + \cdots \right) = \left( \sum_{p}\frac{1}{p} \right) + \sum_{p} \frac{1}{p^2} \left( \frac{1}{2} + \frac{1}{3p} + \frac{1}{4p^2} + \cdots \right)\\&=& \sum_{p} \left( \frac{1}{p} + \frac{1}{2p^2} + \frac{1}{3p^3} + \cdots \right) = \left( \sum_{p}\frac{1}{p} \right) + \sum_{p} \frac{1}{p^2} \left( \frac{1}{2} + \frac{1}{3p} + \frac{1}{4p^2} + \cdots \right)\\&<& \left( \sum_{p}\frac{1}{p} \right) + \sum_{p} \frac{1}{p^2} \left( 1 + \frac{1}{p} + \frac{1}{p^2} + \cdots \right) = \left( \sum_{p} \frac{1}{p} \right) + \left( \sum_{p} \frac{1}{p(p-1)} \right)\\&=& \left( \sum_{p} \frac{1}{p} \right) + C\end{eqnarray}" /></span><script type='math/tex; mode=display'>\begin{eqnarray}\log\log\infty&=&\ln \left( \sum_{n=1}^\infty \frac{1}{n}\right) = \ln \left( \prod_{p} \frac{1}{1-p^{-1}}\right) = \sum_{p} \ln \left( \frac{1}{1-p^{-1}}\right) = \sum_{p} - \ln(1-p^{-1}) \\&=&\sum_{p} \left( \frac{1}{p} + \frac{1}{2p^2} + \frac{1}{3p^3} + \cdots \right) = \left( \sum_{p}\frac{1}{p} \right) + \sum_{p} \frac{1}{p^2} \left( \frac{1}{2} + \frac{1}{3p} + \frac{1}{4p^2} + \cdots \right)\\&=& \sum_{p} \left( \frac{1}{p} + \frac{1}{2p^2} + \frac{1}{3p^3} + \cdots \right) = \left( \sum_{p}\frac{1}{p} \right) + \sum_{p} \frac{1}{p^2} \left( \frac{1}{2} + \frac{1}{3p} + \frac{1}{4p^2} + \cdots \right)\\&<& \left( \sum_{p}\frac{1}{p} \right) + \sum_{p} \frac{1}{p^2} \left( 1 + \frac{1}{p} + \frac{1}{p^2} + \cdots \right) = \left( \sum_{p} \frac{1}{p} \right) + \left( \sum_{p} \frac{1}{p(p-1)} \right)\\&=& \left( \sum_{p} \frac{1}{p} \right) + C\end{eqnarray}</script></p></p>
<p>更精确的，</p>
<p><p style='text-align:center;'><span class='MathJax_Preview'><img src='http://zhiqiang.org/blog/wp-content/plugins/latex/cache/tex_e00ebfe7605ef377d04c2d1b7f137a2e.gif' style='vertical-align: middle; border: none;' class='tex' alt="\sum_{p<n}\frac1p = \log\log n+\Theta(1)" /></span><script type='math/tex; mode=display'>\sum_{p<n}\frac1p = \log\log n+\Theta(1)</script></p></p>
<p>注意此估计可直接得出素数有无穷多个 <img src='http://zhiqiang.org/blog/wp-includes/images/smilies/bigsmile.gif' alt=':D' class='wp-smiley' /> 。</p>
<p>但是纯O(n)的算法也不是没有，只不过需要增加辅助空间保存质数列表：</p>
<pre style="color: #000000; background: #ffffff;"><span style="color: #000084; font-weight: bold;">bool</span>* prime(<span style="color: #000084; font-weight: bold;">int</span> n) {
    <span style="color: #000084; font-weight: bold;">bool</span> *isp = <span style="color: #000084; font-weight: bold;">new</span> <span style="color: #000084; font-weight: bold;">bool</span>[n];
    <span style="color: #000084; font-weight: bold;">bool</span> *p = <span style="color: #000084; font-weight: bold;">new</span> p(<span style="color: #000084; font-weight: bold;">int</span>(2*n/log(n)+20));
    memset(isp, 0, <span style="color: #000084; font-weight: bold;">sizeof</span> isp);
    memset(p, 0, <span style="color: #000084; font-weight: bold;">sizeof</span> p);
    <span style="color: #000084; font-weight: bold;">int</span> np = 0;
    <span style="color: #000084; font-weight: bold;">for</span> (<span style="color: #000084; font-weight: bold;">int</span> i = 2; i &lt; n; i++) {
        <span style="color: #000084; font-weight: bold;">if</span> (~isp(i)) p(np++) = i;
        <span style="color: #000084; font-weight: bold;">for</span> (<span style="color: #000084; font-weight: bold;">int</span> j = 0; j &lt; pn &amp;&amp; p[j]*i &lt; n; j++) {
            isp[p[j]*i] = 1;
            <span style="color: #000084; font-weight: bold;">if</span>(i%p[j] == 0) <span style="color: #000084; font-weight: bold;">break</span>;
        }
    }
    <span style="color: #000084; font-weight: bold;">delete</span> p;
    <span style="color: #000084; font-weight: bold;">return</span> isp;
}</pre>
<p>这个算法的关键在于 if(i%pr[j] == 0) break;。它使得任何一个合数，只被它最小的质因数标记过一次。所以整个算法是线性的。但考虑到log(log(100000000))还不到3，故这个线性算法其实也只有理论上的价值罢了。</p>
<div><h4>相关文章</h4><ul><li><a href="http://zhiqiang.org/blog/science/computer-science/introduce-probabilistic-checkable-proof.html">PCP - Probabilistic Checkable Proof</a></li><li><a href="http://zhiqiang.org/blog/science/computer-science/preliminary-computer-theory-algorithms-and-calculation-model.html">理论计算机初步：算法和计算模型</a></li><li><a href="http://zhiqiang.org/blog/science/mathmatics-in-rubik-cube-and-algorithm.html">魔方里的数学</a></li><li><a href="http://zhiqiang.org/blog/science/computer-science/programs-depend-on-date-struct-not-algorithm.html">编程的核心是数据结构，而不是算法</a></li><li><a href="http://zhiqiang.org/blog/science/computer-science/another-perfect-shuffle-algorithm.html">Perfect Shuffle的算法</a></li><li><a href="http://zhiqiang.org/blog/science/computer-science/median-algorithm-of-ordered-matrix.html">有序矩阵的中位数算法</a></li><li><a href="http://zhiqiang.org/blog/science/computer-science/inverse-square-root-algorithm-analysis.html">求平方根倒数的算法</a></li><li><a href="http://zhiqiang.org/blog/science/computer-science/3-color-a-simple-graph.html">一个简单图的三染色算法问题</a></li><li><a href="http://zhiqiang.org/blog/science/computer-science/how-google-search-similar-images.html">图片搜索的原理</a></li><li><a href="http://zhiqiang.org/blog/science/computer-science/max-drawdown-algorithm.html">最大回撤和最大短期回撤的线性算法</a></li></ul></div>    <p></p>
    <hr noshade style="margin:0;height:1px" />
    <p>&copy; zhiqiang for <a href="http://zhiqiang.org/blog">阅微堂</a>, 2008. | <a href="http://zhiqiang.org/blog/science/computer-science/complexity-of-prime-sieve.html">&#38142;&#25509;</a> | <a href="http://zhiqiang.org/blog/science/computer-science/complexity-of-prime-sieve.html#comments">9 &#26465;&#35780;&#35770;</a></p>]]></content:encoded>
			<wfw:commentRss>http://zhiqiang.org/blog/science/computer-science/complexity-of-prime-sieve.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

