/// <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; }
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); } }
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))); }
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); }
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); }