2017-11-18 21 views
1

バイナリ文字列を表す可能なノードパスをグラフで検索するアルゴリズムを作成しようとしています。偶数番号のノードは数字「0」に対応し、奇数数字「1」はノード番号に対応する。次のコードは、時間が不安定で最適化されていない時間です。コードのコメントでは、私は彼の行動についていくつかの説明をしました。ツリーグラフパスのバイナリ文字列の表現

import networkx as nx 
import matplotlib.pyplot as plt 
import pandas as pd 

df = pd.read_csv("graph.csv", sep=';', encoding='utf-8') 
df1=df.astype(int) 

g = nx.Graph() 
g = nx.from_pandas_dataframe(df1, 'nodes_1', 'nodes_2') 

plt.show() 
# I load any binary string. 
# Example '01' 
z = input('Write a binary number. \n') 

z1=list(z) 
l1 = df1['nodes_2'].tolist() 

# I add to the list '0', because in df1 ['nodes_2'] the node '0' is missing. 
l1[:0] = [0] 

# I check whether the first digit entered in the input() of the variable 'z' is 0 or 1. 
# And with good values I create a list of 'a'. 
a=[] 

if int(z1[0])==0: 
    for i in l1: 
     if i%2==0: 
      num1 = int(i) 
      a.append(num1) 

elif int(z1[0])==1: 
    for i in l1: 
     if i%2 ==1: 
      num1 = int(i) 
      a.append(num1) 

else: print('...') 

# I am creating 'b' list of neighbors lists for nodes from list 'a'. 
b=[] 
c=[] 

for i in a: 
    c.append(i) 
    x4 = g.neighbors(i) 
    b.append(x4) 

# For neighbors I choose only those that are odd in this case, 
# because the second digit from the entered 'z' is 1, 
# and then I create a list of 'e' matching pairs representing the possible graph paths. 
e=[] 

if int(z1[1])==0: 
    for j in range(len(b)): 
     for k in range(len(b[j])): 
      if b[j][k]%2==0: 
      d = [a[j], b[j][k]] 
      e.append(d) 

elif int(z1[1])==1: 
    for j in range(len(b)): 
     for k in range(len(b[j])): 
      if b[j][k]%2==1: 
       d = [a[j], b[j][k]] 
       e.append(d) 

print (a) 
# Output: 
# [0, 2, 4, 6, 8, 10, 12, 14] 
print (b) 
# Output: 
# [[1, 2], [0, 5, 6], [1, 9, 10], [2, 13, 14], [3], [4], [5], [6]] 
print (e) 
# Output: 
# [[0, 1], [2, 5], [4, 1], [4, 9], [6, 13], [8, 3], [12, 5]] 

CSVデータフォーマット:

nodes_1 nodes_2 
0 0  1 
1 0  2 
2 1  3 
3 1  4 
4 2  5 
5 2  6 
6 3  7 
7 3  8 
8 4  9 
9 4  10 
10 5  11 
11 5  12 
12 6  13 
13 6  14 

現時点で、私は、長いバイナリ文字列で使用するコードを調整する問題があります。上記の例では、2ビットの文字列を使用することしかできないためです。だから私はコードの簡素化とカスタマイズに関するヒントに非常に感謝します。あなたがループに取り除くことができるように

答えて

2

すべてのコードは、私が意味する数行に減らすことができるが、ベクトル化することができ

a = pd.Series([0] + df['nodes_2'][df['nodes_2']%2==0].values.tolist()) 

# Creating series to make use of apply 
b = a.apply(g.neighbors) 

n1e ,n2e = df['nodes_1'] % 2 == 0, df['nodes_2'] % 2 == 0 
n1o ,n2o = df['nodes_1'] % 2 == 1, df['nodes_2'] % 2 == 1 

# Now you want either the nodes_1 be to odd or nodes_2 to be odd but not both, same for even. 
# Use that as a boolean mask for selecting the data 
e = df[~((n1e == n2e) & (n1o == n2o))] 

出力すなわち:

a.values.tolist() 
[0, 2, 4, 6, 8, 10, 12, 14] 

b.values.tolist() 
[[1, 2], [0, 5, 6], [1, 10, 9], [2, 13, 14], [3], [4], [5], [6]] 

e.values.tolist() 
[[0, 1], [1, 4], [2, 5], [3, 8], [4, 9], [5, 12], [6, 13]] 

をあなたはvectroizedコードを取ることができますユーザーが指定したそれぞれの条件(ブール値)の下に置きます。最後に奇数保つとさえ初めすなわち

e = [[i[0],i[1]] if i[0]%2 == 0 else [i[1],i[0]] for i in e ] 
e = pd.DataFrame(e).sort_values(0).values.tolist() 

[[0, 1], [2, 5], [4, 1], [4, 9], [6, 13], [8, 3], [12, 5]] 
+0

リスト「a」と「b」にする条件に基づいて

更新eはスーパーですが、「C」リストが一致しない場合、Iそう思う。リスト 'a'に示されているように、バイナリ文字列に入力された最初の数字は偶数であるため、隣人も同意します。 –

+0

しかし、バイナリ文字列の2番目の数字が '0'であるとします。そのため、リスト "e"では、指定されたペアの2番目の数字が偶数でなければなりません。一方、バイナリ文字列の2番目の数字が '1'の場合、ペアの2番目の数字は奇数でなければなりません。右側の隣人から明らかに選ばれた。 私がひどく思っていない限り) –

+0

「e」を取得した後のOhkは、条件に基づいて値を交換するためにはどうですか?私は更新された答えの助けを意味するのですか?私はまだnetworkxの初心者ですが、私がもっと慣れ親しんだときに解決策をアップデートするでしょう:) – Dark