2016-12-27 17 views
1

我寫了一個KargerMinCut函數,我在Python中編寫了一個隨機函數,但是在同一次運行中我得到了相同的結果。如果我重新啓動該功能,將打印不同的結果。爲什麼我第二次在同一個運行中直接得到相同的結果而沒有在Python中運行隨機函數呢?

下面的代碼

import random 

with open('test.txt') as f: 
    #kargerMinCut 
    #a = [[int(x) for x in ln.split()] for ln in f] 
    data_set = [] 
    for ln in f: 
     line = ln.split() 
     if line: 
      a = [int(x) for x in line] 
      data_set.append(a) 

def choose_random_edge(data): 
    a = random.randint(0,len(data)-1) 
    b = random.randint(1,len(data[a])-1) 
    return a,b 

def compute_nodes(data): 
    data_head = [] 
    for i in xrange(len(data)): 
     data_head.append(data[i][0]) 
    return data_head 

def find_index(data_head,data,u,v): 
    index = data_head.index(data[u][v]) 
    return index 

def replace(data_head,data,index,u): 
    for i in data[index][1:]: 
     index_index = data_head.index(i) 
     for position,value in enumerate(data[index_index]): 
      if value == data[index][0]: 
       data[index_index][position] = data[u][0] 
    return data 

def merge(data): 
    u,v = choose_random_edge(data) 
    print u,v 
    data_head = compute_nodes(data) 
    index = find_index(data_head,data,u,v) 
    data[u].extend(data[index][1:]) 
    #print data 
    data = replace(data_head,data,index,u) 
    #print data 
    data[u][1:] = [x for x in data[u][1:] if x!=data[u][0]] 
    #print data 
    data.remove(data[index]) 
    #print data 
    return data 

def KargerMinCut(data): 
     while len(data) >2: 
      data = merge(data) 
      #print data 
     num = len(data[0][1:]) 
     print num 

#KargerMinCut(data_set) 

這裏的test.txt

1 2 3 4 7 

2 1 3 4 

3 1 2 4 

4 1 2 3 5 

5 4 6 7 8 

6 5 7 8 

7 1 5 6 8 

8 5 6 7 

Editted 2016年12月28日

我已經修改我的代碼在合併更換通過添加輸入數據的本地副本。我不知道我是否正確。

下面的代碼

def replace(data_head,data,index,u): 
    data1 = data 
    for i in data[index][1:]: 
     index_index = data_head.index(i) 
     for position,value in enumerate(data[index_index]): 
      if value == data[index][0]: 
       data1[index_index][position] = data[u][0] 
    return data1 

def merge(data1): 
    data = data1 
    u,v = choose_random_edge(data) 
    #print u,v 
    data_head = compute_nodes(data) 
    index = find_index(data_head,data,u,v) 
    data[u].extend(data[index][1:]) 
    #print data 
    data2 = replace(data_head,data,index,u) 
    #print data 
    data2[u][1:] = [x for x in data2[u][1:] if x!=data2[u][0]] 
    #print data 
    data2.remove(data2[index]) 
    #print data 
    return data2 

但是當我運行merge(data_set)我發現我又改變了輸入。爲什麼,我該怎麼做?有人能給我一些線索嗎?

Here is the output of merge and data_set

通過添加所需輸出圖像

Editted以下是圖像: wanted output

我要循環計算KargerMinCut(data_set)並挑選最小值作爲輸出。 正如你所看到的,當我循環計算KargerMinCut(data_set)我應該得到不同的結果,而不是相同的結果,這是錯誤的。我知道我在撥打KargerMinCut(data_set)時已更改輸入數據,但我不知道如何解決此問題。 問題解決於2017年1月7日 我在頂部使用import copy,在KargerMinCut()的第一行使用data = copy.deepcopy(data)。添加calc_num()函數。 下面是輸出:

calc_number(data_set,20) 
17 
calc_number(data_set,2) 
17 

