2010-03-25 1 views
1

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

DeviceID InteractingDeviceID InteractionStartTime InteractionEndTime 
    1   2     1101    1105 

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

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

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

У меня есть два раза вопрос здесь:

  1. мой подход правильный?

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

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

Благодаря

ответ

3

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

Я предполагаю, что вы бы создать класс что-то вроде:

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). Это не должно требовать слишком больших издержек памяти на входную строку; если ваши входные файлы огромны, возможно, вы не сможете хранить данные в памяти и, возможно, придется хранить их в базе данных.

+1

Выполняя это, вы получаете два (или больше для n-сторонних взаимодействий) копий каждого взаимодействия. Если вы поддерживаете отдельный список взаимодействий и используете «вектор <взаимодействие *>» (или используйте более умный указатель), вы получаете одинаковое поведение без дублирования данных. В противном случае, хорошо. – dmckee

+0

Если индекс устройства может появиться в столбце «DeviceID» или в столбце «InteractingDeviceID», тогда вы правы. Отбрасывание 'взаимодействия.other_device_id', имеющего глобальный вектор« взаимодействия »и наличие каждого хранилища' device', будет указывать только на «взаимодействие».Когда я писал это, я предполагал, что список устройств и список взаимодействующих устройств различны (как если бы эти данные отслеживали устройства «инициатор» и список «целевых» устройств, на которые они отправляли команды). – bta

+0

Большое спасибо. Это объясняет это. –

0

Посмотрите на Boost.Spirit. Это достойная структура парсера.

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

+1

В то время как мне действительно нравится Дух, если вы уже не знакомы с ним, его, вероятно, перехитрит для этой цели. – KeithB

+0

Спасибо Глен. Хорошо знать о Boost.Spirit. Поскольку я немного новичок в мире C++, мне было интересно, можно ли это сделать, не полагаясь на такие рамки, как Spirit. Кроме того, мне, вероятно, понадобится образец кода, который даст мне обзор необходимой потребности в сантехнике, чтобы прочитать файл, проанализировать файл и перенести анализируемые данные в другие структуры данных с минимальными накладными расходами, так как время вычисления сократит время моделирования. –

2

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

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

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

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

+0

Спасибо. К счастью для меня, данные трассы были организованы в хронологическом порядке. Как только я начинаю синтаксический анализ данных, триггеры моделирования. Как только я прочитаю первую строку, я проверяю HashMap на наличие DeviceId и взаимодействующего DeviceId. Если нет, я создаю два новых объекта DeviceId, заполняю их свойства и сохраняю их в HashMap. Когда симуляция запускается некоторое время, я анализирую взаимодействия устройств с любыми тенденциями, основанными на частоте взаимодействий и времени, потраченного на устройство, потраченное на другое устройство. Я являюсь «агностиком устройства» во время моей симуляции. –

1

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

+0

Справа. * Независимо от используемой вами системы хранения, вы должны хранить каждую часть данных в * одном месте и использовать множество ссылок (или указателей) для управления вашими организационными потребностями. – dmckee

+0

Спасибо Keith. Можете ли вы объяснить, что представляет собой вектор указательных объектов взаимодействия? Хранение устройства в HashMap с помощью DeviceId в качестве ключа - отличная идея. Во время моделирования я должен искать deviceIds и их историю взаимодействия, чтобы экстраполировать полезные тенденции. Также вы предлагаете создать отдельный класс для части взаимодействия? Я предполагаю, что этот объект взаимодействия будет состоять из InteractingDeviceId, InteractionStartTime и InteractionEndTime. –

Смежные вопросы