diff --git a/ganttzk/pom.xml b/ganttzk/pom.xml index d273872c6..bded8822c 100644 --- a/ganttzk/pom.xml +++ b/ganttzk/pom.xml @@ -98,8 +98,8 @@ - commons-math - commons-math + org.apache.commons + commons-math3 joda-time diff --git a/libreplan-business/pom.xml b/libreplan-business/pom.xml index 5d05cad2f..d00cfaa8b 100644 --- a/libreplan-business/pom.xml +++ b/libreplan-business/pom.xml @@ -26,7 +26,7 @@ org.hibernate hibernate-core - + org.hibernate hibernate-ehcache @@ -99,8 +99,8 @@ - commons-math - commons-math + org.apache.commons + commons-math3 org.slf4j diff --git a/libreplan-business/src/main/java/org/libreplan/business/common/ProportionalDistributor.java b/libreplan-business/src/main/java/org/libreplan/business/common/ProportionalDistributor.java index b65582224..b4fc57079 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/common/ProportionalDistributor.java +++ b/libreplan-business/src/main/java/org/libreplan/business/common/ProportionalDistributor.java @@ -24,7 +24,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.apache.commons.math.fraction.Fraction; +import org.apache.commons.math3.fraction.Fraction; /** * @author Óscar González Fernández @@ -32,24 +32,26 @@ import org.apache.commons.math.fraction.Fraction; public class ProportionalDistributor { public static ProportionalDistributor create(int... initialShares) { - return new ProportionalDistributor(toFractions( - sumIntegerParts(initialShares), initialShares)); + return new ProportionalDistributor(toFractions(sumIntegerParts(initialShares), initialShares)); } private static int sumIntegerParts(int[] numbers) { int sum = 0; + for (int each : numbers) { sum += each; } + return sum; } private static Fraction[] toFractions(int initialTotal, int... shares) { Fraction[] result = new Fraction[shares.length]; + for (int i = 0; i < result.length; i++) { - result[i] = initialTotal == 0 ? Fraction.ZERO : new Fraction( - shares[i], initialTotal); + result[i] = initialTotal == 0 ? Fraction.ZERO : new Fraction(shares[i], initialTotal); } + return result; } @@ -57,14 +59,15 @@ public class ProportionalDistributor { * Note: this class has a natural ordering that is inconsistent with equals. * */ - private static class FractionWithPosition implements - Comparable { + private static class FractionWithPosition implements Comparable { public static List transform(Fraction[] fractions) { - List result = new ArrayList(); + List result = new ArrayList<>(); + for (int i = 0; i < fractions.length; i++) { result.add(new FractionWithPosition(i, fractions[i])); } + return result; } @@ -90,49 +93,56 @@ public class ProportionalDistributor { } public int[] distribute(final int total) { - if (fractions.length == 0) { + if ( fractions.length == 0 ) { return new int[0]; } + int[] result = new int[fractions.length]; int remaining = total - assignIntegerParts(total, result); - if (remaining == 0) { + + if ( remaining == 0 ) { return result; } + Fraction[] currentFractions = toFractions(total, result); assignRemaining(result, currentFractions, remaining); + return result; } private int assignIntegerParts(int current, int[] result) { Fraction currentAsFraction = new Fraction(current, 1); int substract = 0; + for (int i = 0; i < fractions.length; i++) { int intValue = fractions[i].multiply(currentAsFraction).intValue(); - if (intValue > 0) { + + if ( intValue > 0 ) { result[i] = result[i] + intValue; substract += intValue; } } + return substract; } - private void assignRemaining(int[] result, Fraction[] currentProportions, - int remaining) { - List transform = FractionWithPosition - .transform(difference(currentProportions)); + private void assignRemaining(int[] result, Fraction[] currentProportions, int remaining) { + List transform = FractionWithPosition.transform(difference(currentProportions)); Collections.sort(transform, Collections.reverseOrder()); + for (int i = 0; i < remaining; i++) { - FractionWithPosition proportionWithPosition = transform.get(i - % currentProportions.length); + FractionWithPosition proportionWithPosition = transform.get(i % currentProportions.length); result[proportionWithPosition.position] = result[proportionWithPosition.position] + 1; } } private Fraction[] difference(Fraction[] pr) { Fraction[] result = new Fraction[fractions.length]; + for (int i = 0; i < result.length; i++) { result[i] = fractions[i].subtract(pr[i]); } + return result; } diff --git a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/StretchesFunctionTypeEnum.java b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/StretchesFunctionTypeEnum.java index b2dbd31fd..05b0697e1 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/planner/entities/StretchesFunctionTypeEnum.java +++ b/libreplan-business/src/main/java/org/libreplan/business/planner/entities/StretchesFunctionTypeEnum.java @@ -26,9 +26,8 @@ import java.util.List; import org.apache.commons.lang.Validate; import org.apache.commons.logging.LogFactory; -import org.apache.commons.math.FunctionEvaluationException; -import org.apache.commons.math.analysis.SplineInterpolator; -import org.apache.commons.math.analysis.UnivariateRealFunction; +import org.apache.commons.math3.analysis.interpolation.SplineInterpolator; +import org.apache.commons.math3.analysis.UnivariateFunction; import org.joda.time.Days; import org.joda.time.LocalDate; import org.libreplan.business.common.ProportionalDistributor; @@ -47,32 +46,30 @@ public enum StretchesFunctionTypeEnum { @Override public void apply(ResourceAllocation allocation, - List intervalsDefinedByStreches, - LocalDate startInclusive, LocalDate endExclusive, - int totalHours) { - Interval.apply(allocation, intervalsDefinedByStreches, - startInclusive, endExclusive, totalHours); + List intervalsDefinedByStreches, + LocalDate startInclusive, LocalDate endExclusive, + int totalHours) { + Interval.apply(allocation, intervalsDefinedByStreches, startInclusive, endExclusive, totalHours); } }, INTERPOLATED { @Override public void apply(ResourceAllocation allocation, - List intervalsDefinedByStreches, - LocalDate startInclusive, LocalDate endExclusive, - int totalHours) { + List intervalsDefinedByStreches, + LocalDate startInclusive, LocalDate endExclusive, + int totalHours) { final Task task = allocation.getTask(); - double[] x = Interval.getDayPointsFor(task.getStartAsLocalDate(), - intervalsDefinedByStreches); + double[] x = Interval.getDayPointsFor(task.getStartAsLocalDate(), intervalsDefinedByStreches); assert x.length == 1 + intervalsDefinedByStreches.size(); - double[] y = Interval.getHoursPointsFor(totalHours, - intervalsDefinedByStreches); + + double[] y = Interval.getHoursPointsFor(totalHours, intervalsDefinedByStreches); assert y.length == 1 + intervalsDefinedByStreches.size(); - int[] hoursForEachDay = hoursForEachDayUsingSplines(x, y, - startInclusive, endExclusive); + + int[] hoursForEachDay = hoursForEachDayUsingSplines(x, y, startInclusive, endExclusive); Days daysBetween = Days.daysBetween(startInclusive, endExclusive); assert hoursForEachDay.length == daysBetween.getDays(); @@ -84,10 +81,9 @@ public enum StretchesFunctionTypeEnum { // hours for each day specified by the interpolation. The remainder // must be distributed. int[] assignedHours = getAssignedHours(allocation, startInclusive, newEndDate); - int[] remindingHours = distributeRemainder(allocation, startInclusive, totalHours, assignedHours); + int[] remindingHours = distributeRemainder(totalHours, assignedHours); int[] hoursToAllocate = sum(assignedHours, remindingHours); - allocateDaysFrom(allocation, asEffortDuration(hoursToAllocate), - startInclusive); + allocateDaysFrom(allocation, asEffortDuration(hoursToAllocate), startInclusive); assignedHours = getAssignedHours(allocation, startInclusive, newEndDate); Validate.isTrue(sum(assignedHours) == totalHours); @@ -98,132 +94,143 @@ public enum StretchesFunctionTypeEnum { for (int i = 0; i < assignedHours.length; i++) { assignedHours[i] += remindingHours[i]; } + return assignedHours; } private int[] getAssignedHours(ResourceAllocation allocation, - LocalDate startInclusive, LocalDate endExclusive) { + LocalDate startInclusive, + LocalDate endExclusive) { final Days daysBetween = Days.daysBetween(startInclusive, endExclusive); int[] result = new int[daysBetween.getDays()]; LocalDate day = new LocalDate(startInclusive); int i = 0; + while (day.isBefore(endExclusive)) { result[i++] = allocation.getAssignedHours(day, day.plusDays(1)); day = day.plusDays(1); } + return result; } private void allocateDaysFrom(ResourceAllocation allocation, - List hoursToAllocate, LocalDate startInclusive) { + List hoursToAllocate, + LocalDate startInclusive) { + final LocalDate endExclusive = startInclusive.plusDays(hoursToAllocate.size()); - LOG.debug(String.format("allocate on interval (%s, %s): %s", startInclusive, endExclusive, hoursToAllocate)); - allocation.withPreviousAssociatedResources().onInterval( - startInclusive, endExclusive).allocate(hoursToAllocate); + + LOG.debug(String.format("allocate on interval (%s, %s): %s", + startInclusive, endExclusive, hoursToAllocate)); + + allocation.withPreviousAssociatedResources() + .onInterval(startInclusive, endExclusive).allocate(hoursToAllocate); } private List asEffortDuration(int[] hoursPerDay) { - List result = new ArrayList(); + List result = new ArrayList<>(); + for (int hours: hoursPerDay) { result.add(EffortDuration.hours(hours)); } + return result; } - private int[] distributeRemainder(ResourceAllocation allocation, - LocalDate startInclusive, int totalHours, - int[] reallyAssigned) { + private int[] distributeRemainder(int totalHours, int[] reallyAssigned) { final int remainder = totalHours - sum(reallyAssigned); - if (remainder == 0) { + + if ( remainder == 0 ) { return new int[reallyAssigned.length]; } + return distributeRemainder(reallyAssigned, remainder); } - private int[] distributeRemainder(int[] hoursForEachDay, - int remainder) { - ProportionalDistributor remainderDistributor = ProportionalDistributor - .create(hoursForEachDay); + private int[] distributeRemainder(int[] hoursForEachDay, int remainder) { + ProportionalDistributor remainderDistributor = ProportionalDistributor.create(hoursForEachDay); + return remainderDistributor.distribute(remainder); } private int sum(int[] array) { int result = 0; + for (int each : array) { result += each; } + return result; } private LocalDate lastDayAssignment(ResourceAllocation allocation) { List assignments = (List) allocation.getAssignments(); DayAssignment last = assignments.get(assignments.size() - 1); + return last.getDay(); } }; - private static final org.apache.commons.logging.Log LOG = LogFactory - .getLog(StretchesFunctionTypeEnum.class); + private static final org.apache.commons.logging.Log LOG = LogFactory.getLog(StretchesFunctionTypeEnum.class); - public static int[] hoursForEachDayUsingSplines(double[] x, double[] y, - LocalDate startInclusive, LocalDate endExclusive) { - UnivariateRealFunction accumulatingFunction = new SplineInterpolator() - .interpolate(x, y); - int[] extractAccumulated = extractAccumulated(accumulatingFunction, - startInclusive, endExclusive); - return extractHoursShouldAssignForEachDay(ValleyFiller - .fillValley(extractAccumulated)); + public static int[] hoursForEachDayUsingSplines(double[] x, + double[] y, + LocalDate startInclusive, + LocalDate endExclusive) { + + UnivariateFunction accumulatingFunction = new SplineInterpolator().interpolate(x, y); + int[] extractAccumulated = extractAccumulated(accumulatingFunction, startInclusive, endExclusive); + + return extractHoursShouldAssignForEachDay(ValleyFiller.fillValley(extractAccumulated)); } - private static int[] extractAccumulated( - UnivariateRealFunction accumulatedFunction, - LocalDate startInclusive, LocalDate endExclusive) { - int[] result = new int[Days.daysBetween(startInclusive, - endExclusive).getDays()]; + private static int[] extractAccumulated(UnivariateFunction accumulatedFunction, + LocalDate startInclusive, + LocalDate endExclusive) { + + int[] result = new int[Days.daysBetween(startInclusive, endExclusive).getDays()]; + for (int i = 0; i < result.length; i++) { result[i] = evaluate(accumulatedFunction, i + 1); } + return result; } - private static int[] extractHoursShouldAssignForEachDay( - int[] accumulated) { + private static int[] extractHoursShouldAssignForEachDay(int[] accumulated) { int[] result = new int[accumulated.length]; int previous = 0; + for (int i = 0; i < result.length; i++) { final int current = accumulated[i]; result[i] = current - previous; previous = current; } + return result; } - private static int evaluate(UnivariateRealFunction accumulatedFunction, - int x) { - try { - return (int) accumulatedFunction.value(x); - } catch (FunctionEvaluationException e) { - throw new RuntimeException(e); - } + private static int evaluate(UnivariateFunction accumulatedFunction, int x) { + return (int) accumulatedFunction.value(x); } - public void applyTo(ResourceAllocation resourceAllocation, - StretchesFunction stretchesFunction) { + public void applyTo(ResourceAllocation resourceAllocation, StretchesFunction stretchesFunction) { - List intervals = new ArrayList(); + List intervals = new ArrayList<>(); intervals.addAll(stretchesFunction.getIntervalsDefinedByStreches()); LocalDate startInclusive = resourceAllocation.getFirstNonConsolidatedDate(); - LocalDate endExclusive = resourceAllocation.getIntraDayEndDate() - .asExclusiveEnd(); + LocalDate endExclusive = resourceAllocation.getIntraDayEndDate().asExclusiveEnd(); int totalHours = resourceAllocation.getNonConsolidatedHours(); apply(resourceAllocation, intervals, startInclusive, endExclusive, totalHours); } protected abstract void apply(ResourceAllocation allocation, - List intervalsDefinedByStreches, - LocalDate startInclusive, LocalDate endExclusive, int totalHours); + List intervalsDefinedByStreches, + LocalDate startInclusive, + LocalDate endExclusive, + int totalHours); } diff --git a/pom.xml b/pom.xml index e087ff0e8..e117f8563 100644 --- a/pom.xml +++ b/pom.xml @@ -397,9 +397,9 @@ - commons-math - commons-math - 1.2 + org.apache.commons + commons-math3 + 3.6.1