private IEnumerable <ActivityItem> GetTopActivityItems(DistanceBucket distanceBucket, IList <ActivityItem> activities, double topRatioOfActivitiesToUse) { var totalItems = activities.Count; var itemsToTake = Convert.ToInt32(Math.Ceiling(totalItems * topRatioOfActivitiesToUse)); var activitiesBySpeed = activities.OrderByDescending(ai => ComputeNormalizedSpeed(distanceBucket, ai.Distance, ai.Speed)).ToList(); var topActivities = activitiesBySpeed.Take(itemsToTake); return(topActivities); }
private double ComputeNormalizedSpeed(DistanceBucket distanceBucket, double distance, double speed) { //using 6 percent degradation for each 2x distance var df = .06; var dp = distance > distanceBucket.Distance? 1: distance / distanceBucket.Distance; var degradation = (1 - dp) * df; var normalizedSpeed = speed * (1 - degradation); return(normalizedSpeed); }
private ActivityItem AggregrateForBucket(DistanceBucket distanceBucket, IList <ActivityItem> activityItems) { //var totalItems = activityItems.Count; //var itemsToTake = Convert.ToInt32(Math.Ceiling(totalItems * Options.TopRatioOfActivitiesToUse)); var activitiesBySpeed = activityItems.OrderByDescending(ai => ComputeNormalizedSpeed(distanceBucket, ai.Distance, ai.Speed)).ToList(); var bestActivitiesForDistanceBucket = new List <ActivityItem>(); foreach (var activityItem in activitiesBySpeed) { bestActivitiesForDistanceBucket.Add(activityItem); if (bestActivitiesForDistanceBucket.Sum(a => a.Distance) >= distanceBucket.Distance) { break; } } var minStartTime = bestActivitiesForDistanceBucket.Min(ai => ai.StartDateTime); var duration = bestActivitiesForDistanceBucket.Sum(a => a.Duration); var distance = bestActivitiesForDistanceBucket.Sum(a => a.Distance); return(new ActivityItem(minStartTime, distance, duration)); }