Example #1
0
        public async Task <PlanElementCandidate> GenerateAsync(DecisionArray decisionArray, Plan plan, int whichMeal, PlanElementIteratorParams iterParams)
        {
            var test = true;
            //choose type based on preferences
            var type                  = (plan.PlanForm.FoodPreference == FoodPreference.OnlyRestaurant || (plan.PlanForm.FoodPreference == FoodPreference.Mixed && whichMeal == 2)) ? GooglePlaceTypeCategory.Restaurant : GooglePlaceTypeCategory.Food;
            var candidates            = new List <PlanElementCandidate>();
            var decisionRows          = new List <DecisionRow>();
            var googleNearbyFoodInput = _googlePlaceNearbySearchInputFactory.Create(iterParams.CurrentLocation, type);
            var nearbyFoodResults     = await _googlePlaceNearbySearchApiClient.GetAsync(googleNearbyFoodInput);

            int counter = 1;

            foreach (var nr in nearbyFoodResults.results)
            {
                var details = await _googlePlaceDetailsApiClient.GetAsync(_googlePlaceDetailsInputFactory.CreateAllUseful(nr.place_id));

                if (details.IsOk)
                {
                    var candidate = new PlanElementCandidate(details.Result.name, details.Result.place_id, details.Result.formatted_address, details.Result.geometry.location, details.Result.opening_hours, details.Result.types, details.Result.rating, details.Result.price_level, details.Result.user_ratings_total);
                    if (test)
                    {
                        return(candidate);
                    }

                    candidates.Add(candidate);
                }
                ++counter;
                if (counter > 10 && candidates.Count > 5)
                {
                    break;
                }
            }



            var iter = 1;

            foreach (var candidate in candidates)
            {
                decisionRows.Add(_decisionRowFactory.Create(candidate, iter, iterParams.CurrentLocation));
                ++iter;
            }

            var minVector = DecisionArray.GetMinVector(decisionRows);
            var maxVector = DecisionArray.GetMaxVector(decisionRows);

            foreach (var decisionRow in decisionRows)
            {
                decisionRow.NormalizedScore = _sawMethod.CalculateNormalizedScore(SawNormalizationMethod.LinearFirstType, decisionArray.WeightVector, decisionRow.DecisionValues, minVector, maxVector);
            }

            var result = decisionRows.OrderByDescending(x => x.NormalizedScore).FirstOrDefault(x => x.Candidate.IsOpen(iterParams.CurrentDateTime));

            if (result == null)
            {
                throw new UserFriendlyException($"Nie udało się znaleźć żadnego miejsca, gdzie można zjeść w pobliżu o godz: {iterParams.CurrentDateTime}");
            }

            return(result.Candidate);
        }
