mase.spec.BasicHybridExchangerDunn.java Source code

Java tutorial

Introduction

Here is the source code for mase.spec.BasicHybridExchangerDunn.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package mase.spec;

import ec.EvolutionState;
import ec.Individual;
import java.util.ArrayList;
import java.util.List;
import mase.evaluation.BehaviourResult;
import org.apache.commons.lang3.tuple.Pair;

/**
 *
 * @author jorge
 */
public class BasicHybridExchangerDunn extends BasicHybridExchanger {
    private static final long serialVersionUID = 1L;

    /* Similar to bottom-up (agglomerative) hierarchical clustering */
    @Override
    protected void mergeProcess(EvolutionState state) {
        List<BehaviourResult>[] mpBehavs = new List[metaPops.size()];
        for (int i = 0; i < metaPops.size(); i++) {
            MetaPopulation mp = metaPops.get(i);
            Individual[] inds = getElitePortion(mp.inds, (int) Math.ceil(elitePortion * popSize));
            mpBehavs[i] = new ArrayList<BehaviourResult>(mp.agents.size() * inds.length);
            for (Individual ind : inds) {
                for (Integer a : mp.agents) {
                    mpBehavs[i].add(getAgentBR(ind, a));
                }
            }
        }
        distanceMatrix = distanceMatrix(mpBehavs, state);
        Pair<MetaPopulation, MetaPopulation> nextMerge = metaPops.size() >= 3 ? findNextMerge(distanceMatrix, state)
                : null;

        // Merge if they are similar
        if (nextMerge != null) {
            state.output.message("*************************** Merging " + nextMerge.getLeft() + " with "
                    + nextMerge.getRight() + " ***************************");
            merges++;
            MetaPopulation mpNew = mergePopulations(nextMerge.getLeft(), nextMerge.getRight(), state);
            metaPops.remove(nextMerge.getLeft());
            metaPops.remove(nextMerge.getRight());
            metaPops.add(mpNew);
        }
    }

    @Override
    protected Pair<MetaPopulation, MetaPopulation> findNextMerge(double[][] distanceMatrix, EvolutionState state) {
        List<BehaviourResult>[] mpBehavs = new List[metaPops.size()];
        for (int i = 0; i < metaPops.size(); i++) {
            MetaPopulation mp = metaPops.get(i);
            Individual[] inds = getElitePortion(mp.inds, (int) Math.ceil(elitePortion * popSize));
            mpBehavs[i] = new ArrayList<BehaviourResult>(mp.agents.size() * inds.length);
            for (Individual ind : inds) {
                for (Integer a : mp.agents) {
                    mpBehavs[i].add(getAgentBR(ind, a));
                }
            }
        }

        double currentDunn = dunnIndex(distanceMatrix);
        System.out.println("Current dunn: " + currentDunn);
        Pair<MetaPopulation, MetaPopulation> next = null;

        for (int i = 0; i < metaPops.size(); i++) {
            for (int j = 0; j < metaPops.size(); j++) {
                MetaPopulation mpi = metaPops.get(i);
                MetaPopulation mpj = metaPops.get(j);
                if (i != j && mpi.age > stabilityTime && mpj.age > stabilityTime) {
                    List<BehaviourResult>[] hypothesis = new List[metaPops.size() - 1];
                    List<BehaviourResult> merged = new ArrayList<BehaviourResult>();
                    merged.addAll(mpBehavs[i]);
                    merged.addAll(mpBehavs[j]);
                    int index = 0;
                    hypothesis[index++] = merged;
                    for (int k = 0; k < mpBehavs.length; k++) {
                        if (k != i && k != j) {
                            hypothesis[index++] = mpBehavs[k];
                        }
                    }
                    double[][] dists = distanceMatrix(hypothesis, state);
                    double dunn = dunnIndex(dists);

                    System.out.println("Hypothesis merge " + mpi + " with " + mpj + ": " + dunn);

                    if (dunn > currentDunn) {
                        currentDunn = dunn;
                        next = Pair.of(mpi, mpj);
                    }
                }
            }
        }
        return next;
    }

    private double dunnIndex(double[][] distances) {
        double maxIntraCluster = Double.NEGATIVE_INFINITY;
        double minInterCluster = Double.POSITIVE_INFINITY;
        for (int i = 0; i < distances.length; i++) {
            maxIntraCluster = Math.max(distances[i][i], maxIntraCluster);
            for (int j = 0; j < distances.length; j++) {
                if (i != j) {
                    minInterCluster = Math.min(minInterCluster, distances[i][j]);
                }
            }
        }

        return minInterCluster / maxIntraCluster;
    }
}