Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 7

11
votes
answers
18 views
+10

Task on the number of iterations

There is a number N every iteration it becomes equal to (N*2)-1 I need to find out how many steps the number will be a multiple of the original N;

( 1≤ N ≤ 2 · 10 9 )

For example:

N = 7; count = 0

N_ = 7*2-1 = 13; count = 1; N_ % N != 0

N_ = 13*2-1 = 25; count = 2; N_ % N != 0

N_ = 25*2-1 = 49; count = 3; N_ % N == 0 

Answer is 3

if it is impossible to decompose in this way, then output -1

       #include <iostream> 
       using namespace std;

       int main(){
           int N,M,c;
           cin >> N;
           if (N%2==0) {
               cout << -1;
               return 0;
           }
           M = N*2-1;
           c = 1;
           while (M%N!=0){
               c+=1;
               M=M*2-1;
           }
           cout << c;
           return 0;
       }

It does not fit during (1 second limit). How to optimize the algorithm?

P.S All the answers indicated are optimized, but they don’t fit in 1 second, because you need to change the algorithm in principle. The solution was to use Euler's theorem.

沙发
+50

正如其他答案所暗示的那样,问题等同于找到 c ,使 pow(2,c)= 1 mod N 如果N是偶数,则这是不可能的,否则可能(如您的代码所暗示的那样)。

线性时间方法是:

  int c = 1; uint64_t m = 2; while(m!= 1){c + = 1; m =(2 * m)%N; } printf(“%d”,c);   

要在1秒内解决这个问题,我认为你不能使用线性时间算法。最糟糕的情况是 N 是素数大而且很大。例如1999999817,上面的代码在我的笔记本电脑上运行大约10秒钟。

相反,将 N 纳入其主要因素。求解 2 ^ c = 1 mod p ^ k 对于给定的素数幂,如果 k = 1 ,则解决方案是 c = p-1 k 更大时,细节非常混乱,但你可以在这里找到一个书面解决方案: https://math.stackexchange.com/questions/1863037/discrete-logarithm-modulo-powers-of-a-small-prime 对于给定的素数幂,如果 k = 1 ,则解决方案是 c = p-1 k 更大时,细节非常混乱,但你可以在这里找到一个书面解决方案: https://math.stackexchange.com/questions/1863037/discrete-logarithm-modulo-powers-of-a-small-prime

板凳
+40

问题是你溢出,int数据类型只有32位,溢出2 ^ 31-1,在这个问题你不需要保持M的实际值,你可以保持模数n。

  while(M%N!= 0){c + = 1; M = M * 2-1; M%= N}   

编辑:此外,你实际上不需要超过N次迭代来检查是否存在0 mod,因为N只有N个不同的mod并且它只是骑自行车。因此,如果没有0 mod,你还需要牢记这一点。

如果有溢出,那么测试就没有错误的答案,但我有一个与时间相关的错误 - yoloy 8月29日5:38

这当然是你迈出的一大步,但它并没有增加速度 - yoloy 8月29日5:39

@yoloy你怎么知道法官在收到错误答案之前没有放弃?这可能是也可能不是整个问题,但它是一个错误。 - user4581301 8月29日5:39

旁注:在M%= N的情况下,循环条件中的M%N基本上是冗余的。 - user4581301 8月29日5:40

当你溢出时,while循环不会结束,因为mod不会达到0,数字将变为负数并且继续溢出,这导致超出时间限制 - Malek Aug 29 at 5:42

地板
+20

毫无疑问,您的代码的主要问题是有符号整数溢出

每当 M时,我都会添加 M 的打印件已更改(即 cout&lt;&lt; M&lt;&lt; endl; )并给它输入29.这就是我得到的:

  57 113 225 449 897 1793 3585 7169 14337 28673 57345 114689 229377 458753 917505 1835009 3670017 7340033 14680065 29360129 58720257 117440513 234881025 469762049 939524097 1879048193 -536870911 -1073741823 -2147483647 1 1 1 ...无限循环  