Example #2
0
        //0. Price //1. Rating //2. Distance //3. Popularity //4.Entertainment //5. Relax //6. Activity //7. Culture //8. Sightseeing //9. Partying //10. Shopping

        public DecisionRow Create(PlanElementCandidate candidate, int iter, Location startLocation)
        {
            var row = new DecisionRow();

            row.Candidate       = candidate;
            row.InitialPosition = iter;

            //0. Price
            row.SetValue(WeightVectorLabel.Price, Validate(WeightVectorLabel.Price, candidate.Price));
            //1. Rating
            row.SetValue(WeightVectorLabel.Rating, Validate(WeightVectorLabel.Rating, candidate.Rating));
            //2. Distance
            row.SetValue(WeightVectorLabel.Distance, Validate(WeightVectorLabel.Distance, (decimal)PlanHelpers.CalculateDistance(startLocation.lat, startLocation.lng, candidate.Location.lat, candidate.Location.lng)));
            //3. Popularity
            row.SetValue(WeightVectorLabel.Popularity, Validate(WeightVectorLabel.Popularity, candidate.Popularity));
            //4. Entertainment
            row.SetValue(WeightVectorLabel.Entertainment, Validate(WeightVectorLabel.Entertainment, candidate.ElementTypes.Contains(PlanElementType.Entertainment)? 1 : 0));
            //5. Relax
            row.SetValue(WeightVectorLabel.Relax, Validate(WeightVectorLabel.Relax, candidate.ElementTypes.Contains(PlanElementType.Relax) ? 1 : 0));
            //6. Activity
            row.SetValue(WeightVectorLabel.Activity, Validate(WeightVectorLabel.Activity, candidate.ElementTypes.Contains(PlanElementType.Activity) ? 1 : 0));
            //7. Culture
            row.SetValue(WeightVectorLabel.Culture, Validate(WeightVectorLabel.Culture, candidate.ElementTypes.Contains(PlanElementType.Culture) ? 1 : 0));
            //8. Sightseeing
            row.SetValue(WeightVectorLabel.Sightseeing, Validate(WeightVectorLabel.Sightseeing, candidate.ElementTypes.Contains(PlanElementType.Sightseeing) ? 1 : 0));
            //9. Partying
            row.SetValue(WeightVectorLabel.Partying, Validate(WeightVectorLabel.Partying, candidate.ElementTypes.Contains(PlanElementType.Partying) ? 1 : 0));
            //10. Shopping
            row.SetValue(WeightVectorLabel.Shopping, Validate(WeightVectorLabel.Shopping, candidate.ElementTypes.Contains(PlanElementType.Shopping) ? 1 : 0));

            return(row);
        }
        public async Task <IList <PlanElementCandidate> > GetCandidates(Plan plan, WeightVector weightVector)
        {
            var test       = true;
            var candidates = new List <PlanElementCandidate>();

            PlanElementType[] planElementTypes = new PlanElementType[]
            {
                PlanElementType.Entertainment,
                PlanElementType.Relax,
                PlanElementType.Activity,
                PlanElementType.Culture,
                PlanElementType.Sightseeing,
                PlanElementType.Partying,
                PlanElementType.Shopping,
            };


            foreach (var planElementType in planElementTypes)
            {
                var googlePlaceTypes = GooglePlaceTypes.Table.Where(x => x.PlanElementType == planElementType).ToList();

                foreach (var type in googlePlaceTypes)
                {
                    var nearbySearchInput = _googlePlaceNearbySearchInputFactory.Create(plan.StartLocation, (int)MaximumDistanceToAccomodation, type);
                    var nearbyResults     = await _googlePlaceNearbySearchApiClient.GetAsync(nearbySearchInput);

                    int counter = 1;
                    foreach (var nr in nearbyResults.results)
                    {
                        var details = await _googlePlaceDetailsApiClient.GetAsync(_googlePlaceDetailsInputFactory.CreateAllUseful(nr.place_id));

                        if (details.IsOk)
                        {
                            var candidate = new PlanElementCandidate(details.Result.name, details.Result.place_id, details.Result.formatted_address, details.Result.geometry.location, details.Result.opening_hours, details.Result.types, details.Result.rating, details.Result.price_level, details.Result.user_ratings_total);
                            if (!candidates.Any(x => x.PlaceId == candidate.PlaceId))
                            {
                                candidates.Add(candidate);
                            }
                        }
                        ++counter;
                    }

                    if (test && candidates.Count > 15)
                    {
                        return(candidates);
                    }

                    WeightVectorLabel weightVectorLabel = WeightVector.TranslateLabel(planElementType);

                    if ((plan.PlanForm.IsOverOneWeek || weightVector.GetLabelValue(weightVectorLabel) >= 0.1m) && nearbyResults.IsMoreResults)
                    {
                        var nearbyResults2 = await _googlePlaceNearbySearchApiClient.GetNextPageTokenAsync(nearbyResults.next_page_token);

                        foreach (var nr in nearbyResults2.results)
                        {
                            var details = await _googlePlaceDetailsApiClient.GetAsync(_googlePlaceDetailsInputFactory.CreateAllUseful(nr.place_id));

                            if (details.IsOk)
                            {
                                var candidate = new PlanElementCandidate(details.Result.name, details.Result.place_id, details.Result.formatted_address, details.Result.geometry.location, details.Result.opening_hours, details.Result.types, details.Result.rating, details.Result.price_level, details.Result.user_ratings_total);

                                if (!candidates.Any(x => x.PlaceId == candidate.PlaceId))
                                {
                                    candidates.Add(candidate);
                                }
                            }
                            ++counter;
                        }
                    }

                    if (test && candidates.Count > 15)
                    {
                        return(candidates);
                    }
                }

                if (test && candidates.Count > 15)
                {
                    break;
                }
            }

            if (candidates.Count == 0)
            {
                throw new UserFriendlyException($"Nie znaleziono żadnych potencjalnych kandydatów na elementy planu");
            }

            return(candidates);
        }