如何在C#中生成符合指定规则的人员-对象二维排列结构?
1000名人员分配50个对象的C#实现方案
核心思路
你之前的问题在于错误地给对象做了去重处理,而需求明确允许人员共享同一对象。正确的实现方向是不需要限制对象的重复选择,根据场景选择随机分配或可控均衡分配即可。
方案1:完全随机分配(最简单的实现)
每个人员独立从50个对象中随机选取一个,对象可被多次选中,也可能有部分对象全程未被使用,完全符合需求。
方案2:可控均衡分配(按需调整分配密度)
如果需要让被使用的对象承载的人数更均衡,可以先指定要使用的对象数量,再按人数均分后分配,避免出现某几个对象被大量选择的情况。
代码实现
基础类定义
先定义人员和对象的基础结构(可根据实际需求修改):
// 人员类 public class Person { public int Id { get; set; } public AssignedObject AssignedObject { get; set; } } // 待分配的对象类 public class AssignedObject { public int Id { get; set; } public string Name { get; set; } }
方案1:完全随机分配代码
using System; using System.Collections.Generic; using System.Linq; class Program { static void Main() { // 初始化50个对象 var objectPool = Enumerable.Range(1, 50) .Select(id => new AssignedObject { Id = id, Name = $"对象{id}" }) .ToList(); // 初始化1000名人员 var people = Enumerable.Range(1, 1000) .Select(id => new Person { Id = id }) .ToList(); // 随机分配:每个人员独立选择对象,不限制重复 var random = new Random(); foreach (var person in people) { int randomObjIndex = random.Next(objectPool.Count); person.AssignedObject = objectPool[randomObjIndex]; } // 可选:输出分配结果统计 var distribution = people.GroupBy(p => p.AssignedObject.Id) .ToDictionary(g => g.Key, g => g.Count()); foreach (var item in distribution.OrderBy(k => k.Key)) { Console.WriteLine($"对象{item.Key} 分配人数:{item.Value}"); } } }
方案2:可控均衡分配代码
比如指定使用30个对象,让每个被使用的对象分配的人数尽可能相近:
using System; using System.Collections.Generic; using System.Linq; class Program { static void Main() { const int totalPeople = 1000; const int totalObjects = 50; const int usedObjectCount = 30; // 指定要使用的对象数量 // 初始化全部对象,随机挑选指定数量的对象用于分配 var allObjects = Enumerable.Range(1, totalObjects) .Select(id => new AssignedObject { Id = id, Name = $"对象{id}" }) .ToList(); var random = new Random(); var selectedObjects = allObjects.OrderBy(_ => random.Next()).Take(usedObjectCount).ToList(); // 初始化人员列表 var people = Enumerable.Range(1, totalPeople) .Select(id => new Person { Id = id }) .ToList(); // 计算基础分配人数和剩余人数 int baseAssignCount = totalPeople / usedObjectCount; int remainingPeople = totalPeople % usedObjectCount; int currentPersonIndex = 0; for (int i = 0; i < selectedObjects.Count; i++) { // 前remainingPeople个对象多分配1人,保证人数均分 int assignCount = baseAssignCount + (i < remainingPeople ? 1 : 0); for (int j = 0; j < assignCount; j++) { people[currentPersonIndex].AssignedObject = selectedObjects[i]; currentPersonIndex++; } } // 可选:输出分配结果统计 var distribution = people.GroupBy(p => p.AssignedObject.Id) .ToDictionary(g => g.Key, g => g.Count()); foreach (var item in distribution.OrderBy(k => k.Key)) { Console.WriteLine($"对象{item.Key} 分配人数:{item.Value}"); } } }
说明
- 方案1适合对分配均匀度无要求的场景,代码极简,完全满足“无需使用全部对象”的要求。
- 方案2适合需要避免极端分配情况的场景,可通过调整
usedObjectCount参数控制使用的对象数量,分配结果更均衡。
内容的提问来源于stack exchange,提问作者Hendrix
相关产品推荐
相关产品推荐