如您所见,您已经签署了整数溢出。这是C中的未定义的行为,所以任何事情都可能发生!在我的机器上,我结束了一个讨厌的无限循环。在考虑性能之前必须先修复它。

简单的解决方法是添加一行,如

  M = M%N;   

每当 M 被更改时。请参阅@Malek的答案

除此之外,您还应使用无符号整数,即对所有变量使用 uint32_t

但是,这将提高性能。

如果在上述修复后仍有性能问题,您可以尝试这样做:

  uint32_t N; cin&gt;&gt; N; if(N%2 == 0){cout&lt;&lt; -1; 返回0; } //替代算法uint32_t R,c; R = 1; c = 1; 而(R!= N){R = 2 * R + 1; if(R> N)R = R-N; ++℃; } cout&lt;&lt; C;   

在我的笔记本电脑上,当测试1..100000范围内的所有奇数时,此算法的速度要快2.5倍。但是,对于1..2 * 10 ^ 9范围内的所有数字可能还不够。

还要注意使用 uint32_t 来避免整数溢出。

8
votes
answers
4 views
+10

查找2d阵列中所有峰的高效算法

给定矩阵M的整数,峰值是数组中不小于其4个邻居(向上,向下,向左,向右)的元素。有一个很好的线性时间(n乘n矩阵的O(n))算法来找到一个峰值,例如在这些讲义或稍微简单的O(n log n)时间解决方案此代码

假设我想找到k个峰值,如果存在多个峰值。有没有办法在O(n + k)或O(n log n + k)时间内完成此操作?

沙发
+50

答案是否定的。如果 k&gt; 1 然后最糟糕的情况是 O(n ^ 2)

问题在于“如果存在多少”部分。当输入包含少于 k 峰值时,只有当我们确定要找到少于 k 的峰值时,我们的算法才能终止。我将证明(下面)我们只能确定如果我们在相邻元素之间执行 O(n ^ 2)比较,则会有少于 k 的峰值。

证明

为确保元素峰值,我们必须将其与至少 它的一个邻居 - 如果那个邻居恰好更大,那么该元素不是一个峰值。如果我们还没有将一个元素与它的任何一个邻居进行比较,那么它仍然可能是一个峰值,并且我们所做的每个比较最多只排除一个元素来自一个峰值。知道我们的输入中存在少于 k 的峰值相当于知道至少有 n ^ 2 - k + 1 非峰值,这要求我们有至少执行 n ^ 2 - k + 1 比较,即 O(n ^ 2)对于 k&gt; 1 存在&lt;的输入 k 达到峰值,因此在最坏的情况下,我们必须在停止搜索之前执行这些 O(n ^ 2)比较。

注意< / strong>:

k = 1 的情况不会出现此问题的原因是因为每个输入都保证至少有一个峰值。当我们找到第一个峰值时,我们会停止搜索,因此我们无需检查是否找不到更多峰值。

由于我不认为这是对问题的正确解释 - 至少对我来说这个问题是“如果至少有k个峰值,我们能否在O(nlogn + k)时间找到k个?” 如果事实证明我错了就会upvote。 - zw324 8月30日18:33

@myrtclecat如果你事先知道k峰存在怎么办? - 世俗主义滑雪8月30日18:34

回想起来-1是苛刻但投票被锁定: - / - zw324 8月30日18:42

板凳
+30

假设您有 NxN 矩阵 A 最初 A [i] [j] = i + j 只有一个高峰。它很容易找到它,但你试图尽可能快地找到两个峰值。问题是,恶意恶魔会看到你被允许更改你尚未访问过的单个元素的值。显然你无法快速找到第二个峰值,因为恶魔知道你的动作。

形式上,假设算法可以在矩阵中找到最多两个峰而不访问所有元素。 A [i] [j] = i + j 矩阵上运行它。它应该返回单个现有峰值。检查访问了哪些元素。将未访问的元素更改为 3 * N ,这使其成为新的峰值,并再次运行算法。它必须返回与之前相同的答案,现在这是不正确的。

