public TourModel GetNRandomPlaces(int maxTime, int[] timeList, WeatherEntity weather, SubtypeDataEntity subtypeData, bool addRestaurant, string savedPlaces) { List <PlaceEntity> newTourList = new List <PlaceEntity>(); bool addedRestaurant = false; if (savedPlaces != null) { var places = new List <string>(savedPlaces.Split(',')); for (int i = 0; i < places.Count(); i++) { places[i] = places[i].Trim('"', '[', ']'); } foreach (string name in places) { PlaceEntity place = Tour.Where(i => i.Name == name).FirstOrDefault(); if (place != null) { newTourList.Add(place); maxTime -= 45; Tour = Tour.Where(u => u.Name != place.Name).ToList(); } } if (addedRestaurant) { bool found = false; RestaurantEntity restaurant = new RestaurantEntity(); foreach (string name in places) { restaurant = Restaurants.Where(i => i.Name == name).FirstOrDefault(); if (restaurant != null) { found = true; break; } } if (found) { newTourList.Add(restaurant); Restaurants = Restaurants.Where(u => u.Name != restaurant.Name).ToList(); addedRestaurant = true; } } } if (!addedRestaurant) { if (addRestaurant) { double[] restaurantRatings = new double[Restaurants.Count()]; for (int i = 0; i < Restaurants.Count(); i++) { restaurantRatings[i] = double.Parse(Tour.ElementAt(i).Rating, System.Globalization.CultureInfo.InvariantCulture); } int restaurant_index = GetRandomRestaurantIndex(restaurantRatings); newTourList.Add(Restaurants.ElementAt(restaurant_index)); Restaurants = Restaurants.Where(u => u.Name != Restaurants.ElementAt(restaurant_index).Name).ToList(); } } double[] ratings = new double[Tour.Count()]; for (int i = 0; i < Tour.Count(); i++) { if (Tour.ElementAt(i).Rating != null) { ratings[i] = double.Parse(Tour.ElementAt(i).Rating, System.Globalization.CultureInfo.InvariantCulture); } else { ratings[i] = 3; } } List <int> index_list = GetRandomIndexList(ratings, timeList, maxTime, weather, subtypeData); foreach (int i in index_list) { newTourList.Add(Tour.ElementAt(i)); } int[] index_array = index_list.ToArray(); foreach (int i in index_array) { Tour = Tour.Where(u => u.Name != Tour.ElementAt(i).Name).ToList(); for (int j = 0; j < index_array.Length; j++) { if (index_array[j] > i) { index_array[j] -= 1; } } } return(new TourModel(newTourList)); }
// Factors taken into consideration when generating these indexes: - TripAdvisor ratings // - Time and type of places (for each type of attraction selected, the probability of selecting attractions of the same type is slightly lowered) // - Weather (temperature + humidity) // - Subtype private List <int> GetRandomIndexList(double [] ratings, int [] timeList, int maxTime, WeatherEntity weather, SubtypeDataEntity subtypeData) { List <int> index_list = new List <int>(); double total_score = 0; for (int i = 0; i < ratings.Length; i++) { total_score += ratings[i]; } for (int i = 0; i < ratings.Length; i++) { ratings[i] = ratings[i] / total_score; } Random random = new Random(); double n; int timeCounter = 0; if (timeList.Sum() < maxTime) { return(Enumerable.Range(0, ratings.Length).ToList()); } double temp = weather.Main["temp"] - 273.15; double humidity = weather.Main["humidity"]; List <int> outdoorIndexList = getOutdoorIndexList(subtypeData); (List <int> hotIndexList, List <int> coldIndexList) = getSeasonIndexLists(subtypeData); if (temp > 28) { ratings = AdjustProbability(ratings, hotIndexList.ToArray(), 1.5); ratings = AdjustProbability(ratings, coldIndexList.ToArray(), 0.2); } else if (temp < 10) { ratings = AdjustProbability(ratings, coldIndexList.ToArray(), 1.5); ratings = AdjustProbability(ratings, hotIndexList.ToArray(), 0.2); } if (humidity <= 30) { ratings = AdjustProbability(ratings, outdoorIndexList.ToArray(), 1.2); } else if (humidity <= 70) { ratings = AdjustProbability(ratings, outdoorIndexList.ToArray(), 0.7); } else { ratings = AdjustProbability(ratings, outdoorIndexList.ToArray(), 0.3); } while (timeCounter < maxTime) { if (index_list.Count > 10) { break; } double ratings_prob = 0; n = random.NextDouble(); int rand = 0; for (int i = 0; i < ratings.Length; i++) { ratings_prob += ratings[i]; if (ratings_prob > n) { break; } else { rand = i + 1; } } if (index_list.Contains(rand)) { continue; } else { index_list.Add(rand); timeCounter += timeList[rand]; // for each newly added place slightly adjust the probabilities to favour other types of places on the next choice List <int> to_change = new List <int>(); for (int k = 0; k < ratings.Length; k++) { if (timeList[k] == timeList[rand]) { to_change.Add(k); } } ratings = AdjustProbability(ratings, index_list.ToArray(), 0.9); } } return(index_list); }