Algorithm 半随机子集集

Algorithm 半随机子集集,algorithm,random,set,Algorithm,Random,Set,我试图生成带有一些限制的半随机子集 以下是变量说明和示例值: ObjCount—对象数(12) VisibleCount(又名SetSize)-每组对象的数量(6) SetCount—集合数(12) ObjAppearances—对象出现的集合数=SetCount*VisibleCount/ObjCount 我需要生成符合以下规则的给定数量的集合(集合计数): 每个集合都是对象的集合,但没有对象可以在单个集合中多次出现 此外,每个对象应位于相同数量的集合中。如果不均匀划分,则对象出现的数量集

我试图生成带有一些限制的半随机子集

以下是变量说明和示例值:

  • ObjCount—对象数(12)
  • VisibleCount(又名SetSize)-每组对象的数量(6)
  • SetCount—集合数(12)
  • ObjAppearances—对象出现的集合数=
    SetCount*VisibleCount/ObjCount
我需要生成符合以下规则的给定数量的集合(集合计数):

  • 每个集合都是对象的集合,但没有对象可以在单个集合中多次出现
  • 此外,每个对象应位于相同数量的集合中。如果不均匀划分,则对象出现的数量集可以减少1(一些对象在4个集中,其他对象在5个集中)。我会尽量避免这种情况,所以这不是关键
  • 事实证明,这远没有我最初想象的那么琐碎。有人能帮我写些代码吗?通用版本的解决方案也会非常有用

    提前谢谢

    编辑:VisibleCount是设置的大小。对象出现的次数(ObjAppearances)为
    SetCount*VisibleCount/ObjCount

    Edit2:我还应该补充一点,我希望集合是相当随机的。如果所有集合都有顺序对象(例如set1:5,6,7 set2:3,4,5 set3:10,11,0),则解决方案无效。很抱歉没有说清楚

    Edit3:这里有一个不起作用的解决方案。(用C#表示)

    static void Main(字符串[]args)
    {
    var-ObjectCount=12;
    var SetSize=6;
    var SetCount=12;
    var Sets=Enumerable.Range(0,SetCount).Select(i=>newlist()).ToArray();//一个SetCount大小的列表数组
    var objectappearancess=SetSize*SetCount/ObjectCount;
    var rand=new Random();
    //填空
    for(int-obj=0;objs.Count!s.Contains(obj));
    ///////////////////////
    //问题是,所有的非全套可能已经
    //有一份obj
    ///////////////////////
    //随机选择一组
    var currentSetIndex=rand.Next(setwithoutobj.Count());
    var currentSet=设置无对象元素(currentSetIndex);
    //添加对象
    currentSet.Add(obj);
    }
    }
    //随机化每个集合内的顺序并输出每个
    对于(int i=0;irand.Next());
    集合[i]=新列表(随机有序集合);
    //输出
    foreach(集合[i]中的var obj)
    Write(string.Format(“{0},”,obj));
    Console.WriteLine();
    }
    Console.ReadLine();
    }
    
    以下是解决方案-MizardX答案的实现

    static void Main(string[] args)
    {
        var ObjectCount = 12;
        var SetSize = 6;
        var SetCount = 10;
        var rand = new Random();
    
        // make a matrix [SetCount][ObjectCount]
        var Matrix = new int[SetCount][];
        for (int s = 0; s < SetCount; s++)
            Matrix[s] = Enumerable.Repeat(0, ObjectCount).ToArray();
    
        // put approximately the same number of objects in each set by
        // adding sequential objects to sequential sets (not random)
        for (int s = 0; s < SetCount; s++)
        {
            var firstObject = (int)Math.Ceiling((double)s * ObjectCount / SetCount);
            for (int i = 0; i < SetSize; i++)
            {
                var o = (firstObject + i) % ObjectCount;
                Matrix[s][o] = 1;
            }
        }
    
        // output the result
        for (int s = 0; s < SetCount; s++)
        {
            for (int o = 0; o < ObjectCount; o++)
            {
                Console.Write(string.Format("{0}, ", Matrix[s][o]));
            }
            Console.WriteLine();
        }
        Console.WriteLine();
    
        // shuffle sets
        Matrix = Matrix.OrderBy(s => rand.Next()).ToArray();
        // make a new matrix for shuffle objects
        var objOrder = Enumerable.Range(0, ObjectCount).OrderBy(o => rand.Next()).ToArray();
        var MatrixSuffled = new int[SetCount][];
        for (int s = 0; s < SetCount; s++)
            MatrixSuffled[s] = Enumerable.Repeat(0, ObjectCount).ToArray();
        for (int o = 0; o < ObjectCount; o++)
        {
            var oldObj = o;
            var newObj = objOrder[o];
            for (int s = 0; s < SetCount; s++)
            {
                MatrixSuffled[s][newObj] = Matrix[s][oldObj];
            }
        }
    
        // check and output the result
        var objectCounters = Enumerable.Repeat(0, ObjectCount).ToArray();
        for (int s = 0; s < SetCount; s++)
        {
            var objectsInThisSet = 0;
            for (int o = 0; o < ObjectCount; o++)
            {
                objectsInThisSet += MatrixSuffled[s][o];
                objectCounters[o] += MatrixSuffled[s][o];
                Console.Write(string.Format("{0}, ", MatrixSuffled[s][o]));
            }
            Console.Write(string.Format("  {0}", objectsInThisSet));
            Console.WriteLine();
        }
        // output object count
        Console.WriteLine();
        for (int o = 0; o < ObjectCount; o++)
            Console.Write(string.Format("{0}  ", objectCounters[o]));
        Console.ReadLine();
    }
    
    static void Main(字符串[]args)
    {
    var-ObjectCount=12;
    var SetSize=6;
    var SetCount=10;
    var rand=new Random();
    //制作一个矩阵[SetCount][ObjectCount]
    var矩阵=新整数[SetCount][];
    对于(int s=0;srand.Next()).ToArray();
    //为洗牌对象创建新矩阵
    var objOrder=Enumerable.Range(0,ObjectCount).OrderBy(o=>rand.Next()).ToArray();
    var MatrixSuffled=new int[SetCount][];
    对于(int s=0;s
    resultSets=新集合[SetCount];//创建一个集合数组以保存结果
    totalObjectsPlaced=0;
    currentObjectIndex=0;
    而(totalObjectsPlaced<(对象计数*可见计数)){
    做{
    randomSet=rand(SetCount);
    }而(!resultSets[randomSet].contains(object[currentObjectIndex]);
    结果集[randomSet].add(对象[currentObjectIndex]);
    currentObjectIndex=(currentObjectIndex+1)%ObjCount;
    totalObjectsPlac
    
    static void Main(string[] args)
    {
        var ObjectCount = 12;
        var SetSize = 6;
        var SetCount = 10;
        var rand = new Random();
    
        // make a matrix [SetCount][ObjectCount]
        var Matrix = new int[SetCount][];
        for (int s = 0; s < SetCount; s++)
            Matrix[s] = Enumerable.Repeat(0, ObjectCount).ToArray();
    
        // put approximately the same number of objects in each set by
        // adding sequential objects to sequential sets (not random)
        for (int s = 0; s < SetCount; s++)
        {
            var firstObject = (int)Math.Ceiling((double)s * ObjectCount / SetCount);
            for (int i = 0; i < SetSize; i++)
            {
                var o = (firstObject + i) % ObjectCount;
                Matrix[s][o] = 1;
            }
        }
    
        // output the result
        for (int s = 0; s < SetCount; s++)
        {
            for (int o = 0; o < ObjectCount; o++)
            {
                Console.Write(string.Format("{0}, ", Matrix[s][o]));
            }
            Console.WriteLine();
        }
        Console.WriteLine();
    
        // shuffle sets
        Matrix = Matrix.OrderBy(s => rand.Next()).ToArray();
        // make a new matrix for shuffle objects
        var objOrder = Enumerable.Range(0, ObjectCount).OrderBy(o => rand.Next()).ToArray();
        var MatrixSuffled = new int[SetCount][];
        for (int s = 0; s < SetCount; s++)
            MatrixSuffled[s] = Enumerable.Repeat(0, ObjectCount).ToArray();
        for (int o = 0; o < ObjectCount; o++)
        {
            var oldObj = o;
            var newObj = objOrder[o];
            for (int s = 0; s < SetCount; s++)
            {
                MatrixSuffled[s][newObj] = Matrix[s][oldObj];
            }
        }
    
        // check and output the result
        var objectCounters = Enumerable.Repeat(0, ObjectCount).ToArray();
        for (int s = 0; s < SetCount; s++)
        {
            var objectsInThisSet = 0;
            for (int o = 0; o < ObjectCount; o++)
            {
                objectsInThisSet += MatrixSuffled[s][o];
                objectCounters[o] += MatrixSuffled[s][o];
                Console.Write(string.Format("{0}, ", MatrixSuffled[s][o]));
            }
            Console.Write(string.Format("  {0}", objectsInThisSet));
            Console.WriteLine();
        }
        // output object count
        Console.WriteLine();
        for (int o = 0; o < ObjectCount; o++)
            Console.Write(string.Format("{0}  ", objectCounters[o]));
        Console.ReadLine();
    }
    
    resultSets = new Set[SetCount];  // create an array of sets to hold the results
    
    totalObjectsPlaced = 0;
    currentObjectIndex = 0;
    
    while (totalObjectsPlaced < (ObjCount * VisibleCount)) {
      do {
        randomSet = rand(SetCount);
      } while (!resultSets[randomSet].contains(object[currentObjectIndex]));
      resultSets[randomSet].add(object[currentObjectIndex]);
      currentObjectIndex = (currentObjectIndex + 1) % ObjCount;
      totalObjectsPlaced++;
    }
    
    1 0 0 0 0 0
    1 0 0 0 0 0
    1 1 0 0 0 0
    0 1 0 0 0 0
    0 1 1 0 0 0
    0 0 1 0 0 0
    0 0 1 1 0 0
    0 0 0 1 0 0
    0 0 0 1 1 0
    0 0 0 0 1 1
    0 0 0 0 1 1
    0 0 0 0 0 1
    
    1 0 1 0 0 0
    0 0 0 0 1 0
    1 1 0 0 0 0
    0 0 0 1 1 0
    0 1 0 0 0 0
    0 0 0 1 0 0
    0 0 1 0 0 0
    1 0 1 0 0 0
    0 0 0 1 0 0
    0 0 0 0 1 1
    0 1 0 0 0 1
    0 0 0 0 0 1
    
    {1,3,8}
    {3,5,11}
    {1,7,8}
    {4,6,9}
    {2,4,10}
    {10,11,12}