@Test public void testPlunder() { LinkedHashMap<Integer, Long> resources = new LinkedHashMap<>(); resources.put(301, RandomUtils.nextLong(1, 88888)); resources.put(302, RandomUtils.nextLong(1, 88888)); resources.put(303, RandomUtils.nextLong(1, 88888)); resources.put(304, RandomUtils.nextLong(1, 88888)); LinkedHashMap<Integer, Integer> r = new LinkedHashMap<>(); r.put(301, 10); r.put(302, 10); r.put(303, 4); r.put(304, 3); long max = RandomUtils.nextLong(10000, 50000); System.out.println("源：" + resources + "----->抢他个" + max); System.out.println("抢：" + MathUtils.plunder(resources, max, r)); System.out.println(); }
public static <T> Map<T, Long> plunder(Map<T, Long> resources, long max, Map<T, Integer> ratio) { final Map<T, Long> result = new HashMap<>(resources.size()); final long step = max / Math.min(1000, Math.max(10, ratio.values().stream().reduce(0, (a, b) -> a + b))); long total = max; while (total > 0) { boolean flag = false; for (Map.Entry<T, Long> e : resources.entrySet()) { if (e.getValue() <= 0) { continue; } flag = true; long selfStep = step * ratio.getOrDefault(e.getKey(), 1) + RandomUtils.nextLong(step); long temp = selfStep > total ? total : selfStep; if (e.getValue() < temp) { temp = e.getValue(); } final long value = temp; e.setValue(e.getValue() - value); total -= temp; result.compute(e.getKey(), (k, v) -> v == null ? value : v.longValue() + value); if (total <= 0) { break; } } if (!flag) { break; } } return result; }
MathUtils { public static <T> Map<T, Long> plunder(Map<T, Long> resources, long max, Map<T, Integer> ratio) { final Map<T, Long> result = new HashMap<>(resources.size()); final long step = max / Math.min(1000, Math.max(10, ratio.values().stream().reduce(0, (a, b) -> a + b))); long total = max; while (total > 0) { boolean flag = false; for (Map.Entry<T, Long> e : resources.entrySet()) { if (e.getValue() <= 0) { continue; } flag = true; long selfStep = step * ratio.getOrDefault(e.getKey(), 1) + RandomUtils.nextLong(step); long temp = selfStep > total ? total : selfStep; if (e.getValue() < temp) { temp = e.getValue(); } final long value = temp; e.setValue(e.getValue() - value); total -= temp; result.compute(e.getKey(), (k, v) -> v == null ? value : v.longValue() + value); if (total <= 0) { break; } } if (!flag) { break; } } return result; } }
MathUtils { public static <T> Map<T, Long> plunder(Map<T, Long> resources, long max, Map<T, Integer> ratio) { final Map<T, Long> result = new HashMap<>(resources.size()); final long step = max / Math.min(1000, Math.max(10, ratio.values().stream().reduce(0, (a, b) -> a + b))); long total = max; while (total > 0) { boolean flag = false; for (Map.Entry<T, Long> e : resources.entrySet()) { if (e.getValue() <= 0) { continue; } flag = true; long selfStep = step * ratio.getOrDefault(e.getKey(), 1) + RandomUtils.nextLong(step); long temp = selfStep > total ? total : selfStep; if (e.getValue() < temp) { temp = e.getValue(); } final long value = temp; e.setValue(e.getValue() - value); total -= temp; result.compute(e.getKey(), (k, v) -> v == null ? value : v.longValue() + value); if (total <= 0) { break; } } if (!flag) { break; } } return result; }  }
MathUtils { public static <T> Map<T, Long> plunder(Map<T, Long> resources, long max, Map<T, Integer> ratio) { final Map<T, Long> result = new HashMap<>(resources.size()); final long step = max / Math.min(1000, Math.max(10, ratio.values().stream().reduce(0, (a, b) -> a + b))); long total = max; while (total > 0) { boolean flag = false; for (Map.Entry<T, Long> e : resources.entrySet()) { if (e.getValue() <= 0) { continue; } flag = true; long selfStep = step * ratio.getOrDefault(e.getKey(), 1) + RandomUtils.nextLong(step); long temp = selfStep > total ? total : selfStep; if (e.getValue() < temp) { temp = e.getValue(); } final long value = temp; e.setValue(e.getValue() - value); total -= temp; result.compute(e.getKey(), (k, v) -> v == null ? value : v.longValue() + value); if (total <= 0) { break; } } if (!flag) { break; } } return result; }  static int addExact(int x, int y); static long addExact(long x, long y); static int multiplyExact(int x, int y); static long multiplyExact(long x, long y); static double distance(int x1, int y1, int x2, int y2); static double distance(double x1, double y1, double x2, double y2); static double distance(Point p1, Point p2); static boolean adjacent(int x1, int y1, int x2, int y2); static boolean adjacent(Point p1, Point p2); static int floorInt(double a); static long floorLong(double a); static int ceilInt(double a); static long ceilLong(double a); static float formatScale(float value, int newScale); static float formatScale(float value, int newScale, RoundingMode mode); static double formatScale(double value, int newScale); static double formatScale(double value, int newScale, RoundingMode mode); static Map<T, Long> plunder(Map<T, Long> resources, long max, Map<T, Integer> ratio); static double longToDouble(long value, double ratio); static double permillage(long value); static double percentage(long value); }
MathUtils { public static <T> Map<T, Long> plunder(Map<T, Long> resources, long max, Map<T, Integer> ratio) { final Map<T, Long> result = new HashMap<>(resources.size()); final long step = max / Math.min(1000, Math.max(10, ratio.values().stream().reduce(0, (a, b) -> a + b))); long total = max; while (total > 0) { boolean flag = false; for (Map.Entry<T, Long> e : resources.entrySet()) { if (e.getValue() <= 0) { continue; } flag = true; long selfStep = step * ratio.getOrDefault(e.getKey(), 1) + RandomUtils.nextLong(step); long temp = selfStep > total ? total : selfStep; if (e.getValue() < temp) { temp = e.getValue(); } final long value = temp; e.setValue(e.getValue() - value); total -= temp; result.compute(e.getKey(), (k, v) -> v == null ? value : v.longValue() + value); if (total <= 0) { break; } } if (!flag) { break; } } return result; }  static int addExact(int x, int y); static long addExact(long x, long y); static int multiplyExact(int x, int y); static long multiplyExact(long x, long y); static double distance(int x1, int y1, int x2, int y2); static double distance(double x1, double y1, double x2, double y2); static double distance(Point p1, Point p2); static boolean adjacent(int x1, int y1, int x2, int y2); static boolean adjacent(Point p1, Point p2); static int floorInt(double a); static long floorLong(double a); static int ceilInt(double a); static long ceilLong(double a); static float formatScale(float value, int newScale); static float formatScale(float value, int newScale, RoundingMode mode); static double formatScale(double value, int newScale); static double formatScale(double value, int newScale, RoundingMode mode); static Map<T, Long> plunder(Map<T, Long> resources, long max, Map<T, Integer> ratio); static double longToDouble(long value, double ratio); static double permillage(long value); static double percentage(long value); static final double ONE; static final double HUNDRED; static final double THOUSAND; static final double TEN_THOUSAND; static final double MILLION; }