-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprim2.py
More file actions
148 lines (133 loc) · 3.85 KB
/
prim2.py
File metadata and controls
148 lines (133 loc) · 3.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import numpy as np
import pandas as pd
import math
import random
import matplotlib.pyplot as plt
def mean(numbers):
return float(sum(numbers)) / max(len(numbers), 1)
import collections
from collections import Counter
def mean(numbers):
return float(sum(numbers)) / max(len(numbers), 1)
"""
Constants
"""
large_graph = 4096
max_weight = 0.020971164721624622
num_nodes = 65536
num_trials = 1
dimensions = 2
"""
create_complete_graph(n)
"""
def create_complete_graph(n):
vs = list(range(0, n))
graph = collections.defaultdict(dict)
for u in xrange(0, n):
weights = np.random.random_sample((1,n))[0]
for w in xrange(u+1,n):
if n >= large_graph:
if weights[w] < max_weight:
graph[u][w] = weights[w]
graph[w][u] = weights[w]
else:
graph[u][w] = weights[w]
graph[w][u] = weights[w]
return graph
# for a complete graph, m = O(n^2)
# create a graph, matrix representation
"""
multiple dimensions
"""
def create_complete_graph_dimensional(n, d):
vs = list(range(0, n))
graph = collections.defaultdict(dict)
points = np.random.random_sample((n,d))
for u in xrange(0, n):
for w in xrange(u+1,n):
weight = np.linalg.norm(points[u]-points[w])
if n >= large_graph:
if weight < max_weight:
graph[u][w] = weight
graph[w][u] = weight
else:
graph[u][w] = weight
graph[w][u] = weight
return graph
"""
Delete min dict
input: {s:0}
deletes smallest priority element
"""
def delete_min_dict(H):
v = min(H, key=H.get)
edge_weight = H[v]
del H[v]
return v, edge_weight, H
"""
Prim's algorithm
takes a graph of size n
returns a tree
"""
"""
Prim's algorithm
takes a graph of size n
returns a tree
Look through each edge instead of iterating through all the edges
"""
def prim(graph, n):
# keep
dist= collections.defaultdict(int)
# keep track of previous node for each vertex v
prev = collections.defaultdict(int)
vs = list(range(0, n))
for v in vs:
dist[v] = float("inf")
s = 0
dist[s] = 0
# for now, heap to keep track of what to add is just an array
H = {s:0}
T = {}
edge_weights = []
while H != {}:
v, edge_weight, H = delete_min_dict(H)
T[v] = edge_weight
edge_weights.append(edge_weight)
# loop through all the edges of graph (v,w) not already connected in the current tree
for w in graph[v]:
# only care about edge to w if w not in our T, now can access in constant time to check if in other cut
if w not in T:
weight_vw = graph[v][w]
if dist[w] > weight_vw:
dist[w] = weight_vw
prev[w] = v
# replace later with distance of w
H[w] = dist[w]
return T, sum(edge_weights)
def create_graph(N, dimensions):
if dimensions == 1:
graph = create_complete_graph(N)
print "created graph"
return graph
graph = create_complete_graph_dimensional(N, dimensions)
print "created graph"
return graph
"""
Get stats
"""
def get_average(num_trials, N, dimensions):
maxes = []
weights = []
for i in xrange(0, num_trials):
graph = create_graph(N, dimensions)
T, weight = prim(graph, N)
weights.append(weight)
print ("weight", weight)
max_el = max(T.values())
print ("max_el", max_el)
maxes.append(max_el)
print "finished with graph" + str(i)
return max(maxes), mean(weights)
print ("num_trials", num_trials, "num_nodes", num_nodes, "dimensions", dimensions)
max_of_maxes, mean_weights = get_average(num_trials, num_nodes, dimensions)
print (max_of_maxes, mean_weights)