Repository navigation
Frontend 3.8 Routenalgorithmus erstellen
Die hier dargestellte Funktionsweise stellt die Kompensationslösung des Teamleiters (Markus Thömmes) dar. Der eigentliche Algorithmus musste aufgrund von spät aufgetretenen Veränderungen der Datenlage aus der Anwendung entfernt werden. Die Dokumentation von diesem ist [hier](Frontend 3.8 Routenalgorithmus erstellen Felix) zu finden.
Definition: RouteGeneratorService
Modul: happyHour.algorithm.RouteGenerator
Dateiname: components/algorithm/RouteGenerator.js
Typ: Angular Service
Autor: Markus Thömmes
keine
Um die Route zu erstellen, werden zunächst die durch die Routenoptionen definierten Timeframes erstellt, in die die Bars eingesetzt werden sollen.
var timeframes = [];
while(isBeforeOverNight(startTime, endTime)) {
timeframes.push({
startTime: startTime.toString(),
endTime: startTime.add(options.stayTime, 'hours').toString(),
bar: null
});
}Für jeden dieser Timeframes wird nun die Lokation festgelegt, von der aus zu der Bar gelaufen wird, die in den Timeframe eingesetzt wird. Für den ersten Frame ist das die Planungslokation aus den Routenoptionen, für alle folgenden ist das die Bar, die in den vorhergehenden Frame eingesetzt wurde.
var fromLocation = options.location;
if(index > 0) {
fromLocation = timeframes[index-1].bar.location;
}Die Bars (durch Parameter bereitgestellt) werden nun durch eine Scoringfunktion bewertet und es wird die Bar mit dem höchsten Score in den aktuellen Timeframe eingesetzt (letztes Element des Arrays).
var sortedBars = _.sortBy(bars, function(bar) {
return score(timeframe, fromLocation, bar, options.weekday);
});
timeframe.bar = _.last(sortedBars);Dann wird die aktuell eingesetzte Bar aus dem Barpool gelöscht um Dopplungen zu verhindern.
bars = _.without(bars, timeframe.bar);Zuletzt wird das eigentliche Routenobjekt erstellt und mit Optionen und Timeframes befüllt.
var route = {
name: '',
options: options,
timeframes: timeframes
};Die Scoringfunktion bekommt als Parameter den zu befüllenden Timeframe, die Lokation vor dieser Bar, die zu bewertende Bar und den Wochentag für den die Route geplant ist.
Zunächst wird die Distanz zwischen der zu bewertenden Bar und der vorhergehenden Lokation berechnet.
var distance = distanceBetween(fromLocation, bar.location);Danach wird nach HappyHours gesucht, die auf den geforderten Wochentag passen. Wird eine solche HappyHour gefunden, wird deren Überlappung mit dem Timeframe geprüft und die prozentuale Überlappung mit dem Timeframe errechnet.
if(
(happyHourStart.isAfter(timeframeStart) && happyHourStart.isBefore(timeframeEnd)) ||
(happyHourEnd.isAfter(timeframeStart) && happyHourEnd.isBefore(timeframeEnd)) ||
happyHourStart.isSame(timeframeStart) || happyHourEnd.isSame(timeframeEnd)
) {
var overlapStart = timeframeStart;
if(happyHourStart.isAfter(timeframeStart)) {
overlapStart = happyHourStart;
}
var overlapEnd = timeframeEnd;
if(happyHourEnd.isBefore(timeframeEnd)) {
overlapEnd = happyHourEnd;
}
var timeframeDuration = secondsBetween(timeframeStart, timeframeEnd);
var overlapDuration = secondsBetween(overlapStart, overlapEnd);
happyHourOverlap = overlapDuration/timeframeDuration;
}Letztendlich wird aus der Entfernung, dem Rating der Bar und der prozentualen Überschneidung einer HappyHour ein Score errechnet.
(rating*100/Math.pow(distance, 2)) * (1+happyHourOverlap)