-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclustering.py
159 lines (135 loc) · 4.88 KB
/
clustering.py
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
149
150
151
152
153
154
155
156
157
158
159
import math
import numpy as np
from QuadTree import Point
from QuadTree import Actor
### Assistance Methods ################################################################################
#######################################################################################################
def euclidianDistance(p, q):
"""Distance function in multi-dimensional space"""
sumOfSquares = 0.0
for i in range(len(p)):
sumOfSquares = sumOfSquares + ((p[i]-q[i])*(p[i]-q[i]))
return math.sqrt(sumOfSquares)
def varience(p, q):
"""Combined difference between two vectors"""
var = 0.0
for i in range(len(p)):
var = var + np.fabs(p[i] - q[i])
return var
def standardDeviation(collection):
"""Basid Standard Deviation helps us determine how scattered the patterns are"""
if len(collection) > 0:
average = sum(collection)/len(collection)
squaredDifferences = 0.0
for val in collection:
squaredDifferences = squaredDifferences + (val - average)*(val - average)
meanSquaredDifference = squaredDifferences/len(collection)
standardDeviation = math.sqrt(meanSquaredDifference)
return standardDeviation
return 999999
def averageVarience(packets):
"""Return the neighboring packet most different from all of the its peers"""
varSum = 0.0
for i, p in enumerate(packets):
pVarienceSum = 0.0
for op in packets:
if p is not op:
pVarienceSum = pVarienceSum + varience(p.pattern['p'], op.pattern['p'])
varSum = varSum + (pVarienceSum/len(packets))
return varSum/len(packets)
def addNeighborsToCluster(pattern, cluster):
for p in pattern.close['Packet']:
if not p.hasMembership:
cluster.append(p)
p.hasMembership = True
addNeighborsToCluster(p, cluster)
### Environment Classes ###############################################################################
#######################################################################################################
class Cluster:
clusters = []
outLayers = []
hasClusters = False
def __init__(self, packet):
"""Cluster represents a set of packets stacked 3 or higher, packets in groups smaller than this
are considered outlayers."""
self.packets = []
addNeighborsToCluster(packet, self.packets)
if len(self.packets) > 1:
types = self.types()
print("C " + str(len(Cluster.clusters)) +
": Cnt[" + str(self.count()) +
"] Prc[" + str(self.percentage()) +
"] Var[" + str(self.varience()) +
"] (" + ") (".join(str(k)+":"+str(round(float(len(types[k]))/len(self.packets), 2)) for k in types.keys()) + ")")
Cluster.clusters.append(self)
Cluster.hasClusters = True
else:
Cluster.outLayers.append(self)
def count(self):
return len(self.packets)
def percentage(self):
return round(float(len(self.packets))/len(Packet.packets)*100, 1)
def varience(self):
if len(self.packets) == 0:
return 0.0
return round(averageVarience(self.packets), 2)
def types(self):
t = {}
for packet in self.packets:
if packet.pattern['t'] not in t:
t[packet.pattern['t']] = []
t[packet.pattern['t']].append(packet)
return t
@classmethod
def reset(self):
"""Clean out Cluster and OutLayer data"""
Cluster.clusters = []
Cluster.outLayers = []
Cluster.hasClusters = False
class Packet(Actor):
"""Patterns are moved around our solution space within these Packets which are picked up
and dropped off by passing ants."""
packets = []
baseVarience = 0.0
def __init__(self, pattern, position):
super(self.__class__, self).__init__(position)
# self.setRangeOfVision(3)
Packet.packets.append(self)
self.pattern = pattern
self.inHand = False
self.hasMembership = False
def update(self):
"""Pheromone levels decay over time"""
p = Point(self.position.x, self.position.y)
p.z = sum(self.pattern['p'])
self.moveHistory.append(p)
@classmethod
def clusterStats(self, setName):
"""Every so often we collecte cluster details to see how things are going"""
Cluster.reset()
for p in Packet.packets:
p.setRangeOfVision(3)
avgVarience = 0.0
for p in Packet.packets:
if not p.hasMembership:
c = Cluster(p)
avgVarience = avgVarience + c.varience()
avgVarience = avgVarience/len(Cluster.clusters)
with open('records/'+str(setName)+'.csv', 'a') as file:
file.write(str(len(Packet.packets))+","+str(len(Cluster.clusters))+","+str(len(Cluster.outLayers))+","+str(round(Packet.baseVarience, 4))+","+str(round(avgVarience, 4))+",".join(str(round(c.varience(), 4)) for c in Cluster.clusters)+"\n")
print("OutLayers " + str(len(Cluster.outLayers)))
for p in Packet.packets:
p.hasMembership = False
for p in Packet.packets:
p.setRangeOfVision(0)
def updateClosest(self, actor, doAdd):
if doAdd:
self.close[str(type(actor).__name__)].append(actor)
else:
self.close[str(type(actor).__name__)].remove(actor)
def neighborAdded(self, actor):
"""SuperClass Hooke"""
self.updateClosest(actor, True)
def neighborRemoved(self, actor):
"""SuperClass Hooke"""
self.updateClosest(actor, False)