【问题标题】:Need a deterministic algorithm to generate a resource domain prefix for a given path in an evenly distributed fashion需要确定性算法以均匀分布的方式为给定路径生成资源域前缀
【发布时间】:2009-12-04 02:51:16
【问题描述】:

我需要根据给定的路径和配置的资源域数量以确定的方式生成资源域前缀,并具有良好的分布。例如,如果您将路径“/script/site.js”传递给它,它会返回“res#”,其中“#”是介于 0 和配置的资源域数量之间的整数。

使用 C# 3.0。

到目前为止有这个:

var resourceDomainCount = 4;
var hasher = System.Security.Cryptography.SHA1.Create();
var paths = new [] {
    "/App_Themes.0.1.433.232/images/buttonsBackgrounds.jpg",
    "/App_Themes.0.1.433.232/images/blahblah.jpg",
    "/App_Themes.0.1.433.232/images/pagebg.gif",
    "/App_Themes.0.1.433.232/site.css",
    "/script/site.js",
    "/App_Themes.0.1.433.232/images/different.jpg",
    "/App_Themes.0.1.433.232/images/shadows.jpg",
    "/Handlers/ImageHandler.ashx?type=l&id=123&s=g&index=0",
    "/Handlers/ImageHandler.ashx?type=l&id=234&s=g&index=0",
    "/Handlers/ImageHandler.ashx?type=l&id=345&s=g&index=0",
    "/Handlers/ImageHandler.ashx?type=p&id=MyProduct&s=g&index=0",
    "/Handlers/ImageHandler.ashx?type=p&id=WineGreat&s=g&index=0",
    "/Handlers/ImageHandler.ashx?type=p&id=YayYay&s=g&index=0"
    };
foreach (var path in paths) {
    var pathHash = hasher.ComputeHash(Encoding.ASCII.GetBytes(path));
    var singleByteHash = pathHash.Aggregate(0, (a, b) => a ^ b);
    var random = new Random((int)singleByteHash);
    var resourceDomainIndex = random.Next(0, resourceDomainCount);
    (resourceDomainIndex + ": " + path).Dump();
}

这会产生以下内容:

3:/App_Themes.0.1.433.232/images/buttonsBackgrounds.jpg
0: /App_Themes.0.1.433.232/images/blahblah.jpg
1:/App_Themes.0.1.433.232/images/pagebg.gif
1:/App_Themes.0.1.433.232/site.css
3:/script/site.js
1:/App_Themes.0.1.433.232/images/different.jpg
3:/App_Themes.0.1.433.232/images/shadows.jpg
1:/Handlers/ImageHandler.ashx?type=l&id=123&s=g&index=0
1:/Handlers/ImageHandler.ashx?type=l&id=234&s=g&index=0
0: /Handlers/ImageHandler.ashx?type=l&id=345&s=g&index=0
2:/Handlers/ImageHandler.ashx?type=p&id=MyProduct&s=g&index=0
1:/Handlers/ImageHandler.ashx?type=p&id=WineGreat&s=g&index=0
0: /Handlers/ImageHandler.ashx?type=p&id=YayYay&s=g&index=0

没有得到我想要的分布(那里只有一个 '2' 的实例)。

有数千个输入字符串一直在变化,路径将在运行时生成,例如:<a href="<%= GetPath("/script/site.js") %>">Link</a>

【问题讨论】:

    标签: c# .net algorithm


    【解决方案1】:

    这比散列字符串简单得多(好吧,大概它已经是一个散列)并且似乎可以获得更好的分布:

    Math.Abs(path.GetHashCode()) % resourceDomainCount
    

    【讨论】:

    • 顺便说一句,将其代入原始的 sn-p 得到这个结果:0,2,1,2,3,1,3,0,1,2,1,2,2
    • 这在运行之间并不总是相同的。谨慎使用! andrewlock.net/…
    【解决方案2】:

    您的样本太少了。随机性通常类似于统计数据。它只是在很长一段时间内得到证实。尝试在 100 次迭代中重新运行您的代码,并查看每个值出现的时间是否相同。然后再次尝试 10,000 次迭代,并注意实际结果数更接近百分比。然后运行它进行 100 万次迭代,并注意到它更接近了。它永远不需要完全相同 - 否则它不会真的是随机的。

    如果结果不遵循该模式,那么您可能遇到了均匀分布问题。

    【讨论】:

    • 我明白你在说什么,但我想找到一种即使在小集合上也能提供良好分布的算法。对显示 25 个搜索结果的页面进行成像,每个搜索结果都有自己的图像。我希望这 25 个图像路径在 4 个资源域之间有良好的分布。
    • 如果您的目的是保证在小集合上的平均分配,为什么不使用循环法呢?或者将所有数据填充到一个集合中,然后从该集合中提取并返回一个随机元素(并且每当集合为空时,用每个可能的元素重新填充它)?
    猜你喜欢
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 2021-11-16
    • 2012-06-26
    • 1970-01-01
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多