2011-07-31 21 views
3

の倍数でN個の重みのすべての順列を生成た:
- 重みの属性するN可能な変数を与えられました。
- 可能な限りすべてのウェイトのパーミュテーションを作成します(合計は100%になります)。
- N及びPを反比例される重みは、
R:私は(R IN)関数を作成する必要がP

明らかP(通常1%)の倍数で生じなければならない制約を受ける - すなわちIはN = 7指定することができずP = 0.4。しかし、整数解のみを指定できるようにしたい、すなわちP = 0.01です。

申し訳ありませんこれはよく知られている問題です - 私は数学者ではありません。私が知っている条件を使って検索しましたが、十分近いものは見つかりませんでした。

私は書いたコードを投稿したいと思いますが、それは印象的ではありません。

ありがとうございました!

+0

小さなNとP?私は体重の順列によってあなたが意味することをかなり理解していません。重みに制約がなければ、これらは[0,1]の間の実際の値になる可能性があります。そのような値の集合は無計画です。または、「Pの倍数」は整数倍でなければならないことを意味しますか? – Iterator

+1

アプリケーションを記述することも役立ちます。これは、何らかの制約のもとで整数格子上のすべての点を見つけるように思える。それが標準的なナップザックの問題に還元できるなら、幸運。 – Iterator

+1

とにかくコードを投稿することをお勧めします。 –

答えて

5

重みの順序が重要であると仮定すると、これらはの組成です。それらがなければ、これらはパーティションです。いずれの場合も、Nの呼び出しとなる部品数によって制限されますが、次のコードではnumpartsが使用されます。 0の重みが許されるかどうかという問題もある。

重み付けを1にするには、1/pを整数にする必要があります。これは、次のコードではsumpartsです。それは重みの数に依存しない。コンポジションを作成したら、それをpに掛けることができます。つまり、体重を得るにはnで割ることができます。このような組成物または制限された区画を生成するためには、partitionsパッケージがある。以下のコードは自明である必要があります。行列の各列は重みの集合です。私は7つの重みをとり、p = 0.1または10%を禁止し、0の重みを禁止しました。これは84の可能性を与えます。 0の重み付けは8008の可能性を意味する。 p = 0.01または1%の場合、重みが0でなくても1,120,529,256の可能性があり、それには1,705,904,746があります。注文が問題でない場合はcompositionsの代わりにrestrictedpartsを使用してください。

> library(partitions) 
> numparts <- 7 # number of weights 
> sumparts <- 10 # reciprocal of p 
> weights <- compositions(n=sumparts, m=numparts, include.zero=FALSE)/sumparts 
> weights 

[1,] 0.4 0.3 0.2 0.1 0.3 0.2 0.1 0.2 0.1 0.1 0.3 0.2 0.1 0.2 0.1 0.1 0.2 0.1 0.1 
[2,] 0.1 0.2 0.3 0.4 0.1 0.2 0.3 0.1 0.2 0.1 0.1 0.2 0.3 0.1 0.2 0.1 0.1 0.2 0.1 
[3,] 0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.4 0.1 0.1 0.1 0.2 0.2 0.3 0.1 0.1 0.2 
[4,] 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.2 0.2 0.2 0.3 0.3 0.3 
[5,] 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 
[6,] 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 
[7,] 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 

[1,] 0.1 0.3 0.2 0.1 0.2 0.1 0.1 0.2 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 0.3 0.2 0.1 
[2,] 0.1 0.1 0.2 0.3 0.1 0.2 0.1 0.1 0.2 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 0.2 0.3 
[3,] 0.1 0.1 0.1 0.1 0.2 0.2 0.3 0.1 0.1 0.2 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 0.1 
[4,] 0.4 0.1 0.1 0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.3 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 
[5,] 0.1 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.3 0.3 0.3 0.3 0.4 0.1 0.1 0.1 
[6,] 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.2 0.2 0.2 
[7,] 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 

[1,] 0.2 0.1 0.1 0.2 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 0.1 0.3 
[2,] 0.1 0.2 0.1 0.1 0.2 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 0.1 
[3,] 0.2 0.2 0.3 0.1 0.1 0.2 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 
[4,] 0.1 0.1 0.1 0.2 0.2 0.2 0.3 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 0.2 0.1 0.1 0.1 
[5,] 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.2 0.3 0.1 0.1 0.1 0.1 0.2 0.1 0.1 
[6,] 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.3 0.3 0.3 0.3 0.3 0.4 0.1 
[7,] 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.2 

