Генерация случайного времени в диапазоне двух раз с условием - PullRequest
4 голосов
/ 05 ноября 2019

Я пытаюсь сгенерировать 10 случайных моментов в диапазоне от двух раз, и есть условие, что между сгенерированными временами не может быть менее 30 минут. Поэтому, если я начинаю в 10:00 и заканчиваю в 17:00, промежуток между ними должен составлять не менее 30 минут.

Я уже могу получить случайные времена, но не знаю, как поставить условие там, какие-нибудь идеи?

public LocalTime between(LocalTime startTime, LocalTime endTime) {
    int startSeconds = startTime.toSecondOfDay();
    int endSeconds = endTime.toSecondOfDay();
    int randomTime = ThreadLocalRandom
      .current()
      .nextInt(startSeconds, endSeconds);

    return LocalTime.ofSecondOfDay(randomTime);
}

я поместил это в цикл for, чтобы получить 10 из них

Ответы [ 3 ]

4 голосов
/ 05 ноября 2019

Для хорошего случайного распределения: из 7 часов между началом 10:00 и концом 17:00 (на 24-часовых часах, «военных часах») для вас уже зарезервировано 4 часа 30 минут. минимальные промежутки (9 пробелов при минимуме 30 минут). Так что вычтите 4:30 из 7, это даст 2 часа 30 минут свободы.

  1. Создайте 10 случайных раз в течение 2 часов 30 минут, например, как вы уже это делаете.
  2. Сортируйте их в хронологическом порядке.
  3. Добавьте 0 минут в первый раз, 30 минут в следующий, 1 час в третий и т. Д. Таким образом, вы добавите 4 часа 30 минут в последний раз. Это обеспечит, чтобы интервалы составляли не менее 30 минут каждый, а последний раз все еще находился в пределах времени окончания 17:00.

Счастливое кодирование.

1 голос
/ 05 ноября 2019

Вы можете использовать isBefore в LocalTime, поэтому отметьте startTime+30 Min is before result и result is before endTime-30 Min

LocalTime result = LocalTime.ofSecondOfDay(randomTime);   

if (startTime.plusMinutes(30).isBefore(result) && result.isBefore(endTime.minusMinutes(30))) {
    return result;
}

Возможно, вы можете использовать цикл while, чтобы получить правильный результат

while(true) {

  LocalTime result = LocalTime.ofSecondOfDay(ThreadLocalRandom. current().nextInt(startSeconds, endSeconds));   

if (startTime.plusMinutes(30).isBefore(result) && result.isBefore(endTime.minusMinutes(30))) {
    return result;
    }
  }
0 голосов
/ 05 ноября 2019

Вы не можете генерировать действительно случайные числа с компьютерами, у вас всегда должна быть какая-то стратегия. И если ваши числа действительно случайны, то они не могут знать друг друга. Таким образом, вы не можете генерировать действительно случайное время с интервалом 30 минут отдельно. Вы должны генерировать их все вместе. Вы должны найти минимальное расстояние. И время начала, и время окончания должны иметь достаточное расстояние, чтобы генерировать желаемое количество случайных моментов.

Вы можете генерировать любое количество случайных времен следующим способом в любом заданном диапазоне, если они имеют достаточное расстояние -


public List<LocalTime> generateRandomTimes(LocalTime startTime, LocalTime endTime, int n) {

    if (n < 0) {
        throw new RuntimeException("Must be greater than zero");
    }

    List<LocalTime> localTimeList = new ArrayList<>();

    int startSeconds = startTime.toSecondOfDay();
    int endSeconds = endTime.toSecondOfDay();

    int minimumDistance = LocalTime.of(0, 30).toSecondOfDay();
    int standardDistance = (endSeconds - startSeconds) / n;

    if (standardDistance <= minimumDistance) {
        throw new RuntimeException("Not enough time distance to generate the required number of random times");
    }

    int randomRange = (endSeconds - (n * minimumDistance)) / n;

    for (int i = 1; i <= 10; i++) {
        int nextInt = ThreadLocalRandom
                .current()
                .nextInt(startSeconds, startSeconds + randomRange);

        LocalTime time = LocalTime.ofSecondOfDay(nextInt);
        localTimeList.add(time);

        startSeconds = nextInt + minimumDistance;
    }

    return localTimeList;
}
...