Compare commits
No commits in common. "ce66de0a7236570bcea4df07226846342c763889" and "fdafe1ff225e6c66a84d72ae6c55fe99d8be0b43" have entirely different histories.
ce66de0a72
...
fdafe1ff22
@ -23,17 +23,17 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
||||
SOURCES += \
|
||||
calculate_parking_tickets.cpp \
|
||||
calculate_parking_tickets_utils.cpp \
|
||||
# calculate_parking_tickets_day.cpp \
|
||||
calculate_parking_tickets_day.cpp \
|
||||
calculate_parking_tickets_algorithms.cpp \
|
||||
calculate_parking_tickets_tariff.cpp \
|
||||
# calculate_parking_tickets_tariff_step.cpp
|
||||
calculate_parking_tickets_tariff_step.cpp
|
||||
|
||||
HEADERS += \
|
||||
calculate_parking_tickets_global.h \
|
||||
calculate_parking_tickets.h \
|
||||
calculate_parking_tickets_utils.h \
|
||||
# calculate_parking_tickets_tariff_step.h \
|
||||
# calculate_parking_tickets_day.h \
|
||||
calculate_parking_tickets_tariff_step.h \
|
||||
calculate_parking_tickets_day.h \
|
||||
calculate_parking_tickets_algorithms.h \
|
||||
calculate_parking_tickets_tariff.h
|
||||
|
||||
|
@ -59,8 +59,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static minute_t computeFreeOfCharge(parking_tariff_t const *tariff,
|
||||
minute_t startMinute) {
|
||||
static minute_t computeEffectiveStartMinute(parking_tariff_t const *tariff,
|
||||
minute_t startMinute) {
|
||||
QDateTime const start = TUtils::fromMinutes(startMinute);
|
||||
minute_t free_of_charge = 0;
|
||||
minute_t startMinuteDay = start.time().hour()*60 +start.time().minute();
|
||||
@ -72,12 +72,8 @@ static minute_t computeFreeOfCharge(parking_tariff_t const *tariff,
|
||||
(startMinuteDay >= 0 && startMinuteDay < tariff->night_tariff_end)) {
|
||||
free_of_charge = tariff->free_of_charge_night_tariff;
|
||||
}
|
||||
return free_of_charge;
|
||||
}
|
||||
|
||||
static minute_t computeEffectiveStartMinute(parking_tariff_t const *tariff,
|
||||
minute_t startMinute) {
|
||||
return (startMinute + computeFreeOfCharge(tariff, startMinute));
|
||||
return (startMinute + free_of_charge);
|
||||
}
|
||||
|
||||
static bool checkCalculatePreConditions(parking_tariff_t const* tariff,
|
||||
@ -94,9 +90,8 @@ static bool checkCalculatePreConditions(parking_tariff_t const* tariff,
|
||||
minute_t const parkingTime = endMinute - startMinute;
|
||||
|
||||
if (parkingTime == 0) {
|
||||
price->units = 0;
|
||||
//qInfo() << "startMinute == endMinute => no parking time";
|
||||
return true;
|
||||
qCritical() << "startMinute == endMinute => no parking time";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tariff->parking_time_max != -1) {
|
||||
@ -108,17 +103,26 @@ static bool checkCalculatePreConditions(parking_tariff_t const* tariff,
|
||||
}
|
||||
|
||||
QDateTime const start = TUtils::fromMinutes(startMinute);
|
||||
//minute_t free_of_charge = 0;
|
||||
//minute_t startMinuteDay = start.time().hour()*60 +start.time().minute();
|
||||
//if (startMinuteDay >= tariff->day_tariff_start &&
|
||||
// startMinuteDay < tariff->day_tariff_end) {
|
||||
// free_of_charge = tariff->free_of_charge_day_tariff;
|
||||
//} else
|
||||
//if ((startMinuteDay >= tariff->night_tariff_start && startMinuteDay < MINUTES_PER_DAY) ||
|
||||
// (startMinuteDay >= 0 && startMinuteDay < tariff->night_tariff_end)) {
|
||||
// free_of_charge = tariff->free_of_charge_night_tariff;
|
||||
//}
|
||||
|
||||
minute_t const effectiveStartMinute = computeEffectiveStartMinute(tariff, startMinute);
|
||||
QDateTime const end = TUtils::fromMinutes(endMinute);
|
||||
|
||||
if (effectiveStartMinute > endMinute) {
|
||||
//minute_t free_of_charge = computeFreeOfCharge(tariff, startMinute);
|
||||
//fprintf(stderr,
|
||||
// "[start:%02d:%02d, ende:%02d:%02d]: %ld free minutes. no charge.\n",
|
||||
// start.time().hour(), start.time().minute(),
|
||||
// end.time().hour(), end.time().minute(), free_of_charge);
|
||||
price->units = 0;
|
||||
price->valid = true;
|
||||
fprintf(stderr,
|
||||
"[start:%02d:%02d, ende:%02d:%02d]: %ld free minutes. no charge.\n",
|
||||
start.time().hour(), start.time().minute(),
|
||||
end.time().hour(), end.time().minute(), tariff->free_of_charge_day_tariff);
|
||||
memset(price, 0x00, sizeof(*price));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -127,68 +131,6 @@ static bool checkCalculatePreConditions(parking_tariff_t const* tariff,
|
||||
}
|
||||
|
||||
#define DEBUG_INTERNAL 0
|
||||
#define DEBUG_MAX_PRICE_AT_MIDNIGHT 0
|
||||
|
||||
uint32_t compute_price_for_max_price_at_midnight(parking_tariff_t const *tariff,
|
||||
QDateTime const &end,
|
||||
TariffStep const *step) {
|
||||
uint32_t price_units = 0;
|
||||
QDateTime stepDateTime = step->dateTime();
|
||||
QDateTime nextStepDateTime;
|
||||
QDateTime midnight(stepDateTime.date().addDays(1), QTime(0,0));
|
||||
uint32_t day_price_units = 0;
|
||||
bool dbg = true;
|
||||
while (stepDateTime < end) {
|
||||
uint32_t const price_units_tmp = step->price();
|
||||
step = step->next();
|
||||
nextStepDateTime = step->dateTime();
|
||||
if (stepDateTime < midnight) {
|
||||
day_price_units += price_units_tmp;
|
||||
if (day_price_units > tariff->max_price_at_midnight) {
|
||||
day_price_units = tariff->max_price_at_midnight;
|
||||
if (dbg) {
|
||||
#if DEBUG_MAX_PRICE_AT_MIDNIGHT==1
|
||||
fprintf(stderr,
|
||||
"[%s:%02d:%02d price_so_far=%d day_price=%d]\n",
|
||||
stepDateTime.date().toString().toStdString().c_str(),
|
||||
stepDateTime.time().hour(), stepDateTime.time().minute(),
|
||||
price_units, day_price_units);
|
||||
//dbg = false;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#if DEBUG_MAX_PRICE_AT_MIDNIGHT==1
|
||||
dbg = true;
|
||||
fprintf(stderr,
|
||||
"[%s:%02d:%02d price_so_far=%d day_price=%d]\n",
|
||||
stepDateTime.date().toString().toStdString().c_str(),
|
||||
stepDateTime.time().hour(), stepDateTime.time().minute(),
|
||||
price_units, day_price_units);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if (day_price_units == tariff->max_price_at_midnight) {
|
||||
price_units += day_price_units;
|
||||
day_price_units = 0;
|
||||
} else {
|
||||
day_price_units += price_units_tmp;
|
||||
}
|
||||
#if DEBUG_MAX_PRICE_AT_MIDNIGHT==1
|
||||
fprintf(stderr,
|
||||
"[%s:%02d:%02d 24h max. price_so_far=%d day_price=%d]\n",
|
||||
stepDateTime.date().toString().toStdString().c_str(),
|
||||
stepDateTime.time().hour(), stepDateTime.time().minute(),
|
||||
price_units, day_price_units);
|
||||
#endif
|
||||
midnight = stepDateTime;
|
||||
midnight.setDate(midnight.date().addDays(1));
|
||||
midnight.setTime(QTime(0, 0));
|
||||
}
|
||||
stepDateTime = nextStepDateTime;
|
||||
}
|
||||
price_units += day_price_units;
|
||||
return price_units;
|
||||
}
|
||||
|
||||
TariffStep const *
|
||||
compute_price_for_parking_ticket_internal(parking_tariff_t const *tariff,
|
||||
@ -285,7 +227,60 @@ compute_price_for_parking_ticket_internal(parking_tariff_t const *tariff,
|
||||
}
|
||||
if (tariff->max_price_at_midnight) {
|
||||
// restart pricing at midnight if current price is max_price_at_midnight
|
||||
price_units = compute_price_for_max_price_at_midnight(tariff, end, step);
|
||||
QDateTime stepDateTime = step->dateTime();
|
||||
QDateTime nextStepDateTime;
|
||||
QDateTime midnight(stepDateTime.date().addDays(1), QTime(0,0));
|
||||
uint32_t day_price_units = 0;
|
||||
bool dbg = true;
|
||||
while (stepDateTime < end) {
|
||||
uint32_t const price_units_tmp = step->price();
|
||||
step = step->next();
|
||||
nextStepDateTime = step->dateTime();
|
||||
if (stepDateTime < midnight) {
|
||||
day_price_units += price_units_tmp;
|
||||
if (day_price_units > tariff->max_price_at_midnight) {
|
||||
day_price_units = tariff->max_price_at_midnight;
|
||||
if (dbg) {
|
||||
#if DEBUG_INTERNAL
|
||||
fprintf(stderr,
|
||||
"[%s:%02d:%02d price_so_far=%d day_price=%d]\n",
|
||||
stepDateTime.date().toString().toStdString().c_str(),
|
||||
stepDateTime.time().hour(), stepDateTime.time().minute(),
|
||||
price_units, day_price_units);
|
||||
//dbg = false;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#if DEBUG_INTERNAL
|
||||
dbg = true;
|
||||
fprintf(stderr,
|
||||
"[%s:%02d:%02d price_so_far=%d day_price=%d]\n",
|
||||
stepDateTime.date().toString().toStdString().c_str(),
|
||||
stepDateTime.time().hour(), stepDateTime.time().minute(),
|
||||
price_units, day_price_units);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if (day_price_units == tariff->max_price_at_midnight) {
|
||||
price_units += day_price_units;
|
||||
day_price_units = 0;
|
||||
} else {
|
||||
day_price_units += price_units_tmp;
|
||||
}
|
||||
#if DEBUG_INTERNAL
|
||||
fprintf(stderr,
|
||||
"[%s:%02d:%02d 24h max. price_so_far=%d day_price=%d]\n",
|
||||
stepDateTime.date().toString().toStdString().c_str(),
|
||||
stepDateTime.time().hour(), stepDateTime.time().minute(),
|
||||
price_units, day_price_units);
|
||||
#endif
|
||||
midnight = stepDateTime;
|
||||
midnight.setDate(midnight.date().addDays(1));
|
||||
midnight.setTime(QTime(0, 0));
|
||||
}
|
||||
stepDateTime = nextStepDateTime;
|
||||
}
|
||||
price_units += day_price_units;
|
||||
}
|
||||
|
||||
price->units = price_units;
|
||||
@ -301,9 +296,9 @@ bool compute_price_for_parking_ticket(parking_tariff_t const *tariff,
|
||||
minute_t startMinute, // CET
|
||||
minute_t endMinute, // CET
|
||||
struct price_t *price) {
|
||||
price->valid = false;
|
||||
|
||||
if (!checkCalculatePreConditions(tariff, startMinute, endMinute, price)) { // CET
|
||||
return price->valid;
|
||||
return false;
|
||||
}
|
||||
|
||||
// minute_t const parkingTime = endMinute - startMinute;
|
||||
@ -314,8 +309,8 @@ bool compute_price_for_parking_ticket(parking_tariff_t const *tariff,
|
||||
// QDateTime const effStart = TUtils::fromMinutes(effectiveStartMinute);
|
||||
// QDateTime const end = TUtils::fromMinutes(endMinute);
|
||||
|
||||
// qDebug() << "XXX" << effStart;
|
||||
// qDebug() << "XXX" << end;
|
||||
//qDebug() << effStart;
|
||||
//qDebug() << end;
|
||||
|
||||
TariffStep const *stepDbg =
|
||||
compute_price_for_parking_ticket_internal(tariff,
|
||||
@ -362,8 +357,7 @@ bool compute_price_for_parking_ticket(parking_tariff_t const *tariff,
|
||||
return false;
|
||||
}
|
||||
|
||||
// fprintf(stderr, " : gesamt %.2f (netto: %.2f)\n", price->brutto/100, price->netto/100);
|
||||
|
||||
fprintf(stderr, " : gesamt %.2f (netto: %.2f)\n", price->brutto/100, price->netto/100);
|
||||
return true;
|
||||
|
||||
} else {
|
||||
@ -373,78 +367,27 @@ bool compute_price_for_parking_ticket(parking_tariff_t const *tariff,
|
||||
return false;
|
||||
}
|
||||
|
||||
#define DEBUG_COMPUTE_DURATION 0
|
||||
|
||||
bool compute_duration_for_parking_ticket(parking_tariff_t const *tariff,
|
||||
minute_t start_parking_time,
|
||||
minute_t *end_parking_time,
|
||||
struct price_t const *price) {
|
||||
QDateTime const s = TUtils::fromMinutes(start_parking_time);
|
||||
|
||||
#if DEBUG_COMPUTE_DURATION==1
|
||||
fprintf(stderr, "price %u, start_parking_time %s:%02d:%02d\n",
|
||||
price->units, s.date().toString().toStdString().c_str(),
|
||||
s.time().hour(), s.time().minute());
|
||||
#endif
|
||||
|
||||
minute_t free_of_charge = computeFreeOfCharge(tariff, start_parking_time);
|
||||
minute_t end_time_at_max_price = start_parking_time;
|
||||
for (int now = 0; now < tariff->parking_time_max; ++now) {
|
||||
if (price->units == 0) {
|
||||
if (free_of_charge >= now) {
|
||||
*end_parking_time = start_parking_time + free_of_charge;
|
||||
|
||||
#if DEBUG_COMPUTE_DURATION==1
|
||||
QDateTime const e = TUtils::fromMinutes(*end_parking_time);
|
||||
fprintf(stderr, "price %u, end_parking_time %s:%02d:%02d\n",
|
||||
price->units, e.date().toString().toStdString().c_str(),
|
||||
e.time().hour(), e.time().minute());
|
||||
#endif
|
||||
|
||||
price_t p;
|
||||
for (int i = 0; i < tariff->parking_time_max; ++i) {
|
||||
minute_t end_time = start_parking_time + i;
|
||||
if (compute_price_for_parking_ticket(tariff, start_parking_time,
|
||||
end_time, &p)) {
|
||||
if (p.netto >= price->netto) {
|
||||
*end_parking_time = end_time;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
minute_t end_time = start_parking_time + now;
|
||||
price_t p;
|
||||
if (compute_price_for_parking_ticket(tariff, start_parking_time,
|
||||
end_time, &p)) {
|
||||
if (p.units <= price->units) {
|
||||
end_time_at_max_price = end_time;
|
||||
} else {
|
||||
if (end_time_at_max_price >= free_of_charge) {
|
||||
*end_parking_time = end_time_at_max_price - free_of_charge;
|
||||
|
||||
#if DEBUG_COMPUTE_DURATION==1
|
||||
QDateTime const e = TUtils::fromMinutes(*end_parking_time);
|
||||
fprintf(stderr, "price %u, end_parking_time %s:%02d:%02d\n",
|
||||
price->units, e.date().toString().toStdString().c_str(),
|
||||
e.time().hour(), e.time().minute());
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
fprintf(stderr,
|
||||
"ERROR end_time_at_max_price(%lu) < free_of_charge(%lu)\n",
|
||||
end_time_at_max_price, free_of_charge);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// TODO ausgabe
|
||||
//return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "ERROR %s start_parking_time for price %u: %s:%02d:%02d\n",
|
||||
__func__, price->units, s.date().toString().toStdString().c_str(),
|
||||
s.time().hour(), s.time().minute());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool compute_price_for_tages_ticket(parking_tariff_t *tariff,
|
||||
time_t parking_time_start, // minutes
|
||||
struct price_t *price) {
|
||||
// NOT TESTED
|
||||
QDateTime dateTime = TUtils::fromMinutes(parking_time_start).addDays(1);
|
||||
dateTime.setTime(QTime(0, 0));
|
||||
time_t parking_time_end = dateTime.toSecsSinceEpoch() / 60;
|
||||
@ -457,7 +400,6 @@ bool compute_price_for_24h_ticket(parking_tariff_t *tariff,
|
||||
struct price_t *price) {
|
||||
QDateTime dateTime = TUtils::fromMinutes(parking_time_start).addDays(1);
|
||||
time_t parking_time_end = dateTime.toSecsSinceEpoch() / 60;
|
||||
// NOT TESTED
|
||||
return compute_price_for_parking_ticket(tariff, parking_time_start,
|
||||
parking_time_end, price);
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ typedef struct price_t {
|
||||
double brutto;
|
||||
double vat_percentage;
|
||||
double vat;
|
||||
bool valid;
|
||||
} price_t;
|
||||
|
||||
static constexpr uint16_t const MIN_PER_DAY = 1440;
|
||||
|
@ -131,6 +131,160 @@ struct parking_tariff_t {
|
||||
/// \brief max_price_at_midnight
|
||||
///
|
||||
uint32_t max_price_at_midnight;
|
||||
|
||||
#if 0
|
||||
/// Minimal amount of money for buying a ticket.
|
||||
///
|
||||
/// The minimal amount of money a user has to provide \n
|
||||
/// to get a valid (parking) ticket.
|
||||
uint32_t money_min;
|
||||
|
||||
///
|
||||
/// \brief Minimal parking time.
|
||||
///
|
||||
/// Minimal parking time. The full parking time must be \n
|
||||
/// a multiple of @see parking_time_min.
|
||||
minute_t parking_time_min;
|
||||
|
||||
///
|
||||
/// \brief Maximal parking time. Must be a multiple of @see parking_time_min.
|
||||
///
|
||||
minute_t parking_time_max;
|
||||
|
||||
///
|
||||
/// \brief integration_time_max
|
||||
/// Maximal possible integration time, i.e. the time after which all tickets
|
||||
/// will be closed.
|
||||
/// \note parking_time_max <= integration_time_max.
|
||||
minute_t integration_time_max;
|
||||
|
||||
///
|
||||
/// \brief tages_ticket_uebertrag
|
||||
///
|
||||
bool tages_ticket_uebertrag;
|
||||
|
||||
///
|
||||
/// \brief free_of_charge_uebertrag
|
||||
/// Carry FOC (usually at midnight) or not.
|
||||
/// The default setting is true.
|
||||
bool free_of_charge_uebertrag;
|
||||
|
||||
/// \brief Time for optionally changing tariff-table.
|
||||
///
|
||||
/// Depending on the configuration, a table in the tariff can be swapped
|
||||
/// in, typically at midnight. But it is also possible that this event happens
|
||||
/// during the day.
|
||||
/// @note 0 ≤ tariff_deadline $lt; 1440
|
||||
minute_t tages_ticket_offset;
|
||||
|
||||
///
|
||||
/// \brief vorkauf
|
||||
///
|
||||
/// Maximal time in minutes before business hours where a presales
|
||||
/// ("vorkauf") operation is possible.
|
||||
minute_t vorkauf;
|
||||
|
||||
/// \brief Memory consumption of calculate price algorithm
|
||||
uint32_t memory_consumption;
|
||||
|
||||
///
|
||||
/// Time-range which is free of charge.
|
||||
///
|
||||
struct free_of_charge_range_t free_of_charge;
|
||||
|
||||
///
|
||||
/// \brief business_hours
|
||||
///
|
||||
struct business_hours_range_t business_hours;
|
||||
|
||||
|
||||
/// Array of possible days: DEFAULT, SUN - SAT plus HOLIDAY.
|
||||
///
|
||||
day_t *day[DAYS];
|
||||
|
||||
/// Pointer to current day in tariff-table.
|
||||
///
|
||||
day_t *current_day;
|
||||
|
||||
/// Array of holiday dates. Format: YYYY:MM:DD
|
||||
///
|
||||
holiday_date_t *holiday_date;
|
||||
|
||||
///
|
||||
/// \brief algorithm_features
|
||||
///
|
||||
uint16_t algorithm_features;
|
||||
|
||||
///
|
||||
/// \brief tariff_features
|
||||
///
|
||||
/// @todo: add comment
|
||||
uint64_t tariff_features;
|
||||
|
||||
///
|
||||
/// \brief _tariff_features
|
||||
///
|
||||
/// @todo: add comment
|
||||
uint64_t _tariff_features[64];
|
||||
|
||||
///
|
||||
/// @brief closed_tickets_local_end_times
|
||||
///
|
||||
/// @note The end times of all closed tickets: the possible values are
|
||||
/// 0 <= end_time <= 168h.
|
||||
///
|
||||
bool closed_tickets_sorted;
|
||||
|
||||
///
|
||||
/// \brief closed_tickets_count
|
||||
///
|
||||
/// @note Used internally for optimizations.
|
||||
int closed_tickets_count;
|
||||
|
||||
///
|
||||
/// \brief closed_tickets
|
||||
/// @todo: add comment
|
||||
ticket_t *closed_tickets[NUMBER_OF_TICKETS];
|
||||
|
||||
///
|
||||
/// \brief tariff_step_min
|
||||
///
|
||||
/// @todo: add comment
|
||||
time_t tariff_step_min;
|
||||
|
||||
///
|
||||
/// \brief tariff_step_max
|
||||
///
|
||||
/// @todo: add comment
|
||||
time_t tariff_step_max;
|
||||
|
||||
///
|
||||
/// \brief tariff_version
|
||||
/// Version for a given config-file, associated to a given tariff.
|
||||
char tariff_version[64];
|
||||
|
||||
///
|
||||
/// \brief free_of_charge_at_start;
|
||||
///
|
||||
/// Free-of-charge minutes at beginning of tariff computation
|
||||
///
|
||||
uint16_t free_of_charge_at_start;
|
||||
|
||||
///
|
||||
/// \brief repeated_default_without_carryover
|
||||
///
|
||||
/// Setting describing a special tariff:
|
||||
/// - All days are equal
|
||||
/// - 24:00 is a "tariff-schnitt" (=without_carryover)
|
||||
/// (i.e. computation is carried out
|
||||
/// on a per day basis. Total price is the sum of all days.)
|
||||
bool repeated_default_without_carryover;
|
||||
|
||||
///
|
||||
/// \brief waiting_period
|
||||
/// @note Also called "Karenzzeit". Allowed values: [0, 3]
|
||||
minute_t waiting_period;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // CALCULATE_PARKING_TICKETS_TARIFF_H_INCLUDED
|
||||
|
175342
results/apcoa_prio_1.txt
175342
results/apcoa_prio_1.txt
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user