随机N个数

xikboy 2009-04-05 03:36:43
我现在遇到一个需要随机N个数,N个数的总和加起来要等于某个数S ,现在办法是有,但速度太慢了。
大伙有没有好点的办法:

如:N=5 S=30

我要随机取5个数,这5个数的总和加起来要等于30

要速度快点的方法。
...全文
618 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
qizhengsheng 2009-04-07
  • 打赏
  • 举报
回复
LK MM太厉害了
搞得还可以 2009-04-07
  • 打赏
  • 举报
回复
mark
chuifengde 2009-04-07
  • 打赏
  • 举报
回复
CREATE TABLE  testgg (a INT IDENTITY,b INT)
go

DECLARE @Num VARCHAR(20),@C INT,@Base INT,@N int
DECLARE @i INT
DECLARE @sql1 VARCHAR(1000),@sql2 VARCHAR(1000),@sql3 VARCHAR(1000),@sql4 VARCHAR(1000)

SELECT @Num='30',@N=cast(@Num as int),@C=5,@Base=3

SET ROWCOUNT @N

INSERT testgg SELECT 0 FROM syscolumns s

SET @i=0
WHILE @i<@C
BEGIN
SELECT
@sql1=isnull(@sql1+',','')+CHAR(65+@i)+'.a',
@sql2=isnull(@sql2+',','')+' testgg '+CHAR(65+@i),
@sql3=isnull(@sql3+'+','')+CHAR(65+@i)+'.a',
@sql4=ISNULL(@sql4+' and ','')+CHAR(65+@i)+'.a>'+LTRIM(@Base)
SET @i=@i+1
END
EXEC('select '+@sql1+' from '+@sql2+' where '+@sql3 +'='+@Num+' and '+@sql4)
DROP TABLE testgg
--result
/*a a a a a
----------- ----------- ----------- ----------- -----------
4 14 4 4 4
4 13 5 4 4
4 12 6 4 4
4 11 7 4 4
4 10 8 4 4
4 9 9 4 4
4 8 10 4 4
4 7 11 4 4
4 6 12 4 4
4 5 13 4 4
4 4 14 4 4
4 13 4 5 4
4 12 5 5 4
4 11 6 5 4
4 10 7 5 4
4 9 8 5 4
4 8 9 5 4
4 7 10 5 4
4 6 11 5 4
4 5 12 5 4
4 4 13 5 4
4 12 4 6 4
4 11 5 6 4
4 10 6 6 4
4 9 7 6 4
4 8 8 6 4
4 7 9 6 4
4 6 10 6 4
4 5 11 6 4
4 4 12 6 4
*/
Limpire 2009-04-06
  • 打赏
  • 举报
回复
declare @n int, @s int, @i int
select @n = 5, @s = 30, @i = 3

declare @cyc int, @rand int, @sum int
select @cyc = 0, @sum = 0
while @cyc < @n-1
begin
set @rand = rand() * (@s - @sum - (@n-@cyc)*@i) + 3
set @sum = @sum + @rand
print @rand
set @cyc = @cyc + 1
end

set @rand = @s - @sum
print @rand

/*
4
8
5
7
6
*/
liangCK 2009-04-06
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 xikboy 的回复:]
LiangCK  MM写的,假设置是30 5 5 的时候,5个数据必需是6 这样第一次生成的数据只要不是6后面的就错了。
[/Quote]

sorry,写错

这样再试试:

CREATE PROC p_GetRandomNumber @N INT,@S INT,@M INT
AS
SET NOCOUNT ON;

DECLARE @tb TABLE(number INT);

DECLARE @number INT;
--DECLARE @N INT,@S INT;
DECLARE @i INT;
DECLARE @total INT;
--DECLARE @M INT

--N:个数,S:总数,M:不小于基数
--SELECT @N=10,@S=80,@M=10;

IF @N*@M>@S
BEGIN
RAISERROR('数字组合错误',16,1);
RETURN;
END

SET @i=1;
SET @number = RAND()*(@S/@N)+@M
INSERT @tb VALUES(@number)

WHILE @i < @N-1
BEGIN
SET @total=(SELECT SUM(number) FROM @tb);

SET @number = (RAND()*(@S-@total-(@N-@i)*@M))+@M;
INSERT @tb VALUES(@number);
SET @i=@i+1;
END

SET @total=(SELECT SUM(number) FROM @tb);
INSERT @tb VALUES(@S-@total);

--显示结果
--SELECT SUM(number) AS total FROM @tb;
SELECT * FROM @tb ORDER BY NEWID();
GO

EXEC p_GetRandomNumber 5,30,5;

GO
DROP PROC p_GetRandomNumber
aimee_99 2009-04-06
  • 打赏
  • 举报
回复
mark
jiyan1221 2009-04-06
  • 打赏
  • 举报
回复
标记一下,改天来学习~~
xikboy 2009-04-05
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 zuo_hy 的回复:]
这个问题要明确:
1,能不能重复;(这N个数里面同一数值可不可以出现多次,26+1+1+1+1=30,这种组合是否有效。)
2,这N个随机数有没有范围限制;(例如楼主后来补充的最小值为3,或最大值--当然是在这N个数和以内的更小的范围。像 3 <N <20)
[/Quote]


可以重复,但要符合你说的第二种情况。
xikboy 2009-04-05
  • 打赏
  • 举报
回复
LiangCK MM写的,假设置是30 5 5 的时候,5个数据必需是6 这样第一次生成的数据只要不是6后面的就错了。
E06620127 2009-04-05
  • 打赏
  • 举报
回复
我顶
弘毅致远 2009-04-05
  • 打赏
  • 举报
回复
具体还是参考小梁19楼的成果。
弘毅致远 2009-04-05
  • 打赏
  • 举报
回复
这个问题要明确:
1,能不能重复;(这N个数里面同一数值可不可以出现多次,26+1+1+1+1=30,这种组合是否有效。)
2,这N个随机数有没有范围限制;(例如楼主后来补充的最小值为3,或最大值--当然是在这N个数和以内的更小的范围。像 3<N<20)
新丁11111 2009-04-05
  • 打赏
  • 举报
回复
学习
liangCK 2009-04-05
  • 打赏
  • 举报
回复
封装成存储过程.

CREATE PROC p_GetRandomNumber @N INT,@S INT,@M INT
AS
SET NOCOUNT ON;

DECLARE @tb TABLE(number INT);

DECLARE @number INT;
--DECLARE @N INT,@S INT;
DECLARE @i INT;
DECLARE @total INT;
--DECLARE @M INT

--N:个数,S:总数,M:不小于基数
--SELECT @N=10,@S=80,@M=10;

IF @N*@M>@S
BEGIN
RAISERROR('数字组合错误',16,1);
RETURN;
END

SET @i=1;
SET @number = RAND()*(@S/@N)+@M
INSERT @tb VALUES(@number)

WHILE @i < @N-1
BEGIN
SET @total=(SELECT SUM(number) FROM @tb);

SET @number = (RAND()*(@S/(@N+@M)))+@M;
INSERT @tb VALUES(@number);
SET @i=@i+1;
END

SET @total=(SELECT SUM(number) FROM @tb);
INSERT @tb VALUES(@S-@total);

--显示结果
--SELECT SUM(number) AS total FROM @tb;
SELECT * FROM @tb ORDER BY NEWID();
GO

EXEC p_GetRandomNumber 5,80,10;

GO
DROP PROC p_GetRandomNumber
liangCK 2009-04-05
  • 打赏
  • 举报
回复
--这样再试试.

SET NOCOUNT ON;

DECLARE @tb TABLE(number INT);

DECLARE @number INT;
DECLARE @N INT,@S INT;
DECLARE @i INT;
DECLARE @total INT;
DECLARE @M INT

--N:个数,S:总数,M:不小于基数
SELECT @N=5,@S=80,@M=10;
SET @i=1;
SET @number = RAND()*(@S/@N)+@M
INSERT @tb VALUES(@number)

WHILE @i < @N-1
BEGIN
SET @total=(SELECT SUM(number) FROM @tb);

SET @number = (RAND()*(@S/(@N+@M)))+@M;
INSERT @tb VALUES(@number);
SET @i=@i+1;
END

SET @total=(SELECT SUM(number) FROM @tb);
INSERT @tb VALUES(@S-@total);

--显示结果
SELECT SUM(number) AS total FROM @tb;
SELECT * FROM @tb ORDER BY NEWID();
htl258_Tony 2009-04-05
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 HEROWANG 的回复:]
引用 14 楼 xikboy 的回复:
这样是OK的,我的要求还更复杂一点,如果有空就在帮帮忙,没空的话,我一会结贴。

我的要求是还有一个基数,生成的随机数不能低于某个数 I ,如

N=5 S=30 I=3


就是生成出来的5个数都不能低于3


要大于3的话,把每个随机数改成 3+27*rand()
[/Quote]..
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 xikboy 的回复:]
这样是OK的,我的要求还更复杂一点,如果有空就在帮帮忙,没空的话,我一会结贴。

我的要求是还有一个基数,生成的随机数不能低于某个数 I ,如

N=5 S=30 I=3


就是生成出来的5个数都不能低于3
[/Quote]

要大于3的话,把每个随机数改成 3+27*rand()
sdhdy 2009-04-05
  • 打赏
  • 举报
回复
友情帮顶!
xikboy 2009-04-05
  • 打赏
  • 举报
回复
这样是OK的,我的要求还更复杂一点,如果有空就在帮帮忙,没空的话,我一会结贴。

我的要求是还有一个基数,生成的随机数不能低于某个数 I ,如

N=5 S=30 I=3


就是生成出来的5个数都不能低于3
liangCK 2009-04-05
  • 打赏
  • 举报
回复
--这样试试:

SET NOCOUNT ON;

DECLARE @tb TABLE(number INT);

DECLARE @number INT;
DECLARE @N INT,@S INT;
DECLARE @i INT;
DECLARE @total INT;

SELECT @N=5,@S=30,@i=1;
SET @number = RAND()*(@S-@N+1)+1
INSERT @tb VALUES(@number)

WHILE @i < @N-1
BEGIN
SET @total=(SELECT SUM(number) FROM @tb);

SET @number = RAND()*(@S-@N-@total+@i)+1;
INSERT @tb VALUES(@number);

SET @i=@i+1;
END

SET @total=(SELECT SUM(number) FROM @tb);
INSERT @tb VALUES(@S-@total);

--显示结果
SELECT SUM(number) AS total FROM @tb;
SELECT * FROM @tb ORDER BY NEWID();
加载更多回复(12)

34,576

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