2016-12-09 12 views
1

ディクショナリのキーの組み合わせを繰り返し処理する良い方法はありますか?Julia - 辞書のキーの組み合わせを繰り返す

私の辞書には、のような値があります:私は何をする必要があるか

[1] => [1,2], [2,3] => [15], [3] => [6,7,8], [4,9,11] => [3], ... 

を、nは、したがって、上記の例のようにFX 3

かもしれない長さ1:nのあるすべてのキーの組み合わせをフェッチ

[[1], [3], [2,3], [[1],[1,2]], [[3],[2,3]], [4,9,11]] 

私はちょうど鍵を集めることができると知っていますが、私の辞書はかなり大きく、私はそれはめちゃくちゃときn > 3スワップを開始しているため、アルゴリズム全体を再設計ひどく

TL効率を低下させる途中、DR辞書を-ing collectずに辞書からcombinatoricイテレータを作成する方法はありますか?

答えて

1

以下は、辞書を通過する際のビットを最小化しようとする単純な実装です。さらに、OrderedDictを使用するので、キー索引を保持することは意味があります(Dictsは毎回一貫性のあるキーの繰り返しを意味し、したがって重要なキー索引付けを約束しないため)。

using Iterators 
using DataStructures 

od = OrderedDict([1] => [1,2], [2,3] => [15], [3] => [6,7,8], [4,9,11] => [3]) 

sv = map(length,keys(od))  # store length of keys for quicker calculations 
maxmaxlen = sum(sv)    # maximum total elements in good key 
for maxlen=1:maxmaxlen   # replace maxmaxlen with lower value if too slow 
    @show maxlen 
    gsets = Vector{Vector{Int}}() # hold good sets of key _indices_ 
    for curlen=1:maxlen 
    foreach(x->push!(gsets,x), 
    (x for x in subsets(collect(1:n),curlen) if sum(sv[x])==maxlen)) 
    end 
    # indmatrix is necessary to run through keys once in next loop 
    indmatrix = zeros(Bool,length(od),length(gsets)) 
    for i=1:length(gsets)    for e in gsets[i] 
     indmatrix[e,i] = true 
    end 
    end 
    # gkeys is the vector of vecotrs of keys i.e. what we wanted to calculate 
    gkeys = [Vector{Vector{Int}}() for i=1:length(gsets)] 
    for (i,k) in enumerate(keys(od)) 
    for j=1:length(gsets) 
     if indmatrix[i,j] 
     push!(gkeys[j],k) 
     end 
    end 
    end 
    # do something with each set of good keys 
    foreach(x->println(x),gkeys) 
end 

これは現在のものより効率的ですか?また、コードを関数に入れたり、Juliaタスクに変換して、各反復を設定する次のキーを生成する方がよいでしょう。

--- --- UPDATE https://stackoverflow.com/a/41074729/3580870

改善イテレータ-ifiedバージョンのタスクからのイテレータについての回答を使用して

がある:

今、すべてkeysubsetsを反復処理できます
function keysubsets(n,d) 
    Task() do 
    od = OrderedDict(d) 
    sv = map(length,keys(od))  # store length of keys for quicker calculations 
    maxmaxlen = sum(sv)    # maximum total elements in good key 
    for maxlen=1:min(n,maxmaxlen) # replace maxmaxlen with lower value if too slow 
     gsets = Vector{Vector{Int}}() # hold good sets of key _indices_ 
     for curlen=1:maxlen 
     foreach(x->push!(gsets,x),(x for x in subsets(collect(1:n),curlen) if sum(sv[x])==maxlen)) 
     end 
     # indmatrix is necessary to run through keys once in next loop 
     indmatrix = zeros(Bool,length(od),length(gsets)) 
     for i=1:length(gsets)    for e in gsets[i] 
      indmatrix[e,i] = true 
     end 
     end 
     # gkeys is the vector of vecotrs of keys i.e. what we wanted to calculate 
     gkeys = [Vector{Vector{Int}}() for i=1:length(gsets)] 
     for (i,k) in enumerate(keys(od)) 
     for j=1:length(gsets) 
      if indmatrix[i,j] 
      push!(gkeys[j],k) 
      end 
     end 
     end 
     # do something with each set of good keys 
     foreach(x->produce(x),gkeys) 
    end 
    end 
end 

(StackOverflowの他の回答からコードを実行した後で)このようにしてサイズ4を組み合わせると、次のようになります。

julia> nt2 = NewTask(keysubsets(4,od)) 
julia> collect(nt2) 
10-element Array{Array{Array{Int64,1},1},1}: 
Array{Int64,1}[[1]]   
Array{Int64,1}[[3]]   
Array{Int64,1}[[2,3]]   
Array{Int64,1}[[1],[3]]  
Array{Int64,1}[[4,9,11]]  
Array{Int64,1}[[1],[2,3]]  
Array{Int64,1}[[2,3],[3]]  
Array{Int64,1}[[1],[4,9,11]] 
Array{Int64,1}[[3],[4,9,11]] 
Array{Int64,1}[[1],[2,3],[3]] 

(リンクされたStackOverflow回答からのNewTaskの定義が必要です)。

+0

あなたはman dan getzです! – isebarn

関連する問題