[1,] 0.2 0.1 0.2 0.1 0.1 0.2 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 
[2,] 0.2 0.3 0.1 0.2 0.1 0.1 0.2 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 0.2 0.1 0.1 0.1 
[3,] 0.1 0.1 0.2 0.2 0.3 0.1 0.1 0.2 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 0.2 0.1 0.1 
[4,] 0.1 0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.3 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 0.2 0.1 
[5,] 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.2 0.3 0.1 0.1 0.1 0.1 0.2 
[6,] 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.2 0.2 
[7,] 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 

[1,] 0.1 0.2 0.1 0.1 0.1 0.1 0.1 0.1 
[2,] 0.1 0.1 0.2 0.1 0.1 0.1 0.1 0.1 
[3,] 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1 
[4,] 0.1 0.1 0.1 0.1 0.2 0.1 0.1 0.1 
[5,] 0.1 0.1 0.1 0.1 0.1 0.2 0.1 0.1 
[6,] 0.3 0.1 0.1 0.1 0.1 0.1 0.2 0.1 
[7,] 0.2 0.3 0.3 0.3 0.3 0.3 0.3 0.4 
+0

こんにちは@Henry、それは完璧に動作します。そしてすぐに!ご協力ありがとうございました。 –

1

EDIT:機能が更新され、結果が2回表示されます。

再帰的計算に基づいてこの機能を試すことができます。注文に関係なく、可能な限りすべての組み合わせが提供されます。私はあなたがそうでなければすべての可能な順列で複数の行を取得するので、このようにしました。

計算は整数に基づいています。最小重みPは1に設定され、Pintは分割可能な重み単位の数になります。 max.Wは1つの変数に与えることができる単位の最大量になります。次のように

アルゴリズムが行く:

  • N = 2の場合には、所定の最小値と最大重みのためのすべての可能な組み合わせを作ります。

  • N> 2の場合、N = 1〜上限(max.weight/N)にこのアルゴリズムを適用し、現在の最大重み+1からNを指定して最大重みをNとし、最小重みをNとして指定します。

これは可能なすべての整数の組み合わせを示します。 Pを乗算すると元の重みが得られます。

または関数で:

myfunc <- function(N,P){ 
    if(100%%(P*100) !=0){ 
    stop("100% cannot be divided in portions of P") 
    } 
    Pint <- 100/(P*100) 
    max.W <- Pint- N + 1 

    combs <- function(n,max.w,min){ 
    mw <- max.w + 1 

    if(n==2){ 

     w <- seq.int(min,floor((mw)/2)) 
     out <- cbind(w,mw-w) 

    } else if (n > 2){ 

     x <- lapply(1:ceiling(max.w/n),function(i){ 

     newcombs <- combs(n-1,mw-i,i) 
     cbind(newcombs,rep(i,nrow(newcombs))) 

     }) 

     out <- do.call("rbind",x) 
    } 
    colnames(out) <-rownames(out) <- NULL 
    out 
    } 
    res <- combs(N,max.W) 
    apply(res,1,sort)*P 
} 

これは、行列の列の組み合わせを提供します:

> Y <- myfunc(3,0.1) 
> Y 
    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] 
[1,] 0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.3 
[2,] 0.1 0.2 0.3 0.4 0.2 0.3 0.4 0.3 
[3,] 0.8 0.7 0.6 0.5 0.6 0.5 0.4 0.4 

は注意して!あなたが与えたテストケース(7変数、0.01のジャンプ)で、あなたは膨大な可能性のために非常に長い時間を計算します。 N = 7、P = 0.04の場合、すでに3555種類の組み合わせがあります。 N = 0.2の場合、その可能性は336,443になります。それがあなたの後にあるならば、あなたはこれらの組み合わせのすべての可能な順列を考慮に入れなければなりません。

+0

いくつかの重複があります:列2&5,3&9,4&12,7&10,8&13、および11&14 – Henry

+0

@Henry:それらを捕まえて、問題を今解決しました。 2番目の通知では、明らかに、すでに簡単な方法で問題を解決しました。まあ、これで遊ぶのが楽しいです。再帰で遊ぶのはいつも楽しいです:-) –