題目:用零知識證明實現地圖的三染色問題(用三種顏色染色一個地圖,保證任意兩個相鄰的地區都是不同的顏色)。
編程驗證下述的設計思路,采用Python和C語言編寫均可。
條件:假設一個交互協議有證明者Alice和驗證者Bob。Alice手里有一個地圖三染色的答案(請見下圖),這個圖總共有6個頂點和6條邊。現在Alice想證明給Bob她有答案,但是又不想讓Bob知道這個答案。請用零知識證明的思想設計實驗並驗證至少20次的結果。

測試數據:
1)邊集:(1, 2), (1, 4), (1, 3), (2, 5), (3, 6), (5, 6)
顏色集:(1: 0, 2: 1, 3: 2, 4: 1, 5: 2, 6: 0)
2)邊集:(1, 2), (1, 4), (1, 3), (2, 3), (2, 5), (2, 6), (3, 4), (3, 6), (5, 6)
顏色集:(1: 0, 2: 1, 3: 2, 4: 1, 5: 2, 6: 0)
3)邊集:(1, 2), (1, 4), (1, 3), (2, 3), (2, 5), (2, 6), (3, 4), (3, 6), (5, 6)
顏色集:(1: 0, 2: 1, 3: 1, 4: 2, 5: 2, 6: 0)
思路:
1)Alice 先要對染過色的圖進行一些變換,把顏色做一次全改,例如把所有的綠色變成橙色,把所有的黃色變成藍色,把所有的紅色變成粉色。然后 Alice 得到了一個新的染色答案,這時候她把新的圖的每一個頂點都用紙片蓋上,然后出示給 Bob 看。
2)Bob要隨機挑選一條邊,並由Alice揭開這條邊兩端的紙片,讓Bob檢查,Bob發現這兩個頂點的顏色是不同的,那么Bob認為這次檢驗同構。
經過多次驗證,可以證明Bob認為這個圖滿足三染色的要求。
我的想法
用color0,color1,color2代表圖上三種不同的顏色
這里我采用了python的networkx庫來進行圖的生成繪制以及相關圖屬性的修改
先構造一個空的無向圖,依次將結點123456添加進去
*注意*這里的123456為結點的編號,但是,networkx構造圖結點真正的序號是從0開始的!
輸入n值,即選擇三組測試數據中的一組展開實驗
根據選擇的n值,導入相應的屬性(邊的連通性,結點顏色列表)
畫出原始圖型
隨機生成顏色的函數randomColor(這個函數在網上找的)
顏色有三種表示方法:str類型的字符串:red、RGB表示法:(0,255,255)
以及我采用的16進制表示法:以“#”開頭表示,例如“#FFFFFF”或“#FFF”
此時,用randomColor更新結點顏色列表colors
輸出無色圖(此時每個結點的顏色已經更新了!只是沒有顯示)
輸入要查看的結點序號(這就是為什么開始時說真實的結點序號要比標號小1)
輸出這兩個結點的顏色(直接再colors列表中索引即可)
輸出新的顏色圖
重復上述操作
代碼
import random
import matplotlib.pyplot as plt
import networkx as nx
import numpy as np
#初始化結點顏色
color0='red'
color1='yellow'
color2='green'
#構造空的無向圖
graph= nx.Graph()
#添加結點
node_list = [1,2,3,4,5,6]
for i in range(0,5):
graph.add_node(node_list[i])
#添加測試數據的邊與顏色
n = str(input('請選擇圖a,圖b,圖c'))
if n=='a':
edge_list=[(1, 2), (1, 4), (1, 3), (2, 5), (3, 6), (5, 6)]
colors=[color0,color1,color2,color1,color2,color0]
elif n=='b':
edge_list = [(1, 2), (1, 4), (1, 3), (2, 3), (2, 5), (2, 6), (3, 4), (3, 6), (5, 6)]
colors=[color0,color1,color2,color1,color2,color0]
elif n=='c':
edge_list=[(1, 2), (1, 4), (1, 3), (2, 3), (2, 5), (2, 6), (3, 4), (3, 6), (5, 6)]
colors=[color0, color1, color1, color2, color2, color0]
graph.add_edges_from(edge_list)
#畫原始圖形
nx.draw(graph, pos=nx.spring_layout(graph), with_labels=True, font_size=20, node_size=500, node_color=colors)
plt.show()
#隨機生成顏色函數
def randomcolor():
colorArr = ['1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']
color = ""
for i in range(6):
color += colorArr[random.randint(0,14)]
return "#"+color
#修改顏色
def changeColor():
color0=randomcolor()
color1=randomcolor()
color2=randomcolor()
if n == 'a':
colors = [color0, color1, color2, 