///
/// 权重对象
///
public class RandomObject
{
///
/// 权重
///
public int Weight { set; get; }
///
/// Id
///
public int Id { get; set; }
}
///
/// 权重是指某一因素或指标相对于某一事物的重要程度,其不同于一般的比重,体现的不仅仅是某一因素或指标所占的百分比,强调的是因素或指标的相对重要程度,倾向于贡献度或重要性。通常,权重可通过划分多个层次指标进行判断和计算,常用的方法包括层次分析法、模糊法、模糊层次分析法和专家评价法等。
///
/// 四类宝箱中物品数量的权重(json格式数据):
/// [[1,101],[2,102],[31,103],[41,104]],
/// 宝箱中具体物品数量的权重(json格式数据):
/// [[1202,100],[1203,100],[1201,100],[1210,100]
/// ,[1204,101],[1205,101],[1206,102],[1208,102],
/// [1207,103],[1209,103]]
/// 物品所属宝箱类型:
/// 1201 31
/// 1202 1
/// 1203 1
/// 1204 1
/// 1205 2
/// 1206 1
/// 1207 1
/// 1208 2
/// 1209 2
/// 1210 41
/// 说明:[1,101] 中 1表示宝箱ID,
/// 101表示宝箱中物品总数量的权重。
/// [1202,100]中 1202表示宝箱中具体物品的ID,
/// 100是物品个数的权重。
///
/// 现在有39个物品分布在4类宝箱中,
/// 出现的个数由宝箱权重与具体的物品权重来控制
/// 请写出得到每个物品被分配个数的算法
///
class Program
{
public static T GetRandomList(List list, int count) where T : RandomObject
{
//计算权重总和
int totalWeights = 0;
for (int i = 0; i < list.Count; i++)
{
//权重+1,防止为0情况。
totalWeights += list[i].Weight + 1;
}
//随机赋值权重
//GetRandomSeed()随机种子,防止快速频繁调用导致随机一样的问题
Random ran = new Random(GetRandomSeed());
//第一个int为list下标索引、第二个int为权重排序值
List<KeyValuePair<int, int>> wlist = new List<KeyValuePair<int, int>>();
for (int i = 0; i < list.Count; i++)
{
int w = (list[i].Weight + 1) + ran.Next(0, totalWeights); // (权重+1) + 从0到(总权重-1)的随机数
wlist.Add(new KeyValuePair<int, int>(i, w));
}
//排序
wlist.Sort(
delegate (KeyValuePair<int, int> kvp1, KeyValuePair<int, int> kvp2)
{
return kvp2.Value - kvp1.Value;
});
//随机法则
return list[wlist[0].Key];
}
/// <summary>
/// 随机种子值
/// </summary>
/// <returns></returns>
private static int GetRandomSeed()
{
byte[] bytes = new byte[4];
System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
rng.GetBytes(bytes);
return BitConverter.ToInt32(bytes, 0);
}
static void Main(string[] args)
{
List<RandomObject> list = new List<RandomObject>();
list.Add(new RandomObject { Id = 1, Weight = 101 });
list.Add(new RandomObject { Id = 2, Weight = 102 });
list.Add(new RandomObject { Id = 31, Weight = 103 });
list.Add(new RandomObject { Id = 41, Weight = 104 });
List<RandomObject> listRes = new List<RandomObject>();
for (int i = 0; i < 39; i++)
{
RandomObject lr = GetRandomList<RandomObject>(list, 1);
listRes.Add(lr);
}
List<RandomObject> list1 = new List<RandomObject>();
list1.Add(new RandomObject { Id = 1202, Weight = 100 });
list1.Add(new RandomObject { Id = 1203, Weight = 100 });
list1.Add(new RandomObject { Id = 1204, Weight = 101 });
list1.Add(new RandomObject { Id = 1206, Weight = 102 });
list1.Add(new RandomObject { Id = 1207, Weight = 103 });
List<RandomObject> listRes1 = new List<RandomObject>();
int count1 = listRes.FindAll(m => m.Id == 1).Count;
for (int i = 0; i < count1; i++)
{
RandomObject lr = GetRandomList<RandomObject>(list1, 1);
listRes1.Add(lr);
}
Console.WriteLine("Id为1的箱子放入的物品总数量为:" + listRes1.Count);
foreach (var item in listRes1)
{
Console.WriteLine(item.Id);
}
List<RandomObject> list2 = new List<RandomObject>();
list2.Add(new RandomObject { Id = 1205, Weight = 101 });
list2.Add(new RandomObject { Id = 1208, Weight = 102 });
list2.Add(new RandomObject { Id = 1209, Weight = 103 });
List<RandomObject> listRes2 = new List<RandomObject>();
int count2 = listRes.FindAll(m => m.Id == 2).Count;
for (int i = 0; i < count2; i++)
{
RandomObject lr = GetRandomList<RandomObject>(list2, 1);
listRes2.Add(lr);
}
Console.WriteLine("Id为2的箱子放入的物品总数量为:" + listRes2.Count);
foreach (var item in listRes2)
{
Console.WriteLine(item.Id);
}
List<RandomObject> list3 = new List<RandomObject>();
list3.Add(new RandomObject { Id = 1201, Weight = 100 });
List<RandomObject> listRes3 = new List<RandomObject>();
int count3 = listRes.FindAll(m => m.Id == 31).Count;
for (int i = 0; i < count3; i++)
{
RandomObject lr = GetRandomList<RandomObject>(list3, 1);
listRes3.Add(lr);
}
Console.WriteLine("Id为31的箱子放入的物品总数量为:" + listRes3.Count);
foreach (var item in listRes3)
{
Console.WriteLine(item.Id);
}
Console.WriteLine("Id为41的箱子放入的物品总数量为:" + (39 - listRes1.Count - listRes2.Count - listRes3.Count));
for (int i = 0; i < 39 - listRes1.Count - listRes2.Count - listRes3.Count; i++)
{
Console.WriteLine(1210);
}
Console.ReadKey();
}
}
}