所以答案是否定的。

如果只允许输入至少有k个峰值,那么相同类型的参数都可以工作,只需稍微更改一下。

假设一个算法可以找到两个峰值实际上,在访问 M&lt; N ^ 2 元素时,输入中存在两个或更多个峰值。WLOG我们可以假设,当呈现只有一个峰值的输入时,算法会访问所有元素(如果没有,我们总是可以修改它来执行此操作而不会失去快速处理具有两个峰值的输入的能力,例如切换到M访问后的暴力搜索)。 A [i] [j] = i + j 矩阵表示它。该算法将访问所有元素。注意最后访问了哪个元素并将其更改为峰值(如果最后一个元素峰值,则将第二个最后访问的元素更改为峰值)。再次运行算法。现在输入有两个峰值,但算法仍然需要访问所有元素才能找到它们。

由于我不认为这是对问题的正确解释 - 至少对我来说这个问题是“如果至少有k个峰值,我们能否在O(nlogn + k)时间找到k个?” 如果事实证明我错了就会upvote。 - zw324 8月30日18:36

回想起来-1是苛刻但投票被锁定: - / - zw324 8月30日18:41

@ zw324同样的论证适用于你对问题的解释,我会编辑答案然后你可以重新投票。 - nm 8月31日8:47

地板
0

我怀疑我错过了一些东西,因为对我来说,“是”答案似乎很明显。使用给定的算法查找峰值,但找不到时停止。相反,回溯; 继续寻找,直到你找到 k 的高峰,或者你已经用尽了你的分数&amp; 征服算法。

在某些病态情况下 - 例如导致已知峰值的几个起点 - 您可以通过安排搜索顺序来提高性能。当您向后追溯树然后在广度上移动时,请移动到相邻位置。而是移动到最远未搜索的节点。您可以使用 O(1)距离函数找到它,或者只是抓住一个足够远的距离,给定搜索树的级别(对子矩阵大小的一个很好的估计)。

我的思想的后台正在研究一个包含 k 不同峰值的矩阵,但使用这种方法可以很好地解决问题。二维迷宫设计的连通性提供了许多好的工具 - 这相当于从给定的起点找到迷宫路径。

到目前为止,我似乎有两个没有,一个是。 - Anush 8月30日16:07

这里有问题的部分是回溯。在窗口最大值位于边界上的情况下,您没有其他位置可以提前终止而不会找到所有可能的峰值。如果没有,您可能会回溯,以至于您将访问的不仅仅是O(n)子阵列。 - Nico Schertler 8月30日16:10

“像搜索失败一样回溯”搜索不会失败。总有一个高峰。这是算法的基本假设。删除它,它不再有效。 - nm 8月30日16:12

@nm写错了; 我正在思考,寻找已经通过另一条道路找到的高峰。修复... - 修剪8月30日16:14

如果没有找到k个峰值,那么这种方法如何知道在不访问(几乎)每个元素的情况下停止?在最坏的情况下,它似乎是O(n ^ 2),但如果输入通常包含至少k个峰值,它仍然可能是一个实用的解决方案。 - myrtlecat 8月30日16:15

0
votes
answers
34 views
+10

if if遞歸最壞時間複雜度

4

