/** * Main pick function. If table size is greater then or equal to 16, it will use heuristic * algorithm. * * @param limit maximum value of combinations * @param items object value table * @return solution */ public static <T> Pack<T> pick(Long limit, AbstractMap<T, Long> items) { if (items.size() < 26) { return Pack.binarySearch(limit, items); } else { return Pack.geneticAlgorithm(limit, items); } }
/** * Back-end to pick using BFS. * * @param limit maximum value of combinations * @param items object value table * @return solution */ public static <T> Pack<T> breadthFirstSearch(Long limit, AbstractMap<T, Long> items) { if (Pack.needSearch(limit, items)) { return new Pack<T>(limit, new ArrayList<T>(items.keySet())); } ArrayList<Pack<T>> table = new ArrayList<Pack<T>>(); table.add(new Pack<T>()); for (Entry<T, Long> e : items.entrySet()) { ArrayList<Pack<T>> tmp = new ArrayList<Pack<T>>(); for (Pack<T> p : table) { Long newSize = p.getScore() + e.getValue(); if (newSize <= limit) { ArrayList<T> newDirs = new ArrayList<T>(p.getItems()); newDirs.add(e.getKey()); tmp.add(new Pack<T>(newSize, newDirs)); } } table.addAll(table.size(), tmp); } Pack<T> max = new Pack<T>(); for (Pack<T> p : table) { if (p.getScore() >= max.getScore()) { max = p; } } return max; }
public Pack<T> call(int n, Pack<T> p) { if (p.score_ > this.limit_) { return new Pack<T>(); } else if (n == this.keys_.size()) { return p; } else { Pack<T> a = this.call(n + 1, p); Pack<T> b = this.call(n + 1, p.add(this.keys_.get(n), this.values_.get(n))); if (a.compareTo(b) > 0) { return a; } else { return b; } } }
public Pack<T> call() { while (!this.canStop()) { this.crossOver(); this.mutation(); Collections.sort(this.population_); this.population_.subList(this.table_.size(), this.population_.size()).clear(); } Cell<T> survivor = this.population_.get(0); Pack<T> result = new Pack<T>(survivor.getValue(), new ArrayList<T>()); for (Entry<T, Boolean> e : survivor.getTable().entrySet()) { if (e.getValue()) { result.getItems().add(e.getKey()); } } return result; }
/** * Back-end to pick using heuristic algorithm. The complexity is O(2^n). * * @param limit maximum value of combinations * @param items object value table * @return solution */ public static <T> Pack<T> geneticAlgorithm(Long limit, AbstractMap<T, Long> items) { return (Pack.needSearch(limit, items)) ? new GeneticAlgorithm<T>(limit, items).call() : new Pack<T>(limit, new ArrayList<T>(items.keySet())); }
/** * Back-end to pick using DFS. * * @param limit maximum value of combinations * @param items object value table * @return solution */ public static <T> Pack<T> depthFirstSearch(Long limit, AbstractMap<T, Long> items) { return (Pack.needSearch(limit, items)) ? new DepthFirstSearch<T>(limit, items).call(0, new Pack<T>()) : new Pack<T>(limit, new ArrayList<T>(items.keySet())); }
public static <T> Pack<T> binarySearch(Long limit, AbstractMap<T, Long> items) { return (Pack.needSearch(limit, items)) ? new BinarySearch<T>(limit, items).call() : new Pack<T>(limit, new ArrayList<T>(items.keySet())); }