Как вы справляетесь с временными рядами, которые охватывают выходные и нерабочие часы - PullRequest
2 голосов
/ 25 мая 2011

Я работаю над классом, который будет содержать объекты с отметкой времени и несколькими измерениями.Эти измерения обычно проводятся с 08:00 до 16:00 каждый будний день, но они должны быть гибкими.Теперь я хочу иметь возможность указать временной интервал, скажем, 1 час, и получить среднее значение.Что-то вроде myArrayList.getAvrageHeight (), и оно возвращает среднюю высоту из всех измерений за последний час.Я планирую сохранить в списке только необходимые записи и удалить те, для которых истек срок ожидания.

Выполнение этого в течение одного дня довольно просто.Но я хотел бы, чтобы при вызове этого метода в 08.15 во вторник утром myArrayList содержал данные за 45 минут с понедельника и данные за 15 минут со вторника.

Одно из моих самых больших ограничений заключается в том, чтоизмерения выполняются с произвольными интервалами, начиная от 1 минуты и до нескольких раз в секунду.

До сих пор я получил это для вычисления средних значений каждый раз, когда добавляется измерение:

protected void computeAvrages() {

    averageWeight = 0;
    averageSpeed = 0;
    averageHeight = 0;

    for (int i = 0; i < super.size(); i++) {
        averageWeight += super.get(i).getWeight();
        averageSpeed += super.get(i).getSpeed();
        averageHeight += super.get(i).getHeight();
    }

    averageWeight = averageWeight/super.size();
    averageSpeed = averageSpeed/super.size();
    averageHeight = averageHeight/super.size();

}

Мои объекты выглядят так:

public class Car {

    double weight;
    double speed;
    double height;

    int timeStamp;

    public Car(int timeStamp, double weight, double speed, double height) {
    this.timeStamp = timeStamp;
    this.weight = weight;
    this.speed = speed;
    this.height = height;
    }


    public double getWeight() {
        return weight;
    }

    public double getSpeed() {
        return speed;
    }

    public double getHeight() {
        return height;
    }

    public double getTimeStamp() {
        return timeStamp;
    }
}

myArrayList сортируется по метке времени в порядке возрастания (я могу использовать бинарный поиск в этом списке), и количество записей, которые я планирую хранить, будет составлять от 1.000-> 500 000 в зависимости от трафика (около 3 автомобилей в секунду в течение недели). Интервал времени сохраняется в секундах, поэтому при указании 1 часа я сохраняю его как 3600.

Когда я вызываю myArrayList.add(aCar), вызывается computeAvrages, но мне интересно следующее:

  1. Как мне следует изменить понедельник -> вторник, aи с пятницы по понедельник?
  2. В настоящее время я сохраняю время запуска и остановки как startHour, startMinute, stopHour и stopMinute для простоты. Как бы вы сохранили эти временные ссылки?

Эта проблема может быть сложной для стека и потока ответов типа вопрос-ответ, но я постараюсь сделать ее проще:

Вы смотрите на шоссе.Машины проезжают мимо.Каждый проезжающий автомобиль записывается с указанием веса, роста и скорости.Теперь я хочу указать время суток (т.е. с 08:00 до 16:00), которое меня интересует.Интересны только автомобили, которые проезжают мимо в течение рабочей недели (или понедельник -> пятница). Я бы оставлял проезжающие мимо автомобили только в этот период, но я все равно получал уведомления об автомобилях, которые проезжали за пределами этого периода.

Затем я хочу вычислить среднее значение за 1 час проезжающих машин в течение моего периода времени.Но во вторник в 08:15 меня не интересует только получение среднего значения за последние 15 минут, но я хочу получить среднее значение за последние 45 минут в понедельник в сочетании с первыми 15 вторниками.Так что мои вопросы выше применимы.

Ответы [ 3 ]

0 голосов
/ 25 мая 2011

Итак, если я правильно понимаю ... С 15:15 до 16:15 вы получите среднее: 2. С 8:15 до 9:15 вы получите среднее: 3.

Вы хотитевзять время с 16:00 до 16:15 и включить его в среднее время с 8:15 до 9:00.

Это проблема программирования или математическая проблема?Потому что, если это математическая задача, кажется, что вы должны взять (15/60) * 2 + (45/60) * 3, чтобы получить среднее значение по утрам (с 8:00 до 9:00).

НоВы бы хотели делать это каждый час, а не только часы, разделяющие дни.Если ваш образец был с 8:30 до 9:30 и с 9:30 до 10:30, вам, вероятно, следует усреднить каждый образец вместе.

0 голосов
/ 25 мая 2011

Ваш вопрос настолько сложен, что у меня (и многих других) больше вопросов, чем ответов.В любом случае, вот мои два цента, смотрящие на последние два абзаца вашего вопроса.

Я бы использовал следующие классы:

  1. класс CarEvent с тремя свойствами - wight, height, speed
  2. класс EventTimeStamp с двумя свойствами - Date, ts.Тип ts короткий с диапазоном от 0800 до 1600. Класс должен иметь два метода - subtract(int days, int hours) и add(int days,int hours), оба возвращают другой экземпляр EventTimeStamp.
  3. class TrafficLog, который содержит все CarEvents в LinkedListMap.LinkedListMap - это карта, которая также обеспечивает последовательный доступ, так что вы можете выполнять бинарный поиск.Ключом к карте должен быть экземпляр EventTimeStamp

. С помощью этой структуры данных вы можете реализовать аналитические методы, которые вам нужны, в классе TrafficLog.Например, чтобы получить среднее значение:

public float getAverageTraffic(EventTimeStamp startDate, int durationHours)
{
    EventTimeStamp startEventTS = startDate.subtract(0,durationHours);
    CarEvent startEvent = eventList.get(startEventTS); //there might not be an event at exactly this point. So some tolerance have to be built in to this.
    CarEvent endEvent = eventList.get(startDate);
    return getAverage(startEvent,endEvent);//the two params are part of a linked list, so you can iterate and compute the average.
}
0 голосов
/ 25 мая 2011

Разделите общее количество записей (в периоде времени) на общий период времени.

Используя ваш пример: во вторник утром 8:15. И вы хотите, чтобы последние 15 минут плюс последние 45 минут предыдущего дня составляли среднее значение за этот час. (Что, кстати, действительно странно), затем возьмите данные за последние 45 минут предыдущего дня и суммируйте их с последними 15 минутами для своего среднего.

Что касается структур данных, то ваше среднее значение "в реальном времени" будет содержать час значений. По прошествии минуты в течение периода времени вы будете добавлять данные с одной стороны и удалять с другой. Это позволит вам иметь час, который может занимать два дня.

...