예제 #1
0
 /// <summary>
 /// <para>Initialize an instance of <see cref="System.Fabric.Description.ServiceDescription" /> with service kind.</para>
 /// </summary>
 /// <param name="kind">
 /// <para>Describe the kind of service type.</para>
 /// </param>
 protected ServiceDescription(ServiceDescriptionKind kind)
 {
     this.Kind = kind;
     this.PlacementConstraints         = string.Empty;
     this.isDefaultMoveCostSpecified   = false;
     this.defaultMoveCost              = MoveCost.Low;
     this.ServicePackageActivationMode = ServicePackageActivationMode.SharedProcess;
 }
예제 #2
0
 public int GetGamestateHash()
 {
     unchecked // Overflow is fine, just wrap
     {
         int hash = (int)2166136261;
         // Suitable nullity checks etc, of course :)
         hash = (hash * 16777619) ^ Name.GetHashCode();
         hash = (hash * 16777619) ^ Passable.GetHashCode();
         hash = (hash * 16777619) ^ MoveCost.GetHashCode();
         foreach (var prop in Properties)
         {
             hash = (hash * 16777619) ^ prop.GetHashCode();
         }
         return(hash);
     }
 }
예제 #3
0
        private void CopyFrom(ServiceDescription other)
        {
            // Copy basic types
            this.PlacementConstraints         = other.PlacementConstraints;
            this.ServiceTypeName              = other.ServiceTypeName;
            this.ApplicationName              = other.ApplicationName;
            this.ServiceName                  = other.ServiceName;
            this.InitializationData           = other.InitializationData == null ? null : other.InitializationData.ToArray();
            this.isDefaultMoveCostSpecified   = other.IsDefaultMoveCostSpecified;
            this.defaultMoveCost              = other.defaultMoveCost;
            this.ServiceDnsName               = other.ServiceDnsName;
            this.ServicePackageActivationMode = other.ServicePackageActivationMode;

            ServiceLoadMetricDescription.CopyFrom(other.Metrics, this.Metrics);

            this.correlations.AddRange(other.Correlations.Select(c => new ServiceCorrelationDescription(c)));
            this.PartitionSchemeDescription = other.PartitionSchemeDescription.GetCopy();
            this.placementPolicies.AddRange(other.placementPolicies.Select(p => p.GetCopy()));
            this.scalingPolicies.AddRange(other.ScalingPolicies.Select(p => ScalingPolicyDescription.GetCopy(p)));
        }
예제 #4
0
 public void ReportMoveCost(
     MoveCost moveCost)
 {
 }
 public void ReportMoveCost(MoveCost moveCost)
 {
     throw new NotImplementedException();
 }
 public void ReportMoveCost(MoveCost moveCost)
 {
     this.nativePartition.ReportMoveCost((NativeTypes.FABRIC_MOVE_COST)moveCost);
 }