我有一些麻煩弄清楚下面代碼的最壞時間複雜度。
(這不是一門功課,看https://leetcode.com/problems/integer-replacement/description/。)if if遞歸最壞時間複雜度

int recursion (int n) { 
    if (n == 1) 
     return 0; 
    if (n % 2 == 0) { 
     return recursion(n/2) + 1 
    } else { 
     return min(recursion(n/2 + 1) + 1, recursion(n - 1)) + 1; 
    } 
} 

我唯一知道的是,當N == 2^k(k > 0),最壞的時間複雜度爲O(logN)。 但是,我不清楚何時N不是2^k。因爲即使number/2仍然可以得到奇數。有人說它仍然是O(LogN),但我不相信。

我知道代碼不是最好的解決方案,只是想分析時間複雜性。我試過遞歸樹和聚合分析,似乎沒有幫助。

+0

你的其他情況有錯誤的說法,它應該是'(n + 1)/ 2' –

+0

@BlackMamba。嗨,(n + 1)會溢出。但我有其他錯誤。 Updated.Thanks非常多 – nathan

+0

我看到了leetcode問題陳述。我不知道在前兩個版本中,最後一個分支(用'min'選擇其中一個)與它有關 - 它不應該是「an'else」的一部分,如果「then」無論如何,''終止於無條件的'return'。 – greybeard

沙发
0
4

如果n是偶數,我們知道T(n) = T(n/2) + 1,如果n是奇數我們知道 T(n) = T(n/2 + 1) + T(n-1) + 1。在後一種情況下,由於n很奇怪,我們知道n-1必須是偶數。如果n/2 + 1甚至是T(n) = T(n/4) + T(n/2) + 3並且如果n/2 + 1是奇數T(n) = 2*T(n/4) + T(n/2) + 3

從上面的討論,在最壞的情況下T(n)是基於在一般情況下,T(n/2)T(n/4)定義。從Akra-Bazzi Theorem我們可以說,T(n) = O(n^((log(1+sqrt(5))-log(2))/log(2))) ~ O(n^0.69)(來自第一種情況)和T(n) = O(n)來自第二種情況(其中n/2 + 1是奇數)。

但是,對於更復雜的情況,我們應該在我們的分析中仔細檢查。

+0

嗨,阿克拉 - 巴齊引起了我的思想。我將這個應用於T(n)= T(n/4)+ T(n/2)。 – nathan

+0

如果'n'是奇數,那麼'n/2 + 1'可以是奇數或偶數 - 考慮n = 7和n = 9。 – algrid

+0

@OmG,如果'n = 9',則'n/2 + 1'等於'5'。 – algrid

0
votes
answers
36 views
+10

在哪裏運行JavaScript解決TSP與GA

1

我已編程的TSP求解器遺傳算法,但我必須解決這個問題11000個城市。在瀏覽器中它變得非常慢並且掛起。 如何運行JavaScript的最快的方法?在哪裏運行JavaScript解決TSP與GA

也許在Mac的終端或與亞馬遜EC2服務器上,或者用火力點雲功能的node.js node.js的?

非常感謝

+0

是,在發動機運行時(在node.js中)可能給你對環境的更多控制,並不會影響您的網上衝浪。 (當然,它仍然會很慢,吃你的CPU)。在哪臺機器上 - 您的本地mac,雲實例或其他 - 只能運行該程序,您可以決定。 – Bergi

+0

一些更多的思考:你經常需要解決的問題(運行程序)?輸入和輸出如何工作(或對您而言最方便的是什麼)?對於這樣的問題 – Bergi

+0

使用的JavaScript可僅用於演示。如果您需要爲某個實際應用程序解決此問題,請選擇更好的語言。 –

沙发
0
1

用js很難解決。你需要靠CPU來運行你的代碼。我更喜歡使用正確參數的C,C++。然後你可以建立引擎作爲服務。如果速度不是你的第一個標準,你可以使用服務器端技術看起來像nodejs,php,.net。您需要緩存機制來保存解決方案。如果您打算使用AWS,則可以查看AWS lambda服務。我寧願使用沒有虛擬實例的自己的服務器虛擬實例具有較低的內存訪問速度。您需要進行大量測試以確定您的正確平臺。

0
votes
answers
38 views
+10

製作「插入排序」算法更高效 - 的Python 3.5.2

0

我已經嘗試在Python編碼插入排序算法 -製作「插入排序」算法更高效 - 的Python 3.5.2

def insertion(list): 
    checked = 2 
    while (checked <= len(list)): 
     for i in range(checked-1): 
      if list[checked-1] < list[i]: 
       list.insert(i, list[checked-1]) 
       del list[checked] 
     checked+=1 
    return list 

我測量它採取執行1000項排序的時間 - 106.08099999999997第二

1000分之

我發現這是相當緩慢的,因爲 -

def bubbleSort(alist,n): 
    for j in range(1,n): 
     nextnum = alist[j] 
     i = j - 1 
     while i>=0 and alist[i]>nextnum: 
      alist[i + 1] = alist[i] 
      i = i - 1  
     alist[i + 1] = nextnum 

僅僅用了 - 83.71800000000007千分之一一秒

有沒有什麼辦法可以讓我的代碼更有效率/我會不得不使用不同的代碼?如果是這樣,哪種插入排序實現在python中最快?我知道插入排序通常不是最好的算法。這只是爲了我的學校工作,以便我能更好地理解我們學習的算法。

+0

1.您是如何「測量」的?你用'timeit'完成了嗎? 2.如果你想要一個高效的排序算法,不要使用O(n^2)算法:使用合併或快速排序。如果你知道數字的範圍,你可以用基數或桶排序來實現線性時間 – alfasin

+0

我剛用過time.clock()。它可能不準確,但它只是爲了證明它比其他代碼慢。再次,正如我在底部所述,這僅僅是爲了學校工作。我並不是在尋找最高效的算法,但感謝您的建議。 –

沙发
0
1

插入和從列表中刪除比交換位置內容更昂貴。這比冒泡排序更快:

def insertion(M): 
    for i in range(1,len(M)): 
     for j in range(i): 
      if M[i] < M[j]: 
       M[j],M[j+1:i+1] = M[i],M[j:i] 
       break 

注意這裏使用了a,b = b,a「交換」語法,交換的檢查值插入位置,領先交換的剩餘值列表中的一個。而且,一旦交換完成,從內部循環中斷開。無需繼續檢查插入位置。您還可以檢查要交換的值是否已經大於或等於先前排序的值,並且如果爲true,則跳過內部循環:

def insertion(M): 
    for i in range(1,len(M)): 
     if M[i] >= M[i-1]: 
      continue 
     for j in range(i): 
      if M[i] < M[j]: 
       M[j],M[j+1:i+1] = M[i],M[j:i] 
       break 
+0

我看,這非常有幫助,非常感謝你!我想我可以運用這些技術來使我的其他算法更加高效!更新 - 你將時間縮短到原來的40%! –

0
votes
answers
36 views
+10

找到第k個最小元素

-1

我跟着本書中的算法解決了這個問題。當我打印結果時,它是不正確的。該算法是完全按照書中 我的代碼找到第k個最小元素

import math 

def quickSelect(A, k): 
    m = A[math.floor(len(A)/2)] 
    L = [i for i in A if i < m] 
    E = [i for i in A if i == m] 
    G = [i for i in A if i > m] 
    print(L) 
    print(E) 
    print(G) 

    if k <= len(L): 
    return quickSelect(L, k) 
    elif k <= (len(E) + len(G)): 
    return m 
    else: 
    return quickSelect(G, k- len(L) - len(E)) 

result = quickSelect([7, 14, 10, 12, 2, 11, 29, 3, 4], 4) 

print(result) 
+1

什麼是您預期的結果? – Gumboy

+0

我覺得第4個最小的應該是7對吧?但是當我運行時我得到2 –

+0

你在第二次迴歸elif時的情況是錯誤的。 –

沙发
0
3

這些語句:

L = [i for i in A if i < m]  # less than m 
E = [i for i in A if i == m]  # equal to m 
G = [i for i in A if i > m]  # greater than m 

分區排列爲三個範圍:

| L1 L2 L3 L4 | E1 | G1 G2 G3 
|     |  | 
0     |  | 
       len(L) | 
          len(L) + len(E) 

你的條件爲第二範圍,

elif k <= (len(L) + len(G)): 
    return m 

是錯誤的。它應該是:

elif k <= (len(L) + len(E)): 
    return m 

節點:不要使用浮點運算的,你可以計算m與Python的整數除法:m = A[len(A) // 2]

+0

謝謝,我錯了。如此愚蠢的錯誤 –

0
votes
answers
31 views
+10

使用遞歸進行二叉搜索樹遍歷

-1

問:關於使用遞歸和返回的二叉搜索樹遍歷,我有疑問。我必須按照按升序排列鍵的BST,然後「倒轉」它,這樣所有鍵都按降序排列,正如您在圖片中看到的那樣。使用遞歸進行二叉搜索樹遍歷

根據我的下面的代碼的瞭解,我認爲步驟是:

->reverseKeys (10) ->reverseKeys (2) 
    ->reverseKeys (null): return 
    ->reversekeys(null): return 
    ->BSTNODE <T> ptr = root.left; 
    ->root.left = root.right; 
    ->root.right = ptr; 

我想我誤解的代碼。有人能夠擴展這個代碼如何將左邊的圖片更改爲右邊?我將不勝感激任何幫助。

25     25 
/    / 
10 40  ---> 40 10 
/ /   // 
2 20 30 45  45 30 20 2 
/    /  
15 35   35 15 

public static <T extends Comparable<T>> 
void reverseKeys(BSTNode<T> root) { 
    if (root == null) { 
     return; 
    } 
    reverseKeys(root.left); 
    reverseKeys(root.right); 
    BSTNode<T> ptr = root.left; 
    root.left = root.right; 
    root.right = ptr; 
} 
沙发
0
0

檢查BST - 反向下面的代碼

public void traverse (Node root){ // Each child of a tree is a root of its subtree. 
    if (root.left != null){ 
     traverse (root.left); 
    } 
    System.out.println(root.data); 
    if (root.right != null){ 
     traverse (root.right); 
    } 
} 

// Search with a valid node returned, assuming int 

public Node traverse (Node root, int data){ // What data are you looking for again? 
    if(root.data == data) { 
     return root; 
    } 
    if (root.left != null){ 
     return traverse (root.left, data); 
    } 
    if (root.right != null){ 
     return traverse (root.right, data); 
    } 
    return null; 
} 
板凳
0
1

這些線路只是交換左,右子樹的節點序遍歷(RVL)。由於對方法的遞歸調用,當方法執行時,每個節點都有左右子樹交換。

BSTNode<T> ptr = root.left; 
root.left = root.right; 
root.right = ptr; 
0
votes
answers
18 views
+10

如何在子字符串級別生成同音字符?

1

我想生成編程的單詞同音字。意思是聽起來類似於原始單詞的單詞。如何在子字符串級別生成同音字符?

我碰到過Soundex算法,但它只是用其他字符替換某些字符(如t而不是d)。是否有任何列表或算法有點複雜,至少意味着同音字子串?

重要的是,我想將它應用於不在字典中的單詞,意味着它不能依賴整個真實的單詞。

編輯:

輸入是一個字符串,他們往往是命名實體,因此在沒有真正的(同音字)詞典。一個例子可能是谷歌麥當勞(僅舉兩個流行的命名實體,但許多更不受歡迎)。

然後輸出是該字符串的(隨機)同音字。由於單詞經常有多個同音字,所以單個(隨機)單是我的目標。在谷歌的情況下,同音字可分別古格爾麥當勞麥當勞

+0

分享你的代碼,輸入和期望的輸出 – skrubber

沙发
0
0

如何做到這一點是一個研究課題。例如參見http://www.inf.ufpr.br/didonet/articles/2014_FPSS.pdf

但是,假設你想推出自己的。

第一步是弄清楚如何將給出的字母轉換成它聽起來像的表示。這是一個非常困難的問題,需要猜測。 (例如,什麼聲音「讀取」了?取決於你是否要閱讀,或者你已經閱讀!)但是text to phonemes converter表明阿拉伯已經解決了這個英語。

接下來,您會希望對詞典中的每個詞都進行此操作。假設你可以用一個字來做,那只是一個腳本。

然後,你會希望它存儲在一個數據結構中,你可以很容易地找到類似的聲音。原則上與用於拼寫自動更正的算法類型沒有區別。只能用音素而不是字母。您可以通過http://norvig.com/spell-correct.html瞭解如何做到這一點。或嘗試實施類似http://fastss.csg.uzh.ch/ifi-2007.02.pdf中所述的內容。

就是這樣。

+0

我在哪裏看到的問題是,我的字典不會包含像麥克唐納或格格爾這樣的詞 - 因此不會被認爲是同音詞,對嗎?爲了建立字典,我需要事先知道可能的同音詞。這與自動更正有所不同,因爲我想從Google轉到Gugel而不是Gugel到Google。 – ScientiaEtVeritas

+0

對。您需要提供所有可能的答案才能使用此方法。 – btilly

0
votes
answers
30 views
+10

枚舉n個球的所有可能分佈爲k個盒子

1

我提到的具體問題以及該問題的分佈數量計算爲here。我有興趣明確知道這些分佈。枚舉n個球的所有可能分佈爲k個盒子

例如,有5個球和3個盒子:一個分配是盒子1中的2個球,盒子2中的2個,盒子3中的1個,被稱爲221,現在我想列出所有這些可能的分佈: -

。 。 。

一種方法是,我運行matlab命令:perms([0,0,0,0,0,1,1,1])。這基本上產生了5個球和2支球的所有排列。但由於命令perms無法識別相同的對象,所以存在大量重複計數。

沙发
0
0

很簡單......之類的。

function alloc(balls, boxes): 

    if boxes = 1 
     return [balls] 
    else 
     for n in range 0:balls 
      return alloc(balls-n, boxes-1) 

這是基本的遞歸邏輯:挑選每個可能數量的球,然後重複其餘的球和少一個盒子。

列表粘貼方法將取決於語言;我把它們留給學生練習。

板凳
0
0

可以使用unique()通過perms()擺脫產生相同的列:

A = unique(perms([0,0,0,0,0,1,1,1]), 'rows'); 
% `A` will contain all combinations, not permutations, of [0,0,0,0,0,1,1,1] 
0
votes
answers
49 views
+10

復發T(n)= T(n - log(n))+ 1

0

你如何找到這樣的遞推關係的嚴格界限?這是一個重要的問題,我們期望證明m/log(m)是嚴格的漸近界。我嘗試使用感應,但它似乎無處可去。這是要麼我缺少對數規則或有更多的東西。復發T(n)= T(n - log(n))+ 1

+0

告訴我們你如何開始歸納,也許有人可以從那裏幫助你。 – ShadowMitia

沙发
0
1

感應。假設所有k < nT(k) <= C k/log k對於某些C

展開復發(n/2)/log(n/2)次,更換log(.)log(n/2)(我們利用的事實,即T(n)log(n)是單調函數)。也就是說,

T(n) <= T(n - log(n/2) * (n/2)/log(n/2)) + (n/2)/log(n/2)

T(n) <= T(n/2) + (n/2)/log(n/2)

T(n) <= C (n/2)/log(n/2) + (n/2)/log(n/2)

現在你要證明右邊的表達被C n/log n界。算術和找到這樣的C是作爲一個練習。

+0

我不同意。我認爲解決方案的形式應該是: '(n-log(n))/(log(n-log(n)))' – ugar

+0

@nomadov它取決於你需要的近似程度。 –

+0

如何展開次數?(n/2)/ log(n/2)次?我不明白你是如何得到T(n)<= T(n-log(n/2)*(n/2)/ log(n/2))+(n/2)/ log(n/2 )' – ugar