it.units.malelab.ege.ge.mapper.WeightedHierarchicalMapper.java Source code

Java tutorial

Introduction

Here is the source code for it.units.malelab.ege.ge.mapper.WeightedHierarchicalMapper.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 it.units.malelab.ege.ge.mapper;

import com.google.common.collect.Range;
import it.units.malelab.ege.core.Grammar;
import it.units.malelab.ege.ge.genotype.BitsGenotype;
import it.units.malelab.ege.util.Utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author eric
 */
public class WeightedHierarchicalMapper<T> extends HierarchicalMapper<T> {

    protected final Map<T, Integer> weightsMap;
    private final int expressivenessDepth;
    private final boolean weightOptions;
    private final boolean weightChildren;

    public WeightedHierarchicalMapper(int expressivenessDepth, Grammar<T> grammar) {
        this(expressivenessDepth, false, true, grammar);
    }

    public WeightedHierarchicalMapper(int expressivenessDepth, boolean weightOptions, boolean weightChildren,
            Grammar<T> grammar) {
        super(grammar);
        this.expressivenessDepth = expressivenessDepth;
        this.weightOptions = weightOptions;
        this.weightChildren = weightChildren;
        weightsMap = new HashMap<>();
        for (List<List<T>> options : grammar.getRules().values()) {
            for (List<T> option : options) {
                for (T symbol : option) {
                    if (!weightsMap.keySet().contains(symbol)) {
                        weightsMap.put(symbol, countOptions(symbol, 0, expressivenessDepth));
                    }
                }
            }
        }
        for (T symbol : weightsMap.keySet()) {
            int options = weightsMap.get(symbol);
            int bits = (int) Math.ceil(Math.log10(options) / Math.log10(2d));
            weightsMap.put(symbol, bits);
        }
    }

    private int countOptions(T symbol, int level, int maxLevel) {
        List<List<T>> options = grammar.getRules().get(symbol);
        if (options == null) {
            return 1;
        }
        if (level >= maxLevel) {
            return options.size();
        }
        int count = 0;
        for (List<T> option : options) {
            for (T optionSymbol : option) {
                count = count + countOptions(optionSymbol, level + 1, maxLevel);
            }
        }
        return count;
    }

    @Override
    protected List<Range<Integer>> getChildrenSlices(Range<Integer> range, List<T> symbols) {
        if (!weightChildren) {
            return super.getChildrenSlices(range, symbols);
        }
        List<Range<Integer>> ranges;
        if (symbols.size() > (range.upperEndpoint() - range.lowerEndpoint())) {
            ranges = new ArrayList<>(symbols.size());
            for (T symbol : symbols) {
                ranges.add(Range.closedOpen(range.lowerEndpoint(), range.lowerEndpoint()));
            }
        } else {
            List<Integer> sizes = new ArrayList<>(symbols.size());
            int overallWeight = 0;
            for (T symbol : symbols) {
                overallWeight = overallWeight + weightsMap.get(symbol);
            }
            for (T symbol : symbols) {
                sizes.add((int) Math.floor((double) weightsMap.get(symbol) / (double) overallWeight
                        * (double) (range.upperEndpoint() - range.lowerEndpoint())));
            }
            ranges = Utils.slices(range, sizes);
        }
        return ranges;
    }

    @Override
    protected double optionSliceWeigth(BitsGenotype slice) {
        if (!weightOptions) {
            return super.optionSliceWeigth(slice);
        }
        return (double) slice.count();
    }

    @Override
    protected List<Range<Integer>> getOptionSlices(Range<Integer> range, List<List<T>> options) {
        if (!weightOptions) {
            return super.getOptionSlices(range, options);
        }
        List<Integer> sizes = new ArrayList<>(options.size());
        for (List<T> option : options) {
            int w = 1;
            for (T symbol : option) {
                w = w * Math.max(weightsMap.getOrDefault(symbol, 1), 1);
            }
            sizes.add(w);
        }
        return Utils.slices(range, sizes);
    }

    @Override
    public String toString() {
        return "WeightedHierarchicalMapper{" + "maxDepth=" + expressivenessDepth + ", weightOptions="
                + weightOptions + ", weightChildren=" + weightChildren + '}';
    }

}