Элегантный способ анализа файлов данных для моделирования - PullRequest
1 голос
/ 25 марта 2010

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

DeviceID  InteractingDeviceID InteractionStartTime InteractionEndTime
  1            2                  1101                1105

1,2 1101 и 1105 разделены табуляцией, и это означает, что устройство 1 взаимодействовало с устройством 2 в 1101 мс и завершило взаимодействие в 1105 мс.

У меня есть наборы данных трассировки, которые собирают тысячи таких взаимодействий, и моя работа состоит в том, чтобы анализировать эти взаимодействия.

Первый шаг - анализ файла. Язык выбора - C ++. Подход, о котором я думал, заключался в том, чтобы прочитать файл, для каждой прочитанной строки создать объект устройства. Этот объект Device будет содержать свойство DeviceId и массив / вектор структур, который будет содержать список всех устройств, с которыми данный DeviceId взаимодействовал в ходе моделирования. Структура будет содержать Id взаимодействующего устройства, время начала взаимодействия и Время окончания взаимодействия.

У меня есть двоякий вопрос:

  1. Является ли мой подход правильным?

  2. Если я на правильном пути, как быстро проанализировать эти файлы данных с разделителями табуляции и создать объекты устройства без чрезмерных затрат памяти при использовании C ++?

Толчок в правильном направлении будет высоко ценится.

Спасибо

Ответы [ 4 ]

3 голосов
/ 25 марта 2010

Ваш подход кажется правильным с учетом предоставленной вами информации.

Я предполагаю, что вы создадите класс примерно так:

class device {
  public:
    int id;
    vector<interaction> interactions;
    void add_interaction(interaction add_me); // uses vector::insert
};

с

typedef struct interaction_t {
    int other_device_id;
    int start_time;
    int end_time;
} interaction;

В этот момент вы сможете прочитать в файле по одной строке за раз и извлечь данные.

device* pDev = NULL;
interaction new_interaction;
ifstream ifs( "data.dat" );
char temp[MAX_LINE_LENGTH+1];
int id, other_id, start, end;

while(ifs.getline(temp, MAX_LINE_LENGTH)) {
    sscanf(temp, "%i\t%i\t%i\t%i",
        &id,
        &new_interaction.other_device_id,
        &new_interaction.start_time,
        &new_interaction.end_time);
    pDev = find_device_by_id(id);
    pDev->add_interaction(new_interaction);
}

Код не проверен и предназначен только для иллюстрации, но вы можете понять это. Трюк заключался в написании функции find_device_by_id (возвращал бы указатель на объект device с соответствующим полем id). Это не должно требовать слишком больших затрат памяти на строку ввода; если ваши входные файлы огромны, вы, возможно, не сможете хранить данные в памяти, и вам, возможно, придется хранить их в базе данных.

2 голосов
/ 25 марта 2010

Решение вопроса о проектировании и хранении в памяти:

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

  • Если вы собираетесь последовательно проходить (полностью или частично) данные по времени старта, разве вы не сможете посещать события в порядке по времени старта? Если вы собираетесь когда-нибудь прыгнуть в середину потока, если вы не сможете эффективно выполнять поиск по времени запуска.
  • Если вы хотите исследовать событие, активное в течение определенного интервала, вам также нужно иметь возможность эффективно выполнять поиск по конечному времени.
  • Если вы хотите изучить все взаимодействия одного устройства, вам нужно иметь возможность выбирать события по устройству (что вы предложили структуру делает хорошо)
  • ... какие у вас другие варианты использования ...

Если вам не нужна наилучшая возможная производительность (то есть хорошая производительность подойдет), может быть в порядке реляционная БД. Или вы можете встроить структуры памяти со всеми необходимыми характеристиками, но они могут быть умеренно сложными ...

1 голос
/ 25 марта 2010

Я сделал то же самое с взаимодействующими людьми. Для дальнейшего расширения я бы сделал следующее: Есть класс Device, который содержит идентификатор и вектор указателей объектов взаимодействия. Устройства могут храниться в карте (или хэш-карте) для удобного поиска. Класс взаимодействия будет содержать остальную информацию из файла. Это позволит вам создавать полиморфные устройства и взаимодействия, если у вас есть несколько видов устройств или взаимодействий. Вы могли бы также хотеть иметь фабрики для устройств и взаимодействий, чтобы облегчить это.

0 голосов
/ 25 марта 2010

Взгляните на Boost.Spirit . Это достойный синтаксический анализатор.

редактировать, фиксированная ссылка

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