Java алгоритм разделения времени на убывающие части - PullRequest
0 голосов
/ 06 мая 2020

Я пытаюсь написать метод в Java 7 для распределения времени в списке.

Например:

если requiredConclusionTime - now равно 1.75h и размер моего списка 3, тогда он должен быть распределен следующим образом:

  • item1 получает 1h
  • item2 получает 0.5h
  • item3 получает 0.25h

Как видите, выделение уменьшается вдвое.

Пока что у меня есть следующее:

private void setRequiredConclusionTimes(ApprovalForm approvalForm, Date requiredConclusionTime) {
    long currentTimeInMillies = new Date().getTime();
    long requiredConclusionTimeInMillis = requiredConclusionTime.getTime();
    long diff = requiredConclusionTimeInMillis - currentTimeInMillies;

    List<List<Evaluator>> evaluatorsList = approvalForm.getEvaluatorsList();
    for (Evaluator Evaluator : evaluatorsList.get(0)) {
        GregorianCalendar cal = new GregorianCalendar();
        cal.setTime(fractionedTime); // this is incorrect and needs to be factored
        approvalForm.addRequiredConclusionTimes(cal);
    }
}

Для каждого элемента потребуется дробная часть diff.

Как мне рассчитать правильное fractionedTime для каждого элемента?

Спасибо

Ответы [ 3 ]

1 голос
/ 06 мая 2020

По сути, вам нужно найти x так, чтобы было выполнено

, где t - общее время, а n - количество разделений .

Сумма может быть переформулирована как 2^(1-n)*(2^n - 1), поэтому для x вы получите

x, тогда это значение будет для вас первым. item, а второй элемент получит x/2, а третий - x/(2^2) и т. д.

Зная это, вы можете написать метод split следующим образом:

private static double[] split(double t, int n) {
    double power2_1 = Math.pow(2.0, n - 1);
    double power2 = Math.pow(2.0, n);

    double factor = (t * power2_1) / (power2 - 1);

    double[] res = new double[n];

    for (int i = 0; i < n; i++) {
        res[i] = factor;
        factor /= 2;
    }

    return res;
}
1 голос
/ 06 мая 2020

На основе ответа muued , вот простой GeometricProgression класс, который может просто вычислить ваши данные, используя BigDecimal:

public class GeometricProgression {

    private final int sequenceSize;

    private final BigDecimal chunkFactor;

    public GeometricProgression(BigDecimal value, int sequenceSize) {
        this.sequenceSize = sequenceSize;
        BigDecimal divisor = BigDecimal.valueOf(2)
            .pow(sequenceSize)
            .subtract(BigDecimal.ONE);
        this.chunkFactor = value
            .divide(divisor, 8, RoundingMode.HALF_UP);
    }

    public BigDecimal get(int i) {
        return this.chunkFactor.multiply(BigDecimal.valueOf(2).pow(i));
    }

    public void printSequence() {
        for (int i = 0; i < this.sequenceSize; i++) {
            System.out.print(get(this.sequenceSize - i - 1) + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        new GeometricProgression(new BigDecimal("1.75"), 3).printSequence();
        new GeometricProgression(BigDecimal.valueOf(6), 2).printSequence();
        new GeometricProgression(BigDecimal.valueOf(6), 8).printSequence();
    }
}
1 голос
/ 06 мая 2020

Скажем, n - это размер вашего списка, тогда вы можете определить коэффициент разделения a следующим образом: a = requiredConclusionTime/(2^n - 1).

Затем элемент списка i получит a * 2^i время.

См. Geometri c Прогресс в Википедии

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...