예제 #7
0
        private static (Solution, MetaData) SolveForBuckets(ChoreCore[] coreChores, UserCore[] coreUsers, IEnumerable <KeyValuePair <string, int> > buckets, bool print = false)
        {
            var      metaData       = new MetaData();
            var      foundSolutions = new List <Solution>();
            Solution bestSolution;
            var      chores = coreChores.Select(c => new Chore
            {
                choreId       = c.choreId,
                effortRatings = c.effortRatings
            }).ToArray();
            var users = coreUsers.Select(u => new User
            {
                userId = u.userId
            }).ToArray();

            #region CalculateMoveCosts
            foreach (var chore in chores)
            {
                foreach (var effortRatring in chore.effortRatings)
                {
                    var moveCost = new MoveCost
                    {
                        moveCost = effortRatring.effort - chore.effort,
                        userId   = effortRatring.userId
                    };
                    chore.moveCosts.Add(moveCost);
                }
            }
            ;
            #endregion
            #region Calculate Share of chores per person
            for (int i = 0; i < users.Count(); i++)
            {
                users[i].ShareOfChoresEffort = buckets.Single(kvp => kvp.Key == users[i].userId).Value;
            }
            #endregion
            #region Find first solution
            var prioChores = chores.OrderByDescending(c => c.effort).ThenByDescending(c => c.moveCosts.Sum(m => m.moveCost));
            foreach (var chore in prioChores)
            {
                var userIdsByEffortRating = chore.effortRatings.OrderBy(e => e.effort).Select(e => e.userId).ToList();
                foreach (var idToTry in userIdsByEffortRating)
                {
                    var userToTry = users.First(u => u.userId == idToTry);
                    if (userToTry.CurrentActualEffort + chore.effort <= userToTry.ShareOfChoresEffort)
                    {
                        AssignChore(userToTry, chore);
                        break;
                    }
                }
            }
            foreach (var chore in chores)
            {
                if (string.IsNullOrEmpty(chore.assigneeId))
                {
                    var userToGiveChore = users.OrderBy(u => u.EffortDiff).ThenBy(u => u.CurrentActualEffort).First();
                    AssignChore(userToGiveChore, chore);
                }
            }
            bestSolution = CreateSolution(users);
            metaData.InititalSolution = CreateSolution(users);
            foundSolutions.Add(metaData.InititalSolution);
            #endregion
            if (print)
            {
                Debug.WriteLine("Initial Solution:");
                //PrintSolution(chores, users);
            }
            #region Find best solution
            var cannotImproveUsers = new List <string>();
            int userTurn           = -1;
            for (int i = 0; i < 50; i++)
            {
                metaData.IterationsToFindBestSolution += 1;
                userTurn = userTurn == users.Length - 1 ? 0 : userTurn + 1;

                Debug.WriteLine($"Incoming solution total diff {foundSolutions.Last().TotalDiff} and max diff {foundSolutions.Last().MaximumDiff}");
                if (cannotImproveUsers.Count() == users.Count())
                {
                    Debug.WriteLine("Cannot imporove any more!");
                    //PrintSolution(chores, users);
                    break;
                }
                ;

                var userToPlay = users[userTurn];
                if (userToPlay.EffortDiff == 0 && userToPlay.CurrentActualEffort == userToPlay.ShareOfChoresEffort)
                {
                    cannotImproveUsers.Add(userToPlay.userId);
                    continue;
                }
                var choreToGiveAway = userToPlay.AssignedChores
                                      .OrderByDescending(c => c.EffortDiffForUser(userToPlay.userId))
                                      .ThenBy(c => c.effort)
                                      .FirstOrDefault();

                if (choreToGiveAway == null)
                {
                    cannotImproveUsers.Add(userToPlay.userId);
                    break;
                }

                Debug.WriteLine($"User {userToPlay.userId} wants to give away {choreToGiveAway.choreId}");
                var userToTradeWithPrioArr = choreToGiveAway.moveCosts
                                             .Where(m => m.userId != userToPlay.userId)
                                             .Where(m => m.moveCost == 0)
                                             .OrderBy(m => Guid.NewGuid())
                                             .Select(m => users.First(u => u.userId == m.userId)).ToList();

                if (userToTradeWithPrioArr.Count == 0)
                {
                    cannotImproveUsers.Add(userToPlay.userId);
                    continue;
                }

                var trade = "";
                foreach (var userToTradeWith in userToTradeWithPrioArr)
                {
                    var choresToTakePrio = userToTradeWith.AssignedChores
                                           .Where(c => c.EffortDiffForUser(userToPlay.userId) <= choreToGiveAway.EffortDiffForUser(userToPlay.userId))
                                           .OrderByDescending(c => c.effort)
                                           .ThenBy(c => c.moveCosts.Sum(m => m.moveCost));



                    if (!choresToTakePrio.Any())
                    {
                        continue;
                    }


                    metaData.TradesToFindBestSolution += 1;
                    var choresToTake = new List <Chore>();
                    var choresToGive = new List <Chore> {
                        choreToGiveAway
                    };
                    if (choresToTakePrio.Any(c => c.effort == choreToGiveAway.effort))
                    {
                        //Make 1v1 trade
                        choresToTake.Add(choresToTakePrio.First(c => c.effort == choreToGiveAway.effort));
                    }
                    else if (!choresToTakePrio.Any(c => c.effort < choreToGiveAway.effort))
                    {
                        //Try make many v 1 trade
                        var choreToTake = choresToTakePrio.First();
                        var additionalChoresToGivePrio = userToPlay.AssignedChores
                                                         .Where(c => c.choreId != choreToGiveAway.choreId)
                                                         .Where(c => c.effort < choreToTake.effort)
                                                         .Where(c => c.MoveCostToUser(userToTradeWith.userId) == 0)
                                                         .OrderByDescending(c => c.effort)
                                                         .ThenBy(c => c.moveCosts.Sum(m => m.moveCost));

                        foreach (var chore in additionalChoresToGivePrio)
                        {
                            choresToGive.Add(chore);
                            if (choresToGive.Sum(c => c.effort) == choreToTake.effort)
                            {
                                break;
                            }
                        }
                        choresToTake.Add(choreToTake);
                    }
                    else
                    {
                        //Try make 1 v many trade
                        foreach (var choreToTake in choresToTakePrio)
                        {
                            choresToTake.Add(choreToTake);
                            var choresTakenSum = choresToTake.Sum(ch => ch.effort);
                            if (choresTakenSum == choreToGiveAway.effort)
                            {
                                break;
                            }
                        }
                    }

                    if (choresToGive.Sum(c => c.effort) != choresToTake.Sum(c => c.effort))
                    {
                        break;
                    }

                    foreach (var chore in choresToGive)
                    {
                        Debug.WriteLine($"Giving chore {chore.choreId} ({chore.effort}) from {userToPlay.userId} to {userToTradeWith.userId}");
                        AssignChore(userToTradeWith, chore, userToPlay);
                    }
                    foreach (var chore in choresToTake)
                    {
                        Debug.WriteLine($"Giving chore {chore.choreId} ({chore.effort}) from {userToTradeWith.userId} to {userToPlay.userId}");
                        AssignChore(userToPlay, chore, userToTradeWith);
                    }

                    trade = "heaj";
                    cannotImproveUsers = new List <string>();
                    break;
                }

                if (trade == "")
                {
                    cannotImproveUsers.Add(userToPlay.userId);
                    continue;
                }

                var solution = CreateSolution(users);
                foundSolutions.Add(solution);
                if (solution.IsPerfect)
                {
                    Debug.WriteLine("Found perfect solution!");
                    //PrintSolution(chores, users);
                    break;
                }
            }
            #endregion
            bestSolution = foundSolutions.OrderBy(s => s.TotalDiff).ThenBy(s => s.MaximumDiff).First();
            return(bestSolution, metaData);
        }