org.apache.sysml.runtime.compress.PlanningBinPacker.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.sysml.runtime.compress.PlanningBinPacker.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.sysml.runtime.compress;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.math3.random.RandomDataGenerator;

/**
 * Used for the finding columns to co-code
 * 
 */
public class PlanningBinPacker {
    private final float _binWeight;
    private final List<Integer> _items;
    private final List<Float> _itemWeights;

    public PlanningBinPacker(float binWeight, List<Integer> items, List<Float> itemWeights) {
        _binWeight = binWeight;
        _items = items;
        _itemWeights = itemWeights;
    }

    /**
     * NOTE: upper bound is 17/10 OPT
     * 
     * @return key: available space, value: list of the bins that have that free space
     */
    public TreeMap<Float, List<List<Integer>>> packFirstFit() {
        return packFirstFit(_items, _itemWeights);
    }

    /**
     * shuffling the items to make some potential for having bins of different
     * sizes when consecutive columns are of close cardinalities
     * 
     * @return key: available space, value: list of the bins that have that free
     *         space
     */
    public TreeMap<Float, List<List<Integer>>> packFirstFitShuffled() {
        RandomDataGenerator rnd = new RandomDataGenerator();
        int[] permutation = rnd.nextPermutation(_items.size(), _items.size());
        List<Integer> shuffledItems = new ArrayList<Integer>(_items.size());
        List<Float> shuffledWeights = new ArrayList<Float>(_items.size());
        for (int ix : permutation) {
            shuffledItems.add(_items.get(ix));
            shuffledWeights.add(_itemWeights.get(ix));
        }

        return packFirstFit(shuffledItems, shuffledWeights);
    }

    private TreeMap<Float, List<List<Integer>>> packFirstFit(List<Integer> items, List<Float> itemWeights) {
        // when searching for a bin, the first bin in the list is used
        TreeMap<Float, List<List<Integer>>> bins = new TreeMap<Float, List<List<Integer>>>();
        // first bin
        bins.put(_binWeight, createBinList());
        int numItems = items.size();
        for (int i = 0; i < numItems; i++) {
            float itemWeight = itemWeights.get(i);
            Map.Entry<Float, List<List<Integer>>> entry = bins.ceilingEntry(itemWeight);
            if (entry == null) {
                // new bin
                float newBinWeight = _binWeight - itemWeight;
                List<List<Integer>> binList = bins.get(newBinWeight);
                if (binList == null) {
                    bins.put(newBinWeight, createBinList(items.get(i)));
                } else {
                    List<Integer> newBin = new ArrayList<Integer>();
                    newBin.add(items.get(i));
                    binList.add(newBin);
                }
            } else {
                // add to the first bin in the list
                List<Integer> assignedBin = entry.getValue().remove(0);
                assignedBin.add(items.get(i));
                if (entry.getValue().size() == 0)
                    bins.remove(entry.getKey());
                float newBinWeight = entry.getKey() - itemWeight;
                List<List<Integer>> newBinsList = bins.get(newBinWeight);
                if (newBinsList == null) {
                    // new bin
                    bins.put(newBinWeight, createBinList(assignedBin));
                } else {
                    newBinsList.add(assignedBin);
                }
            }
        }
        return bins;
    }

    /**
     * NOTE: upper bound is 11/9 OPT + 6/9 (~1.22 OPT)
     * 
     * @return sorted map of ?
     */
    public TreeMap<Float, List<List<Integer>>> packFirstFitDescending() {
        // sort items descending based on their weights
        Integer[] indexes = new Integer[_items.size()];
        for (int i = 0; i < indexes.length; i++)
            indexes[i] = i;
        Arrays.sort(indexes, new Comparator<Integer>() {

            @Override
            public int compare(Integer o1, Integer o2) {
                return _itemWeights.get(o1).compareTo(_itemWeights.get(o2));
            }
        });
        List<Integer> sortedItems = new ArrayList<Integer>();
        List<Float> sortedItemWeights = new ArrayList<Float>();
        for (int i = indexes.length - 1; i >= 0; i--) {
            sortedItems.add(_items.get(i));
            sortedItemWeights.add(_itemWeights.get(i));
        }
        return packFirstFit(sortedItems, sortedItemWeights);
    }

    /**
     * NOTE: upper bound is 71/60 OPT + 6/9 (~1.18 OPT)
     * 
     * @return sorted map of ?
     */
    public TreeMap<Float, List<List<Integer>>> packModifiedFirstFitDescending() {
        throw new UnsupportedOperationException("Not implemented yet!");
    }

    private List<List<Integer>> createBinList() {
        List<List<Integer>> binList = new ArrayList<List<Integer>>();
        binList.add(new ArrayList<Integer>());
        return binList;
    }

    private List<List<Integer>> createBinList(int item) {
        List<List<Integer>> binList = new ArrayList<List<Integer>>();
        List<Integer> bin = new ArrayList<Integer>();
        binList.add(bin);
        bin.add(item);
        return binList;
    }

    private List<List<Integer>> createBinList(List<Integer> bin) {
        List<List<Integer>> binList = new ArrayList<List<Integer>>();
        binList.add(bin);
        return binList;
    }
}