Advertisement
Guest User

Untitled

a guest
Feb 23rd, 2019
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.43 KB | None | 0 0
  1. using MySql.Data.MySqlClient;
  2. using Rittenplanner.Objects;
  3. using Rittenplanner.Repositories;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using TAXICONNECT_BASE;
  10. using TAXICONNECT_BASE.Repositories;
  11.  
  12. namespace Rittenplanner.Functions
  13. {
  14. public static class Generate
  15. {
  16. /// <summary>
  17. /// asdfasdf
  18. /// </summary>
  19. /// <param name="rides">sdfads</param>
  20. /// <returns>asdfasdf</returns>
  21. public static List<Schedule> GenerateSchedules(List<Ride> rides)
  22. {
  23. List<Schedule> scheduleList = new List<Schedule>();
  24.  
  25. for (int i = 1; true; ++i)
  26. {
  27. Schedule bestSchedule = new Schedule(i + 100);
  28. List<Ride> unscheduledAndEligibleRides = new List<Ride>();
  29.  
  30. //pick out all the eligible and unscheduled rides from the ridelist
  31. //because only rides that are eligible AND unscheduled, can be scheduled
  32. foreach (Ride ride in rides)
  33. {
  34. if (ride.IsScheduledForADriver == 0 && ride.IsCancelled == 0 && ride.IsTransferred == 0)
  35. unscheduledAndEligibleRides.Add(ride);
  36. }
  37.  
  38. //use every ride as a starting point for a schedule, and pick the best schedule in the process
  39. //you'll end up with 1 best schedule for all the unscheduledAndEligibleRides
  40. foreach (Ride ride in unscheduledAndEligibleRides)
  41. {
  42. Schedule schedule = new Schedule(i);
  43.  
  44. (double, double) DistanceDuration_ReferencePointToFirstRide = (0, 0);
  45.  
  46. //check and (if it exists) get the CACHED distance and duration for the FIRST ride in the schedule (referencepoint --> first ride)
  47. (bool, Combination) GetCombination1 = MysqlRepository.GetCombination(Settings_Planningen.ReferentieStad.Adr_Lat, Settings_Planningen.ReferentieStad.Adr_Long, ride.AdrFromLat, ride.AdrFromLong);
  48.  
  49. //if the combination is in fact cached
  50. if (GetCombination1.Item1)
  51. {
  52. //pass it to DistanceDuration_ReferencePointToFirstRide
  53. DistanceDuration_ReferencePointToFirstRide = (GetCombination1.Item2.RideDistance, GetCombination1.Item2.RideDuration);
  54. }
  55. //if the combination is NOT cached
  56. else
  57. {
  58. //get the combination (distance and duration) from maps
  59. DistanceDuration_ReferencePointToFirstRide = new GoogleMapsRepository().CalculateDistanceDurationManual(Settings_Planningen.ReferentieStad.Adr_Lat, Settings_Planningen.ReferentieStad.Adr_Long, ride.AdrFromLat, ride.AdrFromLong);
  60.  
  61. //cache it both ways (insert in the database),
  62. InsertCombination(Settings_Planningen.ReferentieStad.Adr_Lat, Settings_Planningen.ReferentieStad.Adr_Long, ride.AdrFromLat, ride.AdrFromLong, DistanceDuration_ReferencePointToFirstRide.Item1, DistanceDuration_ReferencePointToFirstRide.Item2);
  63. InsertCombination(ride.AdrFromLat, ride.AdrFromLong, Settings_Planningen.ReferentieStad.Adr_Lat, Settings_Planningen.ReferentieStad.Adr_Long, DistanceDuration_ReferencePointToFirstRide.Item1, DistanceDuration_ReferencePointToFirstRide.Item2);
  64. }
  65.  
  66. //add the first ride to the current schedule
  67. schedule.AddRide(ride, DistanceDuration_ReferencePointToFirstRide.Item2, DistanceDuration_ReferencePointToFirstRide.Item1);
  68. //after adding the first ride, pass it to GenerateSchedule: it will take it from there
  69. schedule = GenerateSchedule(unscheduledAndEligibleRides, schedule);
  70.  
  71. //depending on which setting it's generating, bestSchedule will be overwritten if certain conditions are met
  72. if (Settings_Planningen.HoogstHaalbareOmzet)
  73. {
  74. if (schedule.TotalRevenue > bestSchedule.TotalRevenue) //OLD: schedule.AveragePricePerHour > BestSchedule.AveragePricePerHour && schedule.TotalHours > 9
  75. {
  76. bestSchedule = schedule;
  77. }
  78. }
  79. else if (Settings_Planningen.HoogstHaalbareUurTarief)
  80. {
  81. if (schedule.AveragePricePerHour > bestSchedule.AveragePricePerHour && schedule.TotalRevenue > Settings_Planningen.MinimaleOmzetPerPlanning && schedule.TotalHours > Settings_Planningen.MinimaleArbeidsTijdPerPlanning) //OUD: schedule.AveragePricePerHour > BestSchedule.AveragePricePerHour && schedule.TotalHours > 9
  82. {
  83. bestSchedule = schedule;
  84. }
  85. }
  86. else if (Settings_Planningen.HoogstHaalbareKilometerTarief)
  87. {
  88. if (schedule.AveragePricePerKm > bestSchedule.AveragePricePerKm && schedule.TotalRevenue > Settings_Planningen.MinimaleOmzetPerPlanning && schedule.TotalHours > Settings_Planningen.MinimaleArbeidsTijdPerPlanning) //OUD: schedule.AveragePricePerHour > BestSchedule.AveragePricePerHour && schedule.TotalHours > 9
  89. {
  90. bestSchedule = schedule;
  91. }
  92. }
  93.  
  94. }
  95.  
  96. if (Settings_Planningen.HoogstHaalbareUurTarief)
  97. bestSchedule.TargetPricePerHour = Settings_Planningen.StreefBedragPerUur;
  98. else if (Settings_Planningen.HoogstHaalbareOmzet)
  99. bestSchedule.TargetRevenue = Settings_Planningen.StreefOmzet;
  100. else if (Settings_Planningen.HoogstHaalbareKilometerTarief)
  101. bestSchedule.TargetPricePerKm = Settings_Planningen.StreefBedragPerKm;
  102.  
  103. //check if the generated bestSchedule still fits the minimum requirements
  104. //otherwise it will keep generating until there are no more unscheduledRides left
  105. if (bestSchedule.AveragePricePerHour >= Settings_Planningen.MinimaleUurtariefPerPlanning && bestSchedule.TotalRevenue >= Settings_Planningen.MinimaleOmzetPerPlanning && bestSchedule.TotalHours >= Settings_Planningen.MinimaleArbeidsTijdPerPlanning) //OLD: BestSchedule.AveragePricePerHour >= 25 && BestSchedule.TotalRevenue >= 250
  106. {
  107. //add the bestSchedule to the scheduleList that will be returned
  108. scheduleList.Add(bestSchedule);
  109.  
  110. //mark all the rides in the bestSchedule as IsScheduledForADriver
  111. //otherwise they will be used again next time while generating
  112. foreach (Ride ride1 in rides)
  113. {
  114. foreach (Ride ride2 in bestSchedule.ridelist)
  115. {
  116. if (ride1 == ride2)
  117. {
  118. ride1.IsScheduledForADriver = 1;
  119. }
  120. }
  121. }
  122.  
  123. }
  124. //if the minimum requirements are not fit, it will break
  125. //reason for this is because it generates from best schedule to least best schedule: downward
  126. //this is logical, because it generates with the most choices, to least choices.
  127. else
  128. break;
  129. }
  130.  
  131. return scheduleList;
  132. }
  133.  
  134. /// <summary>
  135. /// asdfasdf
  136. /// </summary>
  137. /// <param name="rides">asdf</param>
  138. /// <param name="schedule">adsfasdf</param>
  139. /// <returns></returns>
  140. private static Schedule GenerateSchedule(List<Ride> rides, Schedule schedule)
  141. {
  142. //the schedule has to be less than 12 hours in time, at all times, this is required by law
  143. while (schedule.TotalHours <= 12)
  144. {
  145. Ride nextride = new Ride();
  146.  
  147. double duration = 0;
  148. double distance = 0;
  149. double priceperhour = 0;
  150.  
  151. bool StillHasEligibleRides = false;
  152.  
  153. foreach (Ride ride in rides)
  154. {
  155. //extra check
  156. if (ride.RideDistance != 0 && ride.RideDuration != 0)
  157. {
  158. DateTime StartTime = schedule.MovingTime;
  159. DateTime EndTime = ride.DateTimeValue;
  160. TimeSpan TimeSpanGap = EndTime.Subtract(StartTime);
  161.  
  162. //if the start time of this particular ride is NOT in the past
  163. if (TimeSpanGap.TotalMinutes > 0)
  164. {
  165. (double, double) DistanceDurationEndPreviousRideToBeginNextRide = (0, 0);
  166.  
  167. //check and (if it exists) get the CACHED distance and duration for the FIRST ride in the schedule (referencepoint --> first ride)
  168. (bool, Combination) GetCombination1 = MysqlRepository.GetCombination(schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLat, schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLong, ride.AdrFromLat, ride.AdrFromLong);
  169.  
  170. //if the combination is cached
  171. if (GetCombination1.Item1 == true)
  172. {
  173. //pass it to DistanceDurationEndPreviousRideToBeginNextRide
  174. DistanceDurationEndPreviousRideToBeginNextRide = (GetCombination1.Item2.RideDistance, GetCombination1.Item2.RideDuration);
  175. }
  176. //if the combination is NOT cached
  177. else
  178. {
  179. //get the combination (distance and duration) from maps
  180. DistanceDurationEndPreviousRideToBeginNextRide = new GoogleMapsRepository().CalculateDistanceDurationManual(schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLat, schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLong, ride.AdrFromLat, ride.AdrFromLong);
  181.  
  182. //cache it both ways (insert into database)
  183. InsertCombination(schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLat, schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLong, ride.AdrFromLat, ride.AdrFromLong, DistanceDurationEndPreviousRideToBeginNextRide.Item1, DistanceDurationEndPreviousRideToBeginNextRide.Item2);
  184. InsertCombination(ride.AdrFromLat, ride.AdrFromLong, schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLat, schedule.ridelist[(schedule.ridelist.Count() - 1)].AdrToLong, DistanceDurationEndPreviousRideToBeginNextRide.Item1, DistanceDurationEndPreviousRideToBeginNextRide.Item2);
  185. }
  186.  
  187. //if - from the current position and at the current movingtime - the duration to the pickup address is less than the timespan gap
  188. //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
  189. if (TimeSpanGap.TotalMinutes >= TrafficFunctions.AdjustRideDuration(StartTime, DistanceDurationEndPreviousRideToBeginNextRide.Item2)) //als de rit NIET al is gepland en ÜBERHAUPT wel HAALBAAR is
  190. {
  191. //add the timespan gap (moving time + rideduration), to give a value translated to a price per hour
  192. //this will help determine the value of each ride
  193. double TotalMinutes = TimeSpanGap.TotalMinutes + TrafficFunctions.AdjustRideDuration(StartTime, ride.RideDuration);
  194. double PricePerHour = (ride.PriceValue / TotalMinutes) * 60;
  195.  
  196. //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
  197. if (PricePerHour > priceperhour && PricePerHour >= 10) //WAS 15!
  198. {
  199. if ((((schedule.TotalHours * 60) + TotalMinutes) / 60) <= 12) //if adding this ride doesn't make the schedule have more than 12 working hours
  200. {
  201. StillHasEligibleRides = true;
  202. priceperhour = PricePerHour;
  203. duration = TimeSpanGap.TotalMinutes;
  204. distance = DistanceDurationEndPreviousRideToBeginNextRide.Item1;
  205. nextride = ride;
  206. }
  207. }
  208. }
  209. }
  210. }
  211. }
  212.  
  213. //check if there are still elibigle rides
  214. //if this is false, it means that after a full foreach loop, not a single eligible ride was found
  215. if (StillHasEligibleRides == true)
  216. schedule.AddRide(nextride, duration, distance);
  217. //break if it's false. the schedule is done
  218. else
  219. break;
  220. }
  221.  
  222. //1 calculate the distance duration of the AdrTo (of the last ride) to the referencepoint
  223. //2 add it to the end of the schedule, and check if totalhours isn't above 12 hours
  224. //3 if it is above 12 hours, delete the last ride and try step 1 again
  225. //4 if it is not above 12 hours, add the ride information to the schedule
  226.  
  227. while (true)
  228. {
  229. (double, double) DistanceDurationEndLastRideToHome = (0, 0);
  230.  
  231. (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);
  232.  
  233. if (GetCombination1.Item1 == true)
  234. {
  235. Combination combination = GetCombination1.Item2;
  236. DistanceDurationEndLastRideToHome = (combination.RideDistance, combination.RideDuration);
  237. }
  238. else
  239. {
  240. 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);
  241.  
  242. 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);
  243. 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);
  244. }
  245.  
  246. //if it is less than 12 hours, add the ride information and break. return the schedule.
  247. if ((schedule.TotalHours + (DistanceDurationEndLastRideToHome.Item2 / 60)) <= 12)
  248. {
  249.  
  250.  
  251. schedule.MovingTime = schedule.MovingTime.AddMinutes(DistanceDurationEndLastRideToHome.Item2);
  252. schedule.DistanceOnbeladen += DistanceDurationEndLastRideToHome.Item1;
  253.  
  254. DateTime StartTime = schedule.StartingTime;
  255. DateTime EndTime = schedule.MovingTime;
  256. TimeSpan Span = EndTime.Subtract(StartTime);
  257. schedule.TotalHours = Span.TotalHours;
  258.  
  259. schedule.PercentageBeladen = (schedule.DistanceBeladen * 100) / (schedule.DistanceBeladen + schedule.DistanceOnbeladen);
  260. schedule.PercentageOnbeladen = (schedule.DistanceOnbeladen * 100) / (schedule.DistanceBeladen + schedule.DistanceOnbeladen);
  261.  
  262. break;
  263. }
  264. //if it is NOT less than 12 hours, delete the last ride in the schedule
  265. else
  266. {
  267. (double, double) DistanceDurationEndOpEenNaLaatsteRideToLastRide = (0, 0);
  268.  
  269. (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);
  270.  
  271. if (GetCombination2.Item1 == true)
  272. {
  273. Combination combination = GetCombination2.Item2;
  274. DistanceDurationEndOpEenNaLaatsteRideToLastRide = (combination.RideDistance, combination.RideDuration);
  275. }
  276. else
  277. {
  278. 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);
  279.  
  280. 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);
  281. 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);
  282.  
  283. }
  284.  
  285. schedule.RemoveRide(schedule.ridelist[schedule.ridelist.Count() - 1], DistanceDurationEndOpEenNaLaatsteRideToLastRide.Item1, DistanceDurationEndOpEenNaLaatsteRideToLastRide.Item2);
  286. }
  287. }
  288.  
  289. //a last-minute avg price per km calcuation
  290. schedule.AveragePricePerKm = Math.Round(schedule.TotalRevenue / (schedule.DistanceBeladen + schedule.DistanceOnbeladen), 2);
  291.  
  292. return schedule;
  293. }
  294.  
  295. /// <summary>
  296. /// Insert a combination in the database. Use it to cache Distance Duration, in order to save Maps requests. Expensive as hell!
  297. /// </summary>
  298. /// <param name="AdrFromLat"></param>
  299. /// <param name="AdrFromLong"></param>
  300. /// <param name="AdrToLat"></param>
  301. /// <param name="AdrToLong"></param>
  302. /// <param name="RideDistance"></param>
  303. /// <param name="RideDuration"></param>
  304. private static void InsertCombination(object AdrFromLat, object AdrFromLong, object AdrToLat, object AdrToLong, object RideDistance, object RideDuration)
  305. {
  306. try
  307. {
  308. using (MySqlConnection connection = new MySqlConnection(string.Format(Secrets.connectionstring)))
  309. {
  310. connection.Open();
  311. try
  312. {
  313. using (var cmd = new MySqlCommand("INSERT into rittenplanner_combinations (AdrFromLat, AdrFromLong, AdrToLat, AdrToLong, RideDistance, RideDuration) VALUES (@AdrFromLat, @AdrFromLong, @AdrToLat, @AdrToLong, @RideDistance, @RideDuration);", connection))
  314. {
  315. cmd.Parameters.AddWithValue("@AdrFromLat", AdrFromLat);
  316. cmd.Parameters.AddWithValue("@AdrFromLong", AdrFromLong);
  317. cmd.Parameters.AddWithValue("@AdrToLat", AdrToLat);
  318. cmd.Parameters.AddWithValue("@AdrToLong", AdrToLong);
  319. cmd.Parameters.AddWithValue("@RideDistance", RideDistance);
  320. cmd.Parameters.AddWithValue("@RideDuration", RideDuration);
  321. cmd.ExecuteNonQuery();
  322. }
  323. }
  324. catch (Exception ex)
  325. {
  326. Form1.UploadException(ex, "InsertCombination");
  327. }
  328. finally
  329. {
  330. connection.Close();
  331. }
  332. }
  333. }
  334. catch (Exception ex)
  335. {
  336. Form1.UploadException(ex, "InsertCombination");
  337. }
  338. }
  339. }
  340. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement