Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using MySql.Data.MySqlClient;
- using Rittenplanner.Objects;
- using Rittenplanner.Repositories;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using TAXICONNECT_BASE;
- using TAXICONNECT_BASE.Repositories;
- namespace Rittenplanner.Functions
- {
- public static class Generate
- {
- /// <summary>
- /// asdfasdf
- /// </summary>
- /// <param name="rides">sdfads</param>
- /// <returns>asdfasdf</returns>
- public static List<Schedule> GenerateSchedules(List<Ride> rides)
- {
- List<Schedule> scheduleList = new List<Schedule>();
- for (int i = 1; true; ++i)
- {
- Schedule bestSchedule = new Schedule(i + 100);
- List<Ride> unscheduledAndEligibleRides = new List<Ride>();
- //pick out all the eligible and unscheduled rides from the ridelist
- //because only rides that are eligible AND unscheduled, can be scheduled
- foreach (Ride ride in rides)
- {
- if (ride.IsScheduledForADriver == 0 && ride.IsCancelled == 0 && ride.IsTransferred == 0)
- unscheduledAndEligibleRides.Add(ride);
- }
- //use every ride as a starting point for a schedule, and pick the best schedule in the process
- //you'll end up with 1 best schedule for all the unscheduledAndEligibleRides
- foreach (Ride ride in unscheduledAndEligibleRides)
- {
- Schedule schedule = new Schedule(i);
- (double, double) DistanceDuration_ReferencePointToFirstRide = (0, 0);
- //check and (if it exists) get the CACHED distance and duration for the FIRST ride in the schedule (referencepoint --> first ride)
- (bool, Combination) GetCombination1 = MysqlRepository.GetCombination(Settings_Planningen.ReferentieStad.Adr_Lat, Settings_Planningen.ReferentieStad.Adr_Long, ride.AdrFromLat, ride.AdrFromLong);
- //if the combination is in fact cached
- if (GetCombination1.Item1)
- {
- //pass it to DistanceDuration_ReferencePointToFirstRide
- DistanceDuration_ReferencePointToFirstRide = (GetCombination1.Item2.RideDistance, GetCombination1.Item2.RideDuration);
- }
- //if the combination is NOT cached
- else
- {
- //get the combination (distance and duration) from maps
- DistanceDuration_ReferencePointToFirstRide = new GoogleMapsRepository().CalculateDistanceDurationManual(Settings_Planningen.ReferentieStad.Adr_Lat, Settings_Planningen.ReferentieStad.Adr_Long, ride.AdrFromLat, ride.AdrFromLong);
- //cache it both ways (insert in the database),
- InsertCombination(Settings_Planningen.ReferentieStad.Adr_Lat, Settings_Planningen.ReferentieStad.Adr_Long, ride.AdrFromLat, ride.AdrFromLong, DistanceDuration_ReferencePointToFirstRide.Item1, DistanceDuration_ReferencePointToFirstRide.Item2);
- InsertCombination(ride.AdrFromLat, ride.AdrFromLong, Settings_Planningen.ReferentieStad.Adr_Lat, Settings_Planningen.ReferentieStad.Adr_Long, DistanceDuration_ReferencePointToFirstRide.Item1, DistanceDuration_ReferencePointToFirstRide.Item2);
- }
- //add the first ride to the current schedule
- schedule.AddRide(ride, DistanceDuration_ReferencePointToFirstRide.Item2, DistanceDuration_ReferencePointToFirstRide.Item1);
- //after adding the first ride, pass it to GenerateSchedule: it will take it from there
- schedule = GenerateSchedule(unscheduledAndEligibleRides, schedule);
- //depending on which setting it's generating, bestSchedule will be overwritten if certain conditions are met
- if (Settings_Planningen.HoogstHaalbareOmzet)
- {
- if (schedule.TotalRevenue > bestSchedule.TotalRevenue) //OLD: schedule.AveragePricePerHour > BestSchedule.AveragePricePerHour && schedule.TotalHours > 9
- {
- bestSchedule = schedule;
- }
- }
- else if (Settings_Planningen.HoogstHaalbareUurTarief)
- {
- if (schedule.AveragePricePerHour > bestSchedule.AveragePricePerHour && schedule.TotalRevenue > Settings_Planningen.MinimaleOmzetPerPlanning && schedule.TotalHours > Settings_Planningen.MinimaleArbeidsTijdPerPlanning) //OUD: schedule.AveragePricePerHour > BestSchedule.AveragePricePerHour && schedule.TotalHours > 9
- {
- bestSchedule = schedule;
- }
- }
- else if (Settings_Planningen.HoogstHaalbareKilometerTarief)
- {
- if (schedule.AveragePricePerKm > bestSchedule.AveragePricePerKm && schedule.TotalRevenue > Settings_Planningen.MinimaleOmzetPerPlanning && schedule.TotalHours > Settings_Planningen.MinimaleArbeidsTijdPerPlanning) //OUD: schedule.AveragePricePerHour > BestSchedule.AveragePricePerHour && schedule.TotalHours > 9
- {
- bestSchedule = schedule;
- }
- }
- }
- if (Settings_Planningen.HoogstHaalbareUurTarief)
- bestSchedule.TargetPricePerHour = Settings_Planningen.StreefBedragPerUur;
- else if (Settings_Planningen.HoogstHaalbareOmzet)
- bestSchedule.TargetRevenue = Settings_Planningen.StreefOmzet;
- else if (Settings_Planningen.HoogstHaalbareKilometerTarief)
- bestSchedule.TargetPricePerKm = Settings_Planningen.StreefBedragPerKm;
- //check if the generated bestSchedule still fits the minimum requirements
- //otherwise it will keep generating until there are no more unscheduledRides left
- if (bestSchedule.AveragePricePerHour >= Settings_Planningen.MinimaleUurtariefPerPlanning && bestSchedule.TotalRevenue >= Settings_Planningen.MinimaleOmzetPerPlanning && bestSchedule.TotalHours >= Settings_Planningen.MinimaleArbeidsTijdPerPlanning) //OLD: BestSchedule.AveragePricePerHour >= 25 && BestSchedule.TotalRevenue >= 250
- {
- //add the bestSchedule to the scheduleList that will be returned
- scheduleList.Add(bestSchedule);
- //mark all the rides in the bestSchedule as IsScheduledForADriver
- //otherwise they will be used again next time while generating
- foreach (Ride ride1 in rides)
- {
- foreach (Ride ride2 in bestSchedule.ridelist)
- {
- if (ride1 == ride2)
- {
- ride1.IsScheduledForADriver = 1;
- }
- }
- }
- }
- //if the minimum requirements are not fit, it will break
- //reason for this is because it generates from best schedule to least best schedule: downward
- //this is logical, because it generates with the most choices, to least choices.
- else
- break;
- }
- return scheduleList;
- }
- /// <summary>
- /// asdfasdf
- /// </summary>
- /// <param name="rides">asdf</param>
- /// <param name="schedule">adsfasdf</param>
- /// <returns></returns>
- private static Schedule GenerateSchedule(List<Ride> rides, Schedule schedule)
- {
- //the schedule has to be less than 12 hours in time, at all times, this is required by law
- while (schedule.TotalHours <= 12)
- {
- Ride nextride = new Ride();
- double duration = 0;
- double distance = 0;
- double priceperhour = 0;
- bool StillHasEligibleRides = false;
- foreach (Ride ride in rides)
- {
- //extra check
- if (ride.RideDistance != 0 && ride.RideDuration != 0)
- {
- DateTime StartTime = schedule.MovingTime;
- DateTime EndTime = ride.DateTimeValue;
- TimeSpan TimeSpanGap = EndTime.Subtract(StartTime);
- //if the start time of this particular ride is NOT in the past
- if (TimeSpanGap.TotalMinutes > 0)
- {
- (double, double) DistanceDurationEndPreviousRideToBeginNextRide = (0, 0);
- //check and (if it exists) get the CACHED distance and duration for the FIRST ride in the schedule (referencepoint --> first ride)
- (bool, Combination) GetCombination1 = MysqlRepository.GetCombination(schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLat, schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLong, ride.AdrFromLat, ride.AdrFromLong);
- //if the combination is cached
- if (GetCombination1.Item1 == true)
- {
- //pass it to DistanceDurationEndPreviousRideToBeginNextRide
- DistanceDurationEndPreviousRideToBeginNextRide = (GetCombination1.Item2.RideDistance, GetCombination1.Item2.RideDuration);
- }
- //if the combination is NOT cached
- else
- {
- //get the combination (distance and duration) from maps
- DistanceDurationEndPreviousRideToBeginNextRide = new GoogleMapsRepository().CalculateDistanceDurationManual(schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLat, schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLong, ride.AdrFromLat, ride.AdrFromLong);
- //cache it both ways (insert into database)
- InsertCombination(schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLat, schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLong, ride.AdrFromLat, ride.AdrFromLong, DistanceDurationEndPreviousRideToBeginNextRide.Item1, DistanceDurationEndPreviousRideToBeginNextRide.Item2);
- InsertCombination(ride.AdrFromLat, ride.AdrFromLong, schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLat, schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLong, DistanceDurationEndPreviousRideToBeginNextRide.Item1, DistanceDurationEndPreviousRideToBeginNextRide.Item2);
- }
- //if - from the current position and at the current movingtime - the duration to the pickup address is less than the timespan gap
- //this means if it is achievable to get on time (adjusted to traffic) to the pickup address, from the current position and at the current movingtime
- if (TimeSpanGap.TotalMinutes >= TrafficFunctions.AdjustRideDuration(StartTime, DistanceDurationEndPreviousRideToBeginNextRide.Item2)) //als de rit NIET al is gepland en ÜBERHAUPT wel HAALBAAR is
- {
- //add the timespan gap (moving time + rideduration), to give a value translated to a price per hour
- //this will help determine the value of each ride
- double TotalMinutes = TimeSpanGap.TotalMinutes + TrafficFunctions.AdjustRideDuration(StartTime, ride.RideDuration);
- double PricePerHour = (ride.PriceValue / TotalMinutes) * 60;
- //add a minimum value of each ride, so that it won't have to choose between bad rides. there HAS to be a hardcoded minimum here
- if (PricePerHour > priceperhour && PricePerHour >= 10) //WAS 15!
- {
- if ((((schedule.TotalHours * 60) + TotalMinutes) / 60) <= 12) //if adding this ride doesn't make the schedule have more than 12 working hours
- {
- StillHasEligibleRides = true;
- priceperhour = PricePerHour;
- duration = TimeSpanGap.TotalMinutes;
- distance = DistanceDurationEndPreviousRideToBeginNextRide.Item1;
- nextride = ride;
- }
- }
- }
- }
- }
- }
- //check if there are still elibigle rides
- //if this is false, it means that after a full foreach loop, not a single eligible ride was found
- if (StillHasEligibleRides == true)
- schedule.AddRide(nextride, duration, distance);
- //break if it's false. the schedule is done
- else
- break;
- }
- //1 calculate the distance duration of the AdrTo (of the last ride) to the referencepoint
- //2 add it to the end of the schedule, and check if totalhours isn't above 12 hours
- //3 if it is above 12 hours, delete the last ride and try step 1 again
- //4 if it is not above 12 hours, add the ride information to the schedule
- while (true)
- {
- (double, double) DistanceDurationEndLastRideToHome = (0, 0);
- (bool, Combination) GetCombination1 = MysqlRepository.GetCombination(schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLat, schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLong, Settings_Planningen.ReferentieStad.Adr_Lat, Settings_Planningen.ReferentieStad.Adr_Long);
- if (GetCombination1.Item1 == true)
- {
- Combination combination = GetCombination1.Item2;
- DistanceDurationEndLastRideToHome = (combination.RideDistance, combination.RideDuration);
- }
- else
- {
- DistanceDurationEndLastRideToHome = new GoogleMapsRepository().CalculateDistanceDurationManual(schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLat, schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLong, Settings_Planningen.ReferentieStad.Adr_Lat, Settings_Planningen.ReferentieStad.Adr_Long);
- InsertCombination(schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLat, schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLong, Settings_Planningen.ReferentieStad.Adr_Lat, Settings_Planningen.ReferentieStad.Adr_Long, DistanceDurationEndLastRideToHome.Item1, DistanceDurationEndLastRideToHome.Item2);
- InsertCombination(Settings_Planningen.ReferentieStad.Adr_Lat, Settings_Planningen.ReferentieStad.Adr_Long, schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLat, schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLong, DistanceDurationEndLastRideToHome.Item1, DistanceDurationEndLastRideToHome.Item2);
- }
- //if it is less than 12 hours, add the ride information and break. return the schedule.
- if ((schedule.TotalHours + (DistanceDurationEndLastRideToHome.Item2 / 60)) <= 12)
- {
- schedule.MovingTime = schedule.MovingTime.AddMinutes(DistanceDurationEndLastRideToHome.Item2);
- schedule.DistanceOnbeladen += DistanceDurationEndLastRideToHome.Item1;
- DateTime StartTime = schedule.StartingTime;
- DateTime EndTime = schedule.MovingTime;
- TimeSpan Span = EndTime.Subtract(StartTime);
- schedule.TotalHours = Span.TotalHours;
- schedule.PercentageBeladen = (schedule.DistanceBeladen * 100) / (schedule.DistanceBeladen + schedule.DistanceOnbeladen);
- schedule.PercentageOnbeladen = (schedule.DistanceOnbeladen * 100) / (schedule.DistanceBeladen + schedule.DistanceOnbeladen);
- break;
- }
- //if it is NOT less than 12 hours, delete the last ride in the schedule
- else
- {
- (double, double) DistanceDurationEndOpEenNaLaatsteRideToLastRide = (0, 0);
- (bool, Combination) GetCombination2 = MysqlRepository.GetCombination(schedule.ridelist[schedule.ridelist.Count() - 1].AdrToLat, schedule.ridelist[schedule.ridelist.Count() - 1].AdrToLong, schedule.ridelist[schedule.ridelist.Count() - 1].AdrFromLat, schedule.ridelist[schedule.ridelist.Count() - 1].AdrFromLong);
- if (GetCombination2.Item1 == true)
- {
- Combination combination = GetCombination2.Item2;
- DistanceDurationEndOpEenNaLaatsteRideToLastRide = (combination.RideDistance, combination.RideDuration);
- }
- else
- {
- DistanceDurationEndOpEenNaLaatsteRideToLastRide = new GoogleMapsRepository().CalculateDistanceDurationManual(schedule.ridelist[schedule.ridelist.Count() - 1].AdrToLat, schedule.ridelist[schedule.ridelist.Count() - 1].AdrToLong, schedule.ridelist[schedule.ridelist.Count() - 1].AdrFromLat, schedule.ridelist[schedule.ridelist.Count() - 1].AdrFromLong);
- InsertCombination(schedule.ridelist[schedule.ridelist.Count() - 1].AdrToLat, schedule.ridelist[schedule.ridelist.Count() - 1].AdrToLong, schedule.ridelist[schedule.ridelist.Count() - 1].AdrFromLat, schedule.ridelist[schedule.ridelist.Count() - 1].AdrFromLong, DistanceDurationEndOpEenNaLaatsteRideToLastRide.Item1, DistanceDurationEndOpEenNaLaatsteRideToLastRide.Item2);
- InsertCombination(schedule.ridelist[schedule.ridelist.Count() - 1].AdrFromLat, schedule.ridelist[schedule.ridelist.Count() - 1].AdrFromLong, schedule.ridelist[schedule.ridelist.Count() - 1].AdrToLat, schedule.ridelist[schedule.ridelist.Count() - 1].AdrToLong, DistanceDurationEndOpEenNaLaatsteRideToLastRide.Item1, DistanceDurationEndOpEenNaLaatsteRideToLastRide.Item2);
- }
- schedule.RemoveRide(schedule.ridelist[schedule.ridelist.Count() - 1], DistanceDurationEndOpEenNaLaatsteRideToLastRide.Item1, DistanceDurationEndOpEenNaLaatsteRideToLastRide.Item2);
- }
- }
- //a last-minute avg price per km calcuation
- schedule.AveragePricePerKm = Math.Round(schedule.TotalRevenue / (schedule.DistanceBeladen + schedule.DistanceOnbeladen), 2);
- return schedule;
- }
- /// <summary>
- /// Insert a combination in the database. Use it to cache Distance Duration, in order to save Maps requests. Expensive as hell!
- /// </summary>
- /// <param name="AdrFromLat"></param>
- /// <param name="AdrFromLong"></param>
- /// <param name="AdrToLat"></param>
- /// <param name="AdrToLong"></param>
- /// <param name="RideDistance"></param>
- /// <param name="RideDuration"></param>
- private static void InsertCombination(object AdrFromLat, object AdrFromLong, object AdrToLat, object AdrToLong, object RideDistance, object RideDuration)
- {
- try
- {
- using (MySqlConnection connection = new MySqlConnection(string.Format(Secrets.connectionstring)))
- {
- connection.Open();
- try
- {
- using (var cmd = new MySqlCommand("INSERT into rittenplanner_combinations (AdrFromLat, AdrFromLong, AdrToLat, AdrToLong, RideDistance, RideDuration) VALUES (@AdrFromLat, @AdrFromLong, @AdrToLat, @AdrToLong, @RideDistance, @RideDuration);", connection))
- {
- cmd.Parameters.AddWithValue("@AdrFromLat", AdrFromLat);
- cmd.Parameters.AddWithValue("@AdrFromLong", AdrFromLong);
- cmd.Parameters.AddWithValue("@AdrToLat", AdrToLat);
- cmd.Parameters.AddWithValue("@AdrToLong", AdrToLong);
- cmd.Parameters.AddWithValue("@RideDistance", RideDistance);
- cmd.Parameters.AddWithValue("@RideDuration", RideDuration);
- cmd.ExecuteNonQuery();
- }
- }
- catch (Exception ex)
- {
- Form1.UploadException(ex, "InsertCombination");
- }
- finally
- {
- connection.Close();
- }
- }
- }
- catch (Exception ex)
- {
- Form1.UploadException(ex, "InsertCombination");
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement