各位大哥,我想实现一个随机分配,如下:假如有9件物品,分配给3个人,则每个人分到3件物品如果有10件物品,分配给3个人,则前2个人分到3件,最后1个人分到4件(3+1)如果有11件物品,分配给3个人,则前2个人分到3件,最后1个人分到5件(3+2)(也就是最后一个人分到总数剩下的那部分)物品各不相同,所以每次每个人分配到的物品都必须是随机的,我想了半天没做出来,所以有劳各位帮帮忙看看~

解决方案 »

  1.   

    随机取出你要分配的数量然后拿要分配的总数量MOD需分配的人数
    余数为A这样每个人分配的数量是(要分配的总数量)-A/需分配的人数
    即为没人分配的数量  最后一个人等于这个结果+A当然你要判断够不够分配(特殊情况再考虑)
      

  2.   

    using System;
    using System.Collections.Generic;
    namespace Test
    {
        class Program
        {
            static List<string> listCus = new List<string>();
            static List<string> peasons = new List<string>();
            static Dictionary<string, List<string>> result = new Dictionary<string, List<string>>();
            static void Main(string[] args)
            {
                #region 初始化数据
                int m = 11;
                int n = 3;            for (int i = 0; i < m; i++)
                {
                    listCus.Add(((char)(i+65)).ToString());
                }            //listCus初始化为A,B,C,D,E,F,G,H,假定为你的数据源            #region 下面重新随机初始化一下            List<string> listCus1 = new List<string>();
                long tick = DateTime.Now.Ticks;   
                Random r = new Random((int)(tick & 0xffffffffL) | (int) (tick >> 32));//保证生成随机数重复率很低
                while (listCus1.Count < m)
                {
                    int j = r.Next(m);
                    string s = ((char)(j + 65)).ToString();
                    if (listCus1.Count > 0)
                    {
                        while (listCus1.Contains(s))
                        {
                            j = r.Next(m);
                            s = ((char)(j + 65)).ToString();                    }
                    
                    }                listCus1.Add(s);
                }
                #endregion 
                for (int j = 0; j < n; j++)
                {
                    string t = (j + 1).ToString().PadLeft(12, '0');
                    peasons.Add(t);
                    result.Add(t, new List<string>());
                }
                #endregion
                
                #region 算法部分
                int iAv = m / n;
                int iMod = m % n;
                int it = 0;            Console.WriteLine("分配结果:");
                foreach (string k in result.Keys)
                {
                    result[k].AddRange(listCus1.GetRange(0, iAv));
                    if (listCus1.Count - iAv != 0 && (listCus1.Count - iAv) / n == 0)
                    {
                        result[k].AddRange(listCus1.GetRange(iAv,  listCus1.Count - iAv));
                    }
                    
                    listCus1.RemoveRange(0, iAv);                Console.WriteLine("{0}:{1}-->{2}", k, result[k].Count, String.Join(",",result[k].ToArray()));
                }
                #endregion        }
        }}结果显示
    ______________________________
    分配结果:
    000000000001:3-->D,J,G
    000000000002:3-->A,C,B
    000000000003:5-->I,H,E,F,K
    请按任意键继续. . .
      

  3.   

    把任务改成一个string数组,就用如下代码:
    using System;
    using System.Collections.Generic;
    namespace Test
    {
        class Program
        {
            
            static void Main(string[] args)
            {            List<string> peasons = new List<string>();
                Dictionary<string, List<string>> result = new Dictionary<string, List<string>>();
                #region 初始化数据
                
                string[] listCus = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K" };//任务
                int m = 11;//任务数
                int n = 3;//分配人数            #region 下面重新随机初始化一下            List<string> listCus1 = new List<string>();//随机化任务列表
                long tick = DateTime.Now.Ticks;   
                Random r = new Random((int)(tick & 0xffffffffL) | (int) (tick >> 32));//保证生成随机数重复率很低
                while (listCus1.Count < m)
                {
                    int j = r.Next(m);
                    string s = listCus[j];
                    if (listCus1.Count > 0)
                    {
                        while (listCus1.Contains(s)) //随机数重复,重新取
                        {
                            j = r.Next(m);
                            s = listCus[j];                    }
                    
                    }                listCus1.Add(s);
                }
                #endregion 
                for (int j = 0; j < n; j++)  //分配人员ID编号
                {
                    string t = (j + 1).ToString().PadLeft(12, '0');
                    peasons.Add(t);
                    result.Add(t, new List<string>());
                }
                #endregion
                
                #region 算法部分
                int iAv = m / n;
                int iMod = m % n;
                int it = 0;            Console.WriteLine("分配结果:");
                foreach (string k in result.Keys)
                {
                    result[k].AddRange(listCus1.GetRange(0, iAv));
                    if (listCus1.Count - iAv != 0 && (listCus1.Count - iAv) / n == 0)
                    {
                        result[k].AddRange(listCus1.GetRange(iAv,  listCus1.Count - iAv));
                    }
                    
                    listCus1.RemoveRange(0, iAv);                Console.WriteLine("{0}:{1}-->{2}", k, result[k].Count, String.Join(",",result[k].ToArray()));
                }
                #endregion        }
        }}
      

  4.   

    CutBug大哥,我试了一下,好像有一点点小问题,就是当int m = 4;//任务数
    int n = 3;//分配人数
    或者是
    int m = 3;//任务数
    int n = 3;//分配人数的时候,结果不正常,你试一下看是不是
      

  5.   

    用MOD 不行的吧用取余的话如果有10件物品,分配给3个人, 应该是4,4,2如果有11件物品,分配给3个人, 应该是4,4,3
      

  6.   

    都说了,
    不过我说理论的,以前我做过,忘记代码在哪里了!首先,你根据产品总数,如10,生成10个不同的随机数,保存在数组里面,这个时候,数组步长将从0到9最好使用ArrayList充当数组,因为它的步长不用定义,直接ADD就可以!然后,再生成随机数,随机数控制在步长以内,然后,根据随机数,匹配数组的步长,这样就可以实现随机给产品了记得,取一个产品出来之后,就删除ArrayList里面的值,这样,就不会重复了!
      

  7.   

    我以前做法就这样,参考http://blog.csdn.net/CutBug/archive/2009/01/27/3853648.aspx上面的Bug改了一下,测是了一下应该可以了:using System;
    using System.Collections.Generic;
    namespace Test
    {
        class Program
        {        static void Main(string[] args)
            {            List<string> peasons = new List<string>();
                Dictionary<string, List<string>> result = new Dictionary<string, List<string>>();
                #region 初始化数据            string[] listCus = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K" };//任务
                int m = listCus.Length;//任务数
                int n = 3;//分配人数            #region 下面重新随机初始化一下            List<string> listCus1 = new List<string>();//随机化任务列表
                long tick = DateTime.Now.Ticks;
                Random r = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32));//保证生成随机数重复率很低
                while (listCus1.Count < m)
                {
                    int j = r.Next(m);
                    string s = listCus[j];
                    if (listCus1.Count > 0)
                    {
                        while (listCus1.Contains(s)) //随机数重复,重新取
                        {
                            j = r.Next(m);
                            s = listCus[j];                    }                }                listCus1.Add(s);
                }            
                #endregion
                for (int j = 0; j < n; j++)  //分配人员ID编号
                {
                    string t = (j + 1).ToString().PadLeft(12, '0');
                    peasons.Add(t);
                    result.Add(t, new List<string>());
                }
                #endregion            #region 算法部分
                if (m==0)
                {
                    Console.WriteLine("没有任务!");
                    return;
                }
                int iAv = m / n == 0 ? 1 : m / n;
                int iMod = m % n;
                int i = 0;           
                Console.WriteLine("分配结果:");
                foreach (string k in result.Keys)
                {
                    if (listCus1.Count == 0) break;
                    result[k].AddRange(listCus1.GetRange(0, iAv));
          
                    if (i == result.Keys.Count-1 && listCus1.Count / n <2)
                    {
                        result[k].AddRange(listCus1.GetRange(iAv, listCus1.Count - iAv));
                    }                listCus1.RemoveRange(0, iAv);
                    i++;
                    Console.WriteLine("{0}:{1}-->{2}", k, result[k].Count, String.Join(",", result[k].ToArray()));
                }
                #endregion        }
        }}