calc_number(data_set,15) 
20 
calc_number(data_set,15) 
17 

下面的代碼: 進口隨機 進口副本

with open('kargerMinCut.txt') as f: 
    #kargerMinCut 
    #a = [[int(x) for x in ln.split()] for ln in f] 
    data_set = [] 
    for ln in f: 
     line = ln.split() 
     if line: 
      a = [int(x) for x in line] 
      data_set.append(a) 

def choose_random_edge(data): 
    a = random.randint(0,len(data)-1) 
    b = random.randint(1,len(data[a])-1) 
    return a,b 

def compute_nodes(data): 
    data_head = [] 
    for i in xrange(len(data)): 
     data_head.append(data[i][0]) 
    return data_head 

def find_index(data_head,data,u,v): 
    index = data_head.index(data[u][v]) 
    return index 

def replace(data_head,data,index,u): 
    for i in data[index][1:]: 
     index_index = data_head.index(i) 
     for position,value in enumerate(data[index_index]): 
      if value == data[index][0]: 
       data[index_index][position] = data[u][0] 
    return data 

def merge(data): 
    u,v = choose_random_edge(data) 
    #print u,v 
    data_head = compute_nodes(data) 
    index = find_index(data_head,data,u,v) 
    data[u].extend(data[index][1:]) 
    #print data 
    data = replace(data_head,data,index,u) 
    #print data 
    data[u][1:] = [x for x in data[u][1:] if x!=data[u][0]] 
    #print data 
    data.remove(data[index]) 
    #print data 
    return data 

def KargerMinCut(data): 

    data = copy.deepcopy(data) 
    while len(data) >2: 
     data = merge(data) 
     #print data 
    num = len(data[0][1:]) 
    return num 

#KargerMinCut(data_set) 
def calc_number(data,iteration): 
    list = [] 
    for i in xrange(iteration): 
     list.append(KargerMinCut(data)) 
    return min(list) 

回答

1

data_set是列表,列表是可變的。如果您按照以下函數調用:KargerMinCut調用mergemerge調用replacemergereplace都會改變傳遞的列表。

merge變異它在該行

data[u].extend(data[index][1:]) 

replace變異它在該行

data[index_index][position] = data[u][0] 

在一個會議上,第一次調用KargerMinCut(data_set)發生變異data_set,改變輸入到第二個電話號碼是KargerMinCut(data_set)。這就是爲什麼這兩個函數調用的行爲不同。

如果這不是您想要的,您可以通過創建data的本地副本來啓動各個功能mergereplace

+0

科爾曼先生,你真的很幫我。我很感激你在我的問題上的努力。但我不太明白你的意思。我修改了我的「合併」和「替換」功能,並且在輸出中仍然存在一些錯誤。 – SSQ

+0

@SSQ正如我在一個被刪除的評論中說過的(因爲幾分鐘後你不能編輯評論),data = data1的問題是它爲同一個列表創建了一個別名,而不是一個副本。你需要創建*拷貝*和'copy'模塊是一個很好的方法。您可以將所需的複製移至頂層。只留下'merge'和'replace',但作爲'KargerMinCut'中的第一行有'data = copy.deepcopy(data)'行。這將防止對參數'data'進行任何更改(當然,其他錯誤可能會發生)。 –

+0

非常感謝科爾曼先生。有用! – SSQ

0
def KargerMinCut(data): 
while len(data) > 2: #here is the problem 
    data = merge(data) 
    # print data 
num = len(data[0][1:]) 
print num 

問題出現在第二行。

在第二次調用KargerMinCut len(data)> 2時,它只是再次打印相同的num。

+0

謝謝Pio,我發現我改變了輸入數據,但我不想改變輸入數據,我該怎麼辦?你可以幫我嗎? – SSQ

+0

你想要做什麼? – pio

+0

我找出問題所在,謝謝Pio! – SSQ

相關問題