コード例 #1
0
ファイル: MOGOMEA.py プロジェクト: thversfelt/MO-GOMEA
    def clusterPopulation(self):
        """Clusters the given population into k clusters using balanced k-leader-means clustering."""
        # TODO: POSSIBLE CHANGE = CALCULATE OPTIMAL k VALUE

        # The first leader is the solution with maximum value in an arbitrary objective.
        leaders = [self.population[0]]
        for solution in self.population:
            if solution.fitness[0] > leaders[0].fitness[0]:
                leaders[0] = solution

        # The solution with the largest nearest-leader distance is chosen as the next leader,
        # repeated k - 1 times to obtain k leaders.
        for _ in range(self.amountOfClusters - 1):
            nearestLeaderDistance = {}
            for solution in self.population:
                if solution not in leaders:
                    nearestLeaderDistance[solution] = util.euclidianDistance(
                        solution.fitness, leaders[0].fitness)
                    for leader in leaders:
                        leaderDistance = util.euclidianDistance(
                            solution.fitness, leader.fitness)
                        if leaderDistance < nearestLeaderDistance[solution]:
                            nearestLeaderDistance[solution] = leaderDistance
            leader = max(nearestLeaderDistance, key=nearestLeaderDistance.get)
            leaders.append(leader)

        # k-means clustering is performed with k leaders as the initial cluster means.
        clusters = []
        for leader in leaders:
            mean = leader.fitness
            cluster = Cluster(mean, self.problem)
            clusters.append(cluster)

        # Perform k-means clustering until all clusters are unchanged.
        while True in [cluster.changed for cluster in clusters]:
            for solution in self.population:
                nearestCluster = clusters[0]
                nearestClusterDistance = util.euclidianDistance(
                    solution.fitness, nearestCluster.mean)
                for cluster in clusters:
                    clusterDistance = util.euclidianDistance(
                        solution.fitness, cluster.mean)
                    if clusterDistance < nearestClusterDistance:
                        nearestCluster = cluster
                        nearestClusterDistance = clusterDistance
                nearestCluster.append(solution)

            for cluster in clusters:
                cluster.computeMean()
                cluster.clear()

        # Expand the clusters with the closest c solutions.
        c = int(2 / self.amountOfClusters * self.populationSize)
        for cluster in clusters:
            distance = {}
            for solution in self.population:
                distance[solution] = util.euclidianDistance(
                    solution.fitness, cluster.mean)
            for _ in range(c):
                if len(distance) > 0:
                    solution = min(distance, key=distance.get)
                    del distance[solution]
                    cluster.append(solution)
        self.clusters = clusters