def calcFitness(thing, maxDim, value=None): '''Calculate the fitness of a thing based on it's current location, the view size, and the other things that exist within that range. Use EuclideanDistance to determine intra-thing similarity. Several conditions exist where we want to punish so fitness is bottomed to 0.''' global inputs global inputLocations global maxDimensions fitness = 0 testing = copy.deepcopy(thing.location) for i in range(-maxDim, maxDim + 1): for j in range(-maxDim, maxDim + 1): testing[0] = int((thing.location[0] + i) % (maxDimensions + 1)) testing[1] = int((thing.location[1] + j) % (maxDimensions + 1)) if testing in inputLocations and value == None: testFit = 1 - ((PSO.EuclideanDistance( inputs[inputLocations.index(testing)], inputs[inputLocations.index(thing.location)])) / thing.activity) if testFit <= 0: # If we ever go negative, bail return 0 else: fitness += testFit elif testing in inputLocations and value != None: testFit = 1 - \ ((PSO.EuclideanDistance( inputs[inputLocations.index(testing)], value)) / thing.activity) if testFit <= 0: # If we ever go negative, bail return 0 else: fitness += testFit #fitness = (1 / 2) * fitness if fitness <= 0: # If the final sum is negative return 0 else: return fitness
def getClusters(inputs, centroids, k): '''Find closest cluster to each centroid via euclidean distance''' chosenCluster = 0 for i in range(k): centroids[i][1:] = [] for i in range(len(inputs)): chosenCluster = 0 euclidean = PSO.EuclideanDistance(inputs[i], centroids[0][0]) for j in range(k): tempEuc = PSO.EuclideanDistance(inputs[i], centroids[j][0]) if tempEuc < euclidean: euclidean = tempEuc #PSO.EuclideanDistance(inputs[i], centroids[j][0]) chosenCluster = j centroids[chosenCluster].append(inputs[i]) return centroids
def compLearn(inputs, numHNodes, iterations, learnRate): clusters = [] cluster_num = 0 final_clusters = [] inputs_copy = [] # normalize inputs minIn = 10000 maxIn = 0 for x in inputs: for y in x: minIn = min(minIn, y) maxIn = max(maxIn, y) inputs_copy = PSO.rescaleMatrix(inputs, minIn, maxIn, 0, 1) clusters = competitiveLearn(inputs_copy, numHNodes, iterations, learnRate) for c in range(len(clusters)): final_clusters.append([]) # calculate distance to get which cluster center the inputs lie in dist = 10000 for i in range(len(inputs_copy)): for j in range(len(clusters)): tmpDist = PSO.EuclideanDistance(clusters[j], inputs_copy[i]) if tmpDist < dist: dist = tmpDist cluster_num = j dist = 10000 final_clusters[cluster_num].append(inputs[i]) #print("Clusters: ") #for i in range(len(final_clusters)): # print(clusters[i], final_clusters[i]) return [x for x in final_clusters if x != []]
def seperation(cluster1, cluster2): # calc the difference for every element in cluster1 to every element # in cluster2 and sum. # We want to maximize this value sep = 0 for p1 in cluster1: for p2 in cluster2: sep += PSO.EuclideanDistance(p1, p2) return sep
def cohesian(cluster): # Compare the intra distance of the cluster for all points and divide # by the number of instances in the cluster # We want to minimize this value coh = 0 for p1 in cluster: for p2 in cluster: if p1 != p2: coh += PSO.EuclideanDistance(p1, p2) return coh / len(cluster)
def competitiveLearn(inputs, numHNodes, iterations, learnRate): index = 0 nodes = [] winner = [] weights = [] wcount = 0 tmp_wt = [] minWt = 10000 maxWt = 0 # randomly assign numHNodes input vectors to be the weights for i in range(numHNodes): weights.append(random.choice(inputs)) for i in range(iterations): print("{:>7.2%}".format(i / iterations), end="\r") # randomly select an input vector for comparison selectedInput = random.choice(inputs) # calculate a starting point for the winner winner = PSO.EuclideanDistance(weights[0], selectedInput) # find the winning weight vector index = 0 for w in weights: tmp_w = w temp = PSO.EuclideanDistance(tmp_w, selectedInput) if winner >= temp: # want the shortest distance winner = temp index = weights.index(w) # winning index # update the weight at the winning index dist = PSO.EuclideanDistance(selectedInput, weights[index]) for j in range(len(weights[index])): weights[index][j] += learnRate * (dist) # renormalize weights for x in weights: for y in x: minWt = min(minWt, y) maxWt = max(maxWt, y) weights = PSO.rescaleMatrix(weights, minWt, maxWt, 0, 1) # weights are now the cluster centers return weights
def die(self): '''Once the ant has reached the end of it's life, we give it a chance to be enlightened. The ant will explore all locations on the grid systematical and determine the best location for the currently held block. Once this is determined, it is placed there.''' global inputs global maxDimensions global inputLocations bestFit = 0 bestLoc = [] if self.heldValue != None: # We have a location that is obvously better for i in range(maxDimensions + 1): for j in range(maxDimensions + 1): testLoc = [i, j] if testLoc not in inputLocations: self.location = testLoc fitness = calcFitness(self, 1, self.heldValue) #print(bestFit, fitness) if fitness > bestFit: bestFit = fitness bestLoc = [i, j] # We need to look for the best place now that an obvious one doesn't exist if bestFit == 0: bestFit = 1000 for i in range(maxDimensions + 1): for j in range(maxDimensions + 1): testLoc = [i, j] if testLoc not in inputLocations: diff = 0 for k in range(-5, 6): for l in range(-5, 6): testPos = copy.deepcopy(testLoc) testPos[0] = int( (testLoc[0] + k) % (maxDimensions + 1)) testPos[1] = int( (testLoc[1] + l) % (maxDimensions + 1)) if testPos in inputLocations: diff += PSO.EuclideanDistance( self.heldValue, inputs[ inputLocations.index(testPos)]) if diff < bestFit: bestFit = diff bestLoc = [i, j] #print(self, 'DROP @\t', bestLoc, ' \t<=', self.heldValue) inputs.append(copy.deepcopy(self.heldValue)) inputLocations.append(copy.deepcopy(bestLoc)) self.heldValue = None self.heldDensity = None