【发布时间】:2019-02-08 17:50:52
【问题描述】:
我正在开发一个使用多个帐户发布到多个网站的项目。每个帐户都可以发布到特定网站。如下面的“字典”所示。问题是我试图公平地分配帐户上的发布作业,并在拥有超过 1 个作业的帐户之间拉开距离。
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public struct Job
{
public string Site { get; set; }
public string Account { get; set; }
}
private static readonly Dictionary<string, List<string>> Dict = new Dictionary<string, List<string>>();
private static List<string> _accounts;
public static void Main()
{
var sites = new List<string>{"Site-A", "Site-B", "Site-C", "Site-D", "Site-E"};
_accounts = new List<string>{"Account-A", "Account-B", "Account-C", "Account-D", "Account-E"};
// Permissions dictionary. specify accounts that has a permessions to publish on a particular Site
Dict.Add("Site-A", new List<string>{"Account-A", "Account-C"});
Dict.Add("Site-B", new List<string>{"Account-A", "Account-E"});
Dict.Add("Site-C", new List<string>{"Account-C", "Account-D"});
Dict.Add("Site-D", new List<string>{"Account-A"});
Dict.Add("Site-E", new List<string>{"Account-A"});
var jobs = new List<Job>();
foreach (var site in sites)
{
var job = new Job();
// Get an account that has a permissions to publish on 'site'
// checking against the permissions dictionary Dict
var account = GetAccountCanPost(Dict, site, _accounts);
job.Site = site;
job.Account = account;
jobs.Add(job);
}
var jobsCountForEachAccountDict = CalculateJobsCountForEachAccounts(jobs);
//////#### Now.. We need to re Order Jobs and swipe it here before send it to processing ####.....//////
foreach (var job in jobs)
{
Console.WriteLine(job.Account + " publish on " + job.Site);
}
}
public static Dictionary<string, int> CalculateJobsCountForEachAccounts(List<Job> jobs)
{
var dict = new Dictionary<string, int>();
foreach (var job in jobs)
{
if (dict.ContainsKey(job.Account))
dict[job.Account]++;
else
dict.Add(job.Account, 1);
}
return dict;
}
public static string GetAccountCanPost(Dictionary<string, List<string>> dict, string targetSite, List<string> accounts)
{
var accountIdsAssoc = GetAccountsIdsAssociatedWithCommunity(dict, targetSite);
var selectedId = PickRandom(accountIdsAssoc, new Random());
var account = accounts.FirstOrDefault(s => s == selectedId);
return account;
}
private static List<string> GetAccountsIdsAssociatedWithCommunity(Dictionary<string, List<string>> communitiesAccountsAssociationsDict, string communityId)
{
if (communitiesAccountsAssociationsDict.ContainsKey(communityId))
return communitiesAccountsAssociationsDict[communityId];
return null;
}
private static T PickRandom<T>(IList<T> list, Random random)
{
var index = random.Next(0, list.Count);
return list[(int) index];
}
}
当创建工作时,它类似于以下内容:(在重新调整工作分配之前)
> Account-A Publish on Site-A
> Account-E Publish on Site-B
> Account-D Publish on Site-C
> Account-A Publish on Site-D
> Account-A Publish on Site-E
上面创建的发布工作没有公平地分配给帐户,您可以看到“帐户-A”分配了 3 个工作,而其他帐户可以发布到“字典”中定义的“站点”,所以它应该看起来类似:
> Account-C Publish on Site-A
> Account-E Publish on Site-B
> Account-A Publish on Site-D
> Account-D Publish on Site-C
> Account-A Publish on Site-E
在上面的输出中,工作在帐户上是公平分配的,而且拥有超过 1 个工作的帐户之间也存在距离
一个关于工作之间距离的例子:
> Account-A Publish on Site-A
> Account-E Publish on Site-B
> Account-D Publish on Site-C
> Account-A Publish on Site-D
> Account-A Publish on Site-E
Account-A 正在处理作业 4 和 5。一个帐户不应按顺序处理两个作业,因此可以与另一个作业交换。
如果您能提供帮助,我们将不胜感激。我需要一种算法来完成工作分配以获得相似的输出。性能并不重要。
谢谢你..
【问题讨论】:
-
它的分布不均匀,因为它的网站到帐户的分布不均匀。如果您甚至想要您的帐户,那么只需选择一个随机帐户然后选择一个随机站点。在这种情况下,最简单的方法是扁平化您的具有站点列表的帐户(反之亦然)
-
您好,您能详细说明“帐户之间的最大距离”部分吗?
-
@Suparshva 我已经更新了问题,请看一下
-
@AronF - 我想要一份关于工作分配的白痴指南。你能像我 5 岁一样向我解释吗?
-
@Enigmativity 请再看看这个问题。添加了更多细节。上面的发布作业没有公平地分配给帐户,正如您所见,“帐户-A”分配了 3 个作业,而其他帐户可以发布到“字典”中定义的“站点”,因此我们需要分配发布作业在帐户上确保尽可能公平地将工作分配给帐户。非常感谢