列表中项目的随机分布达到最大计数
Random distribution of items in list up to a maximum count
我有 List
个项目,其中包含 x 个项目。
我想在其他列表中随机分发这些项目,条件是:
- Each List has a maximum size of y item (with y = 4)
- Each Item must be used a maximum of z times (with z = 5)
如果 x 不能同时被 y 和 z 整除,则可以包含少于 y 个项目的列表。
我正在寻找这种方法的 Java(从 1.6 到 1.8)实现。谢谢!
编辑
以下是我到目前为止的尝试:
List<Item> myItems; // Initialized in an other part
int y, z; // Initialized in an other part
int x = myItems.size();
List<List<Item>> myList = new ArrayList<List<Item>>();
int a = (int) Math.ceil((double)x/y);
Random random = new Random(new Random().nextInt());
for (int j = 0; j < a; j++) {
myList.add(j, new ArrayList<Item>());
}
for (int i = 0; i < x; i++) {
int r = random.nextInt(a);
while (myList.get(r).size() >= y) {
r = random.nextInt(a);
}
myList.get(r).add(myItems.get(i));
}
// Here myList is populated
以下代码应该可以工作。我在这里假设列表中的项目总数不应该改变。
public List<List<Item>> distribute(List<Item> list, int y, int z) {
int x = list.size();
int nLists = (int) Math.ceil((double)x/y);
// Create result lists
List<List<Item>> result = new ArrayList<>();
for (int j = 0; j < nLists; j++)
result.add(new ArrayList<Item>());
List<List<Item>> outputLists = new ArrayList<>(result);
// Create item count store
Map<Item, Integer> itemCounts = new HashMap<>();
for (Item item : list)
itemCounts.put(item, 0);
// Populate results
Random random = new Random();
for (int i = 0; i < x; i++) {
// Add a random item (from the remaining eligible items)
// to a random list (from the remaining eligible lists)
Item item = list.get(random.nextInt(list.size()));
List<Item> outputList = outputLists.get(random.nextInt(outputLists.size()));
outputList.add(item);
// Manage eligible output lists
if (outputList.size() >= y)
outputLists.remove(outputList);
// Manage eligible items
int itemCount = itemCounts.get(item).intValue() + 1;
if (itemCount >= z)
list.remove(item);
else
itemCounts.put(item, itemCount);
}
return result;
}
注意:上面的代码改变了原始列表。如果不需要,您应该在开始时创建列表的副本。
使用以下输入:
list = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29]
y = 4
z = 3
这给出了输出列表,例如:
[1,10,17,2]
[2,24,6,26]
[16,23,21]
[8,0,3,13]
[12,11,6,0]
[2,17,14,7]
[0,27,7,12]
[7,19,3]
在 运行 期间,项目 0
、2
和 7
达到了 z
限制,并且不再使用。
我有 List
个项目,其中包含 x 个项目。
我想在其他列表中随机分发这些项目,条件是:
- Each List has a maximum size of y item (with y = 4)
- Each Item must be used a maximum of z times (with z = 5)
如果 x 不能同时被 y 和 z 整除,则可以包含少于 y 个项目的列表。
我正在寻找这种方法的 Java(从 1.6 到 1.8)实现。谢谢!
编辑
以下是我到目前为止的尝试:
List<Item> myItems; // Initialized in an other part
int y, z; // Initialized in an other part
int x = myItems.size();
List<List<Item>> myList = new ArrayList<List<Item>>();
int a = (int) Math.ceil((double)x/y);
Random random = new Random(new Random().nextInt());
for (int j = 0; j < a; j++) {
myList.add(j, new ArrayList<Item>());
}
for (int i = 0; i < x; i++) {
int r = random.nextInt(a);
while (myList.get(r).size() >= y) {
r = random.nextInt(a);
}
myList.get(r).add(myItems.get(i));
}
// Here myList is populated
以下代码应该可以工作。我在这里假设列表中的项目总数不应该改变。
public List<List<Item>> distribute(List<Item> list, int y, int z) {
int x = list.size();
int nLists = (int) Math.ceil((double)x/y);
// Create result lists
List<List<Item>> result = new ArrayList<>();
for (int j = 0; j < nLists; j++)
result.add(new ArrayList<Item>());
List<List<Item>> outputLists = new ArrayList<>(result);
// Create item count store
Map<Item, Integer> itemCounts = new HashMap<>();
for (Item item : list)
itemCounts.put(item, 0);
// Populate results
Random random = new Random();
for (int i = 0; i < x; i++) {
// Add a random item (from the remaining eligible items)
// to a random list (from the remaining eligible lists)
Item item = list.get(random.nextInt(list.size()));
List<Item> outputList = outputLists.get(random.nextInt(outputLists.size()));
outputList.add(item);
// Manage eligible output lists
if (outputList.size() >= y)
outputLists.remove(outputList);
// Manage eligible items
int itemCount = itemCounts.get(item).intValue() + 1;
if (itemCount >= z)
list.remove(item);
else
itemCounts.put(item, itemCount);
}
return result;
}
注意:上面的代码改变了原始列表。如果不需要,您应该在开始时创建列表的副本。
使用以下输入:
list = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29]
y = 4
z = 3
这给出了输出列表,例如:
[1,10,17,2]
[2,24,6,26]
[16,23,21]
[8,0,3,13]
[12,11,6,0]
[2,17,14,7]
[0,27,7,12]
[7,19,3]
在 运行 期间,项目 0
、2
和 7
达到了 z
限制,并且不再使用。