随机选择变量集,每个项目至少保证一次

时间:2014-01-12 19:31:25

标签: c# algorithm random

我正在研究c#中的游戏,但这个细节并不是解决我的问题所必需的。

在我的高水平这里是我想要的:

  • 我有一套可以包含任意数量的物品。
  • 我想从该套装中随机选择10件商品。
  • 如果该项目少于10项,那么我希望选择相同的项目 项目不止一次。
  • 我想确保每件商品至少被选中一次。

这个算法是什么?

对不起,我不确定这是不是一个合适的地方,但我手头没有笔和纸,我不能完全了解所需要的,所以感谢你的帮助。

  • 此外,我可能还想为项目添加权重 增加/减少选择的机会,所以如果你能够 将其纳入你的答案中。

最后我想我应该提一下我的设置实际上是List<string>,如果你愿意提供一个完整的答案而不是伪代码,这可能是相关的。

3 个答案:

答案 0 :(得分:1)

这是我用来随机化数组的方法。它需要一个整数数组并随机排序,列出由随机数(r)确定的一定时间。

    private int[] randomizeArray(int[] i)
    {
        int L = i.Length - 1;
        int c = 0;
        int r = random.Next(L);
        int prev = 0;
        int curr = 0;
        int temp;

        while (c < r)
        {
            curr = random.Next(0, L);
            if (curr != prev)
            {
                temp = i[prev];
                i[prev] = i[curr];
                i[curr] = temp;
                c++;
            }
        }
        return i;
    }

答案 1 :(得分:1)

如果你寻找有效的代码,我的回答不是它。理论上,创建一些可以从中删除的集合将镜像您的集合。然后从中选择对象的随机成员...并删除,这将保证不重复的项目(如果可能)。

Random rnd = new Random();
List<int> indexes = new List<int>(items.Count);

for (int i = 0; i < items.Count; i++)
    indexes.Add(i);

List<string> selectedItems = new List<string>(10);
int tmp;
for(int i = 0; i < 10; i++)
{
tmp = rnd.Next(1,10000); //something big
if(indexes.Count > 0)
{
    selectedItems.Add(yourItems[indexes[tmp%indexes.Count]]); 
    indexes.RemoveAt(tmp%indexes.Count);
}
else
    selectedItems.Add(yourItems[rnd.Next(0,9)]); //you ran out of unique items
}

其中items是您的列表而yourItems是所选项目的列表,如果您想立即处理它们,则无需存储它们

答案 2 :(得分:0)

也许shuffle收集和挑选前面的元素,直到你有所需的数量。

一旦你完成了所有的元素,你或许应该再次洗牌,所以你不要只重复相同的序列。

改组的基本算法:(伪代码)

for i from n − 1 downto 1 do
   j ← random integer with 0 ≤ j ≤ i
   exchange a[j] and a[i]

使用上面的算法(或微小的变化),可以随意洗牌,直到达到所需数量的元素,无需改变整个过程。