如何高效的產生一億組1到1億的隨機排列?
用c#和python numpy都做了嘗試,8g內存機器跑幾十分鐘沒完成,如何破?
謝謝各位老司機的指導。補充說明:需要獲得一億組,1到1億的亂序排列。items=range(1,100000001)oklst=[]for i in range(0,len(items)):
temp=items[:] random.shuffle(temp) oklst.append(temp)循環一次要75秒,要循環1億次,有生之年就看不到了結果了。
謝邀,需要的範圍呢?直接把1到1億shuffle了可以嗎……大約需要一分多鐘吧如果要求範圍,可以用random.sample(xrange(maxrand + 1), 100000000),應該也需要一分多鐘====================================================================一億組……你光把這些數據存進內存內存就炸了,存進硬碟硬碟也炸了,這可是2^54量級,16PB的數量……你為什麼不去租神威太湖之光……
我的電腦上20秒跑完:
In [122]: %timeit np.random.shuffle(np.arange(1e8))
1 loop, best of 3: 17.2 s per loop
謝邀。
我只有再來修改答案了,因為我沒注意到是1億組1-1億的數據,那我只能先問一下了 @ff0018 :
你的需求真的有那麼大?我們先來看存儲:就算你優化存儲模式,自己寫一個二進位格式來做保存,1組數只要1G磁碟容量好了,1億組需要10萬T的存儲空間,2T家用硬碟大約400多RMB一個。大約2千萬人民幣了啊再來看看計算量:簡單查了下資料,普通家用CPU的浮點運算力也就每秒幾百億次而已,就算加上GPU,做到了每秒一組,1億組也需要三年時間。所以單台PC是無法完成你的計算需求的。
結論:要麼題主好好思考一下自己的需求,是不是可以用更高級的演算法來代替天量數據;要麼準備10萬T的數據存儲空間去超算中心下訂單吧。
-----------------------------------------------------以下是我看錯的題目,計算了1-1億的隨機序列一次。題主更新了內容:既然是產生1到1億的隨機序列,那直接產生一個序列,然後用random打亂一次就好了啊,題主的代碼完全不需要循環億次啊,只需要random.shuffle一次就打亂了。另外 @知之 的方案也是如此。
import random
def myrandom():
itmes = [x for x in range(10000000)]
random.shuffle(itmes)
我的機器內存太小,只能跑一千萬,大約是21.8秒,跑1億內存要出錯。
跑一千萬的結果:------------------------------------以下是老題目答案,先不刪除了。
題目寫得不夠詳細,那我就只考慮產生,也不考慮類別和大小了,也不考慮輸出了我認為要想快必須是不驗重。
但是既然題目是要求不重複,那我們設計一種絕對不會重複的產生辦法。比如說隨機數乘以系統時間:time.time()*random.random()
我的N年前的破電腦上產生1億個這樣的數字,也只用了52秒。
電腦配置:這段代碼我機器跑20秒左右。演算法的思路就是遍歷每個元素,並跟一個隨機位置的數據交換。
static void Main(string[] args)
{
int length = 100000000;
int[] array = new int[length];
for(int i = 0; i &< length; i++)
{
array[i] = i;
}
Random random = new Random();
for (int i = 0; i &< length; i++)
{
int index = random.Next(0, length);
int temp = array[i];
array[i] = array[index];
array[index] = temp;
}
//Console.WriteLine(string.Join(",", array));
Console.WriteLine("Done");
Console.ReadLine();
}
搜到一篇文章,剛好契合題主的問題,搬運一下
http://www.cnblogs.com/Geometry/archive/2011/01/25/1944582.html一億個不重複的隨機數?什麼類型?範圍是什麼,若是int 範圍也是1億辣么不重複不就是1到1億么?我已經開始懷疑我理解的不對了,請補充需求
這樣是105s?
為啥不能用呢?
本質上是把給定的數組亂序把每個位置都與隨機位置交換一下就好~_~
using System;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var arr = Enumerable.Range(1, 100000000).ToArray();
var startTime = DateTime.Now;
Randomize(arr);
Console.WriteLine(DateTime.Now - startTime);
//輸出太慢,隨便打30個出來看看就行了
Console.WriteLine(string.Join(" ", arr.Take(30)));
}
static void Randomize(int[] arr)
{
var r = new Random();
var length = arr.Length;
for (var i = 0; i &< length; i++)
{
//交換第i個與第隨機個
var j = r.Next(length);
var tmp = arr[j];
arr[j] = arr[i];
arr[i] = tmp;
}
}
}
}
先生成1到1e9 的順序集合…然後隨機交換…
==========高能演算法===============
直接取1億個隨機數就可以,因為都是偽隨機數,周期很長,不會重複不查重:1.8秒 o n查重:10秒 o nlog n重複了可以重新取,無所謂,人有多大膽,地有多大產==========以下為原回答============這個問題難點在於平均分布,用重複重取可以保證
期望為常數,o1複雜度。這個常數和值域和隨機次數有關,值域遠大的時候,非常接近1,我算過。
一般隨機數都是long,就算是int也是20多億,很小的常數記錄重複用hash優化為o1複雜度。所以最終結果是on,也就是接近一億次隨機和hash即可解決問題空間時間都是on,感覺不錯
內存佔用就算是long也才8億byte,不到1g(實際TreeSet佔用不到3g,HashSet不到10g)
java:
生成隨機數時間:1.8秒 o nTreeSet時間:210秒 o nlog nHashSet時間:128秒 o n由於java集合存的是對象,不是基本數據類型,所以性能很差。瀉藥。跟題主一起等大神。不過,用python跑一億隨機數,居然不死機
我猜想你想要的是shuffle,shuffle不是隨機的,當你前面(除了最後一個數)都確定了後,最後一個也就確定了。
我寫過類似的。
生成n位無規律的不重複的字元串。無規律和不重複怎麼保證呢,產生的性能又如何保證呢,下面我們一起走進科學。首先,字元串由a...z和A...Z和0...9組成,共62種。即每一位有62種可能。假設產生一個四位的字元串,
第一種可能是AAAA第二種可能是AAAB第三種可能是AAAC。。。這樣下來,絕對能保證不重複。但這樣還不夠,因為是順序的。那麼怎麼保證無序呢。也簡單,14776336=62*62*62*63,那麼必然有一個集合[1,100000000)存在一個數字——100000000,大於14776336並且是個很好看的數字。有這個集合有什麼用呢?簡單的說,在集合里必然存在1的鏡像數字1000000,2的鏡像數字2000000,…,9的鏡像數字是90000000,10的鏡像數字01000000,11的鏡像數字11000000,…,這樣,原本第一種排解組合AAAA,第二種排列組合AAAB,就不按順序取了,按這個數字的鏡像數字取。即第一個隨機字元串取第10000000個排列組合,第二個字元串取第20000000個排列組合…這樣,既不重複又看上去是無序的。而且,不用事先產生,可以隨時計算出來,計算效率其實是很高的。回到題主的問題來,題主需要的是純數字,也簡單,只要在產生的字元串上接一個密碼本就好了。比如第一位的字母a代表97,第一位的字母b代表98,…,第二位的字母a代表79,第二位的字母b代表89,…,就行了。推薦閱讀: