График среднего действия в минуту - PullRequest
2 голосов
/ 15 ноября 2011

Я создаю график в php, используя библиотеку графиков Google, чтобы показать данные StarCraft II APM, и мне трудно думать о логике всего этого. Я не уверен, что это лучшее место, чтобы спросить, но у меня нет выбора. Это немного сложно объяснить, поэтому, если требуется какое-либо разъяснение, дайте мне знать.

У меня есть массив ключей и значений. Ключ время в секундах. Значение - это действия, выполненные в ту секунду. Секунды с 0 действиями опущены моим источником данных. Пример:

seconds     actions
1           10
3           5
4           7
7           15
etc         etc

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

Вот мой текущий код

$p1_total = 0;
foreach ($p1 as $seconds => $actions) {
    $p1_total = $p1_total + $actions;
    $data['player1'][$seconds] = round($p1_total * 60 / $seconds);
}

Однако это вычисляет скользящее среднее по мере прибавления $ p1_total, и мне действительно нужно среднее значение за последние 60 секунд на каждом интервале.

Я просто не могу понять, как правильно это кодировать. Я знаю, что мне нужно заменить $ p1_total количеством действий за последние 60 секунд. Но собирание - вот что меня заводит. Как я должен динамически настроить это, не имея дело с безумным количеством переменных? Имейте в виду, что мои секунды - это не каждая секунда, поэтому я не могу просто взять последние 60 записей в массиве, поскольку они могут быть длиннее 60 секунд.

Я думал о вставке значений в массив, чтобы восполнить пробелы, но я не могу придумать разумного способа, не искажая среднее значение. Или есть способ, которым я могу сделать это чисто математически.

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

Ответы [ 2 ]

2 голосов
/ 15 ноября 2011

Вы можете вставить нули, чтобы восполнить пустые места, потому что каждый раз, который не представлен в данных, соответствует секунде, где были выполнены нулевые действия. Это, вероятно, концептуально простой способ. Вам не нужно на самом деле вставлять нули в; то, что вы могли бы сделать, это создать функцию, которая возвращает $p1[$t], если она существует, в противном случае 0. Затем просто используйте вашу функцию вместо прямого доступа к $p1. (Мой PHP довольно ржавый, поэтому при необходимости рассмотрите этот PHP-подобный псевдокод)

function actions_at_second($t) {
    return ($t in $p1) ? $p1[$t] : 0;
}

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

Что касается фактического вычисления скользящего среднего, то вы можете выполнить итерацию в течение первых 60 секунд и сохранить накопленную сумму в выходном массиве:

for ($t = 1; $t <= 60; $t++) {
    $total += actions_at_second($t);
    $data['player_1'][$t] = $total * 60 / $t;
}

(Это нужно будет скорректировать, если ваши необработанные данные содержат запись для нулевых секунд). Затем, после первых 60 секунд, каждый раз, когда вы добавляете количество действий в данную секунду, вычитаете количество действий, выполненных на 60 секунд раньше:

for ($t = 61; $t <= $tmax; $t++) {
    $total += actions_at_second($t) - actions_at_second($t - 60);
    $data['player_1'][$t] = $total;
}

($tmax будет самой высокой секундой, в которую у вас есть данные, в основном, продолжительность игры.) Я полагаю, что в последнем примере $total больше не представляет полную совокупную сумму, поэтому вы можете переименовать ее - но она должна быть той же переменной, что и $total в предыдущем примере кода.

Кстати, я предполагаю, что $tmax никогда не будет меньше 61. Если вы собираетесь выпускать этот код «в дикую природу» для использования другими людьми, убедитесь, что вы проверили этот случай ( на случай досрочной сдачи или чего-то еще).

0 голосов
/ 15 ноября 2011

Это будет циклически проходить через массив и добавлять только действия между max(0,$current_time-60) и $ current_time . To get the average you need to divide by $ current_time - $ start_time which will be 60 or $ current_time if $ current_time is less than 60`.

// $p1 is array of seconds => actions

$current_time = 75;
$start_time = max(0,$current_time-60);

$total_actions = 0;
foreach($p1 as $key => $value) {
  if( $start_time < $key && $key <= $current_time )
    $total_actions += $value;
}
$average = $total_actions / ($current_time - $start_time);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...