我正在尝试在随机时间段内分配某个值。为了澄清更多,
假设我想在 30 天内分发产品 x 和 y。我有 1500 件产品 x 必须在 30 天内随机分发。1天内可以分发的物品数量有限制.max即60件。
我一直在试图刮掉一些东西,但对这个问题真的不成功。我真的是编程新手,所以如果有人能指出我正确的方法,那将是一个真正的帮助。
作为附录,如果我有超过 1 个项目要分发(例如假设有 x,y 和 z)具有不同的值(例如 1500、1000、900),并且对特定日期可以分发的项目数量有限制(每天最多 150 个),这个逻辑是否仍然有效,或者我应该看看新的东西。另外,是否应该进行检查,例如假设 x 的 100、y 的 20 和 z 的 30 分布,然后减去该值(第二天我有 x 的 1400、y 的 980 和 z 的 870 可供分配),因为这会改变排列值?
谢谢你们!
这应该适合您!
days = 30;
elem = 1500;
max_x = 60;
x = randi(max_x,days,1);
remain = elem - sum(x);
while remain > 0
idx_1 = find(x < max_x); % Numbers that can be increased
idx_fill = randperm(numel(idx_1),remain);
% idx_fill = idx_fill(:,1); % Might be needed
x(idx_1(idx_fill)) = x(idx_1(idx_fill)) + 1;
remain = elem - sum(x);
end
while remain < 0
idx_2 = find(x > 0); % Numbers that can be reduced
idx_red = randperm(numel(idx_2),abs(remain));
% idx_red = idx_red(:,1); % Might be needed
x(idx_2(idx_red)) = x(idx_2(idx_red)) - 1;
remain = elem - sum(x);
end
sum(x)
max(x)
min(x)
ans = 1500
ans = 60
ans = 34
这是一种直观的方法,适用于 2D 数组,没有"randperm":
N = 36000; % for three hundred years
days = 30; % days
elem = 1500; % elements in ten years
min_x = 0; % daily minimum
max_x = 60; % daily maximum
tic
x = zeros(days, N);
for hh = 1:elem
% Add new candidates
inds = randi(days, N, 1);
inds = ((1:N).' - 1) * days + inds;
x(inds) = x(inds) + 1;
% Check
inds_chck = x > max_x;
any_inds_chck = any(inds_chck);
find_any_inds_chck = find(any_inds_chck);
ctrl = numel(find_any_inds_chck);
while ctrl>0
% First remove baddies
inds = inds(find_any_inds_chck);
x(inds) = x(inds) - 1;
% Then reassign to new candidates
inds = randi(days, ctrl, 1);
inds = (find_any_inds_chck.' - 1) * days + inds;
x(inds) = x(inds) + 1;
% Check again
inds_chck = x(:, find_any_inds_chck) > max_x;
any_inds_chck = any(inds_chck);
find_any_inds_chck = find(any_inds_chck);
ctrl = numel(find_any_inds_chck);
end
end
toc
但价格是一个奇怪的概率函数:
hist(x(:), max_x - min_x + 1)
请注意,约束对自由度也有明显的影响。
另请注意,他们试图在 Matlab 中生成具有最大值、最小值和平均值(平均值)的随机数中回答类似的问题。