gpt4 book ai didi

php - 将时间:[Distance,速度]数据转换为距离:[Time,速度]数据

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:46:26 29 4
gpt4 key购买 nike

我在想出一个算法时遇到了麻烦...

我有一系列 GPS 数据,以 1 秒为间隔记录时间、速度、距离。假设距离是米,速度是米/秒。可能有超过 2 小时的数据,或 7200 个点。这里的“时间”字段主要是作为引用。

因此,前 5 秒将是类似这样的值,其中 [1-5] 是秒。

$data = array(
1 : array('distance'=>0, 'time'=>'2014-01-09 17:50:00', 'speed'=>0.0),
2 : array('distance'=>2, 'time'=>'2014-01-09 17:50:01', 'speed'=>2.0),
3 : array('distance'=>6, 'time'=>'2014-01-09 17:50:02', 'speed'=>4.0),
4 : array('distance'=>10, 'time'=>'2014-01-09 17:50:03', 'speed'=>4.0),
5 : array('distance'=>12, 'time'=>'2014-01-09 17:50:04', 'speed'=>2.0)
);

我想将其转换为以 1 米为间隔列出的数据,例如 [1-6] 是米。

$data = array(
1 : array('seconds'=>1.5, 'time'=>'2014-01-09 17:50:01.500', 'speed'=>.666),
2 : array('seconds'=>2, 'time'=>'2014-01-09 17:50:02', 'speed'=>2.0),
3 : array('seconds'=>2.25, 'time'=>'2014-01-09 17:50:02.250', 'speed'=>4.0),
4 : array('seconds'=>2.5, 'time'=>'2014-01-09 17:50:02.500', 'speed'=>4.0),
5 : array('seconds'=>2.75, 'time'=>'2014-01-09 17:50:02.750', 'speed'=>4.0),
6 : array('seconds'=>3, 'time'=>'2014-01-09 17:50:03', 'speed'=>4.0)
);

当然,这可以在没有时间字段的情况下完成。我在计算时遇到了问题,因为它绝对不是一对一的。如果我们从 7200 秒的数据开始,我们可能会根据所覆盖的距离(多于或少于 7200 米)最终得到或多或少的数据。

编辑(2014 年 1 月 10 日)

下面是这两个方法的实际实现。实际上,我很难决定我更喜欢哪种方法,迭代方法还是递归方法。我可能会去迭代

方法 1,迭代(@Ezequiel Muns,我做了非常小的修改):

function timeToDistance($data) {
if(sizeof($data) == 0){ return; }
$startTime = $data[0]['time'];

$prev = null;
$result = array();
foreach ($data as $secs => $row) {
$row['seconds'] = $secs; // to simplify passing in secs
if ($prev == null) {
// make sure we have a pair
$prev = array( 'distance'=>0 );
}
foreach (distanceRowsBetween($startTime,$prev, $row) as $dist => $distRow) {
$result[$dist] = $distRow;
}
$prev = $row;
}
return $result;
}

function distanceRowsBetween($startTime,$prevRow, $nextRow) {
// Return the by-distance rows that are between $prevRow (exclusive)
// and $nextRow (inclusive)
$rows = array();
$currDist = $prevRow['distance'];
while (true) {
// try to move to the next whole unit of distance
$dDist = ceil($currDist) - $currDist;
$dDist = $dDist == 0.0? 1.0 : $dDist; // dDist is 1 unit if currDist is whole
$currDist += $dDist;
if ($currDist > $nextRow['distance'])
break;

$currSpeed = $nextRow['speed'];
$currSecs = strtotime($nextRow['time']) - strtotime($startTime);
$currTime = $nextRow['time'];

$rows[$currDist] = array(
'speed' => $currSpeed,
'seconds' => $currSecs,
'time' => $currTime,
);
}
return $rows;
}

方法 2,递归(@Nathaniel Ford 伪代码,我的实际代码):

function data2dist($time_data = array()){
$dist_data = array();
if(sizeof($time_data) == 0){ return $dist_data; }

$start_point = array_shift($time_data);
$start_time = $start_point['time'];

data2dist_sub($start_time, $time_data,$dist_data,$start_point);

return $dist_data;
}

function data2dist_sub($start_time,&$time_data, &$dist_data, $start_point = array()){
if(sizeof($time_data) == 0 && !isset($start_point)){
return;
}

if(sizeof($dist_data) == 0){
$prev_dist = 0;
} else {
$prev_dist = $dist_data[sizeof($dist_data)-1]['distance'];
}
// since distances are accumulating, get curr distance by subtracting last one
$point_dist = $start_point['distance'] - $prev_dist;

if($point_dist == 1){
// exactly 1: perfect, add and continue
$dist_data[] = $start_point;
$start_point = array_shift($time_data);
} else if($point_dist > 1){
// larger than 1: effectively remove 1 from current point and send it forward
$partial_point = $start_point;
$partial_point['distance'] = 1 + $prev_dist;
$dist_data[] = $partial_point;

} else if($point_dist < 1){
// less than 1, carry forward to the next item and continue (minor: this partial speed is absorbed into next item)
$start_point = array_shift($time_data);
if(!isset($start_point)){ return; }

$start_point['distance'] += $point_dist;
}
data2dist_sub($start_time,$time_data,$dist_data,$start_point);
}

最佳答案

您可以简化这一点,注意对于每一对连续的按时间行,您需要计算 0 个或更多按距离行,而这些仅取决于这两个按时间行。

因此,从一个函数开始进行这种更简单的计算,这是一个骨架,为了简单起见,将转换后的“秒”、“速度”和“时间”值的计算保留在外。

function distanceRowsBetween($prevRow, $nextRow) {
// Return the by-distance rows that are between $prevRow (exclusive)
// and $nextRow (inclusive)
$rows = array();
$currDist = $prevRow['distance'];
while (true) {
// try to move to the next whole unit of distance
$dDist = ceil($currDist) - $currDist;
$dDist = $dDist == 0.0? 1.0 : $dDist; // dDist is 1 unit if currDist is whole
$currDist += $dDist;
if ($currDist > $nextRow['distance'])
break;

// calculate $currSecs at distance $currDist
// calculate $currSpeed
// calculate $currTime

$rows[$currDist] = array(
'speed' => $currSpeed,
'seconds' => $currSecs,
'time' => $currTime,
);
}
return $rows;
}

现在您已经有了这些,剩下的就是迭代输入中的每个连续对,并按距离累积结果行:

function timeToDistance($data) {
$prev = null;
$result = array();
foreach ($data as $secs => $row) {
$row['seconds'] = $secs; // to simplify passing in secs
if ($prev == null) {
$prev = $row; // make sure we have a pair
continue;
}
foreach (distanceRowsBetween($prev, $row) as $dist => $distRow) {
$result[$dist] = $distRow;
}
$prev = $row;
}
return $result;
}

请注意,在此函数中,我正在填充并传入行中的当前“秒”值,以减少传递到前一个函数的参数数量。

关于php - 将时间:[Distance,速度]数据转换为距离:[Time,速度]数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21033188/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com