src/main/java/com/mobiquityinc/packer/Packer.java
private static List<Integer> solveUnboundedKnapsackProblem(int capacity, List<Thing> things) {
        if (things.isEmpty() || capacity == 0) {
            return Collections.emptyList();
        }
        int factor = calculateFactor(things);
        //to send a package which weights less in case there is more than one package with the
        //same price, we need to group them by cost and sort by weight.
        things.sort(Comparator.comparingInt(Thing::getCost).thenComparing(Thing::getWeight));
        List<Integer> items = new ArrayList<>();
        capacity = capacity * factor;
        int[][] matrix = new int[things.size() + 1][capacity + 1];
        for (int i = 0; i <= things.size(); i++) {
            for (int j = 0; j <= capacity; j++) {
                if (i == 0 || j == 0) {
                    matrix[i][j] = 0;
                } else {
                    Thing thing = things.get(i - 1);
                    if (thing.getWeight() * factor <= j) {
                        matrix[i][j] = Math.max(thing.getCost() +
                            matrix[i - 1][j - (int) (thing.getWeight() * factor)], matrix[i - 1][j]);
                    } else {
                        matrix[i][j] = matrix[i - 1][j];
                    }
                }
            }
        }
        int result = matrix[things.size()][capacity];
        for (int i = things.size(); i > 0 && result > 0; i--) {
            if (result != matrix[i - 1][capacity]) {
                items.add(things.get(i - 1).getIndex());
                result = result - things.get(i - 1).getCost();
                capacity = capacity - (int) things.get(i - 1).getWeight();
            }
        }
        return items;
    }
/**
     * The algorithm determines which things to put into the package so that the
     * total weight is less than or equal to the package limit and the total cost
     * is as large as possible.
     * In case there is more than one thing with the same price it would choose
     * the thing which weights less.
     * @param capacity weight limit of package.
     * @param things the list of all things for the package.
     * @return the list of things' indexes need to be chosen.
     */
The algorithm determines which things to put into the package so that the
total weight is less than or equal to the package limit and the total cost
is as large as possible.
In case there is more than one thing with the same price it would choose
the thing which weights less.
@param capacity weight limit of package.
@param things the list of all things for the package.
@return the list of things' indexes need to be chosen.
The algorithm determines which things to put into the package so that the total weight is less than or equal to the package limit and the total cost is as large as possible . In case there is more than one thing with the same price it would choose the thing which weights less . @param capacity weight limit of package . @param things the list of all things for the package . @return the list of things ' indexes need to be chosen .
private static List<Integer> solveUnboundedKnapsackProblem(int capacity, List<Thing> things) {
        if (things.isEmpty() || capacity == 0) {
            return Collections.emptyList();
        }
        int factor = calculateFactor(things);
        things.sort(Comparator.comparingInt(Thing::getCost).thenComparing(Thing::getWeight));
        List<Integer> items = new ArrayList<>();
        capacity = capacity * factor;
        int[][] matrix = new int[things.size() + 1][capacity + 1];
        for (int i = 0; i <= things.size(); i++) {
            for (int j = 0; j <= capacity; j++) {
                if (i == 0 || j == 0) {
                    matrix[i][j] = 0;
                } else {
                    Thing thing = things.get(i - 1);
                    if (thing.getWeight() * factor <= j) {
                        matrix[i][j] = Math.max(thing.getCost() +
                            matrix[i - 1][j - (int) (thing.getWeight() * factor)], matrix[i - 1][j]);
                    } else {
                        matrix[i][j] = matrix[i - 1][j];
                    }
                }
            }
        }
        int result = matrix[things.size()][capacity];
        for (int i = things.size(); i > 0 && result > 0; i--) {
            if (result != matrix[i - 1][capacity]) {
                items.add(things.get(i - 1).getIndex());
                result = result - things.get(i - 1).getCost();
                capacity = capacity - (int) things.get(i - 1).getWeight();
            }
        }
        return items;
    }
private static List < Integer > solveUnboundedKnapsackProblem ( int capacity , List < Thing > things ) { if ( things . isEmpty ( ) || capacity == 0 ) { return Collections . emptyList ( ) ; } int factor = calculateFactor ( things ) ; things . sort ( Comparator . comparingInt ( Thing :: getCost ) . thenComparing ( Thing :: getWeight ) ) ; List < Integer > items = new ArrayList < > ( ) ; capacity = capacity * factor ; int [ ] [ ] matrix = new int [ things . size ( ) + 1 ] [ capacity + 1 ] ; for ( int i = 0 ; i <= things . size ( ) ; i ++ ) { for ( int j = 0 ; j <= capacity ; j ++ ) { if ( i == 0 || j == 0 ) { matrix [ i ] [ j ] = 0 ; } else { Thing thing = things . get ( i - 1 ) ; if ( thing . getWeight ( ) * factor <= j ) { matrix [ i ] [ j ] = Math . max ( thing . getCost ( ) + matrix [ i - 1 ] [ j - ( int ) ( thing . getWeight ( ) * factor ) ] , matrix [ i - 1 ] [ j ] ) ; } else { matrix [ i ] [ j ] = matrix [ i - 1 ] [ j ] ; } } } } int result = matrix [ things . size ( ) ] [ capacity ] ; for ( int i = things . size ( ) ; i > 0 && result > 0 ; i -- ) { if ( result != matrix [ i - 1 ] [ capacity ] ) { items . add ( things . get ( i - 1 ) . getIndex ( ) ) ; result = result - things . get ( i - 1 ) . getCost ( ) ; capacity = capacity - ( int ) things . get ( i - 1 ) . getWeight ( ) ; } } return items ; }
The algorithm determines which things to put into the package so that the
 total weight is less than or equal to the package limit and the total cost
 is as large as possible.
The algorithm determines which things to put into the package so that the total weight is less than or equal to the package limit and the total cost is as large as possible .
//to send a package which weights less in case there is more than one package with the //same price, we need to group them by cost and sort by weight.