Advertisement
Guest User

Untitled

a guest
Jan 10th, 2020
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.21 KB | None | 0 0
  1. Test 1  -  orig: 7.4  new: 8.5  (116.1%)  samu: 10.8  (146.5%)  -  0 stations
  2. Test 2  -  orig: 21.1  new: 20.2  (95.9%)  samu: 22.3  (105.7%)  -  1 station 0 rating
  3. Test 3  -  orig: 19.9  new: 24.7  (123.7%)  samu: 30.5  (152.8%)  -  1 station
  4. Test 4  -  orig: 32.4  new: 77.7  (239.5%)  samu: 180.3  (555.9%)  -  2 stations one company
  5. Test 5  -  orig: 33.2  new: 74.0  (222.8%)  samu: 178.5  (537.6%)  -  2 stations 2 companies
  6. Test 6  -  orig: 48.6  new: 130.0  (267.8%)  samu: 317.3  (653.5%)  -  3 stations 2 companies
  7. Test 7  -  orig: 47.8  new: 136.1  (285.0%)  samu: 304.9  (638.5%)  -  3 stations 1 company
  8. Test 8  -  orig: 153.3  new: 458.8  (299.3%)  samu: 831.3  (542.3%)  -  10 stations 10 companies
  9. Test 9  -  orig: 144.0  new: 478.2  (332.2%)  samu: 842.0  (584.8%)  -  10 stations 1 company
  10. Test 10  -  orig: 145.8  new: 293.0  (201.0%)  samu: 351.8  (241.2%)  -  10 stations but only 3 valid
  11.  
  12. uint MoveGoodsToStationSamu(CargoID type, uint amount, SourceType source_type, SourceID source_id, const StationList *all_stations)
  13. {
  14.     /* Return if nothing to do. Also the rounding below fails for 0. */
  15.     if (all_stations->size() == 0) return 0;
  16.     if (amount == 0) return 0;
  17.  
  18.     Station *first_station = nullptr;
  19.     typedef std::pair<Station *, uint> StationInfo;
  20.     std::vector<StationInfo> used_stations;
  21.  
  22.     for (Station *st : *all_stations) {
  23.         if (!CanMoveGoodsToStation(st, type)) continue;
  24.  
  25.         /* Avoid allocating a vector if there is only one station to significantly
  26.          * improve performance in this common case. */
  27.         if (first_station == nullptr) {
  28.             first_station = st;
  29.             continue;
  30.         }
  31.         if  (used_stations.size() == 0) {
  32.             used_stations.reserve(2);
  33.             used_stations.emplace_back(std::make_pair(first_station, 0));
  34.         }
  35.         used_stations.emplace_back(std::make_pair(st, 0));
  36.     }
  37.  
  38.     /* no stations around at all? */
  39.     if (first_station == nullptr) return 0;
  40.  
  41.     if (used_stations.size() == 0) {
  42.         /* only one station around */
  43.         amount *= (first_station->goods[type].rating + 1);
  44.         return UpdateStationWaiting(first_station, type, amount, source_type, source_id);
  45.     }
  46.  
  47.     uint company_best[OWNER_NONE + 1] = {};  // best rating for each company, including OWNER_NONE
  48.     uint company_sum[OWNER_NONE + 1] = {};   // sum of ratings for each company
  49.     uint best_rating = 0;
  50.     uint best_sum = 0;  // sum of best ratings for each company
  51.  
  52.     for (auto &p : used_stations) {
  53.         auto owner = p.first->owner;
  54.         auto rating = p.first->goods[type].rating;
  55.         if (rating > company_best[owner]) {
  56.             best_sum += rating - company_best[owner];  // it's usually faster than iterating companies later
  57.             company_best[owner] = rating;
  58.             if (rating > best_rating) best_rating = rating;
  59.         }
  60.         company_sum[owner] += rating;
  61.     }
  62.  
  63.     /* From now we'll calculate with fractional cargo amounts.
  64.      * First determine how much cargo we really have. */
  65.     amount *= best_rating + 1;
  66.  
  67.     uint moving = 0;
  68.     for (auto &p : used_stations) {
  69.         uint st_owner = p.first->owner;
  70.         /* Multiply the amount by (company best / sum of best for each company) to get cargo allocated to a company
  71.          * and by (station rating / sum of ratings in a company) to get the result for a single station. */
  72.         p.second = amount * company_best[st_owner] * p.first->goods[type].rating / best_sum / company_sum[st_owner];
  73.         moving += p.second;
  74.     }
  75.  
  76.     /* If there is some cargo left due to rounding issues distribute it among the best rated stations.  */
  77.     if (amount > moving) {
  78.         std::sort(used_stations.begin(), used_stations.end(), [type] (const StationInfo &a, const StationInfo &b) {
  79.             return b.first->goods[type].rating < a.first->goods[type].rating;
  80.         });
  81.  
  82.         assert(amount - moving <= used_stations.size());
  83.         for (uint i = 0; i < amount - moving; i++) {
  84.             used_stations[i].second++;
  85.         }
  86.     }
  87.  
  88.     uint moved = 0;
  89.     for (auto &p : used_stations) {
  90.         moved += UpdateStationWaiting(p.first, type, p.second, source_type, source_id);
  91.     }
  92.  
  93.     return moved;
  94. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement