2015-09-01 29 views
7

Tôi muốn tạo 10.000 ma trận nhị phân ngẫu nhiên có cùng số lượng 1s mỗi hàng và mỗi cột dưới dạng ma trận nhị phân đã cho.Tạo ma trận nhị phân ngẫu nhiên

Ma trận là ~ 500 x ~ 10.000. Có khoảng 2.000.000 1s. Không có hàng hoặc cột nào.

Phương pháp hiện tại của tôi chuyển đổi ma trận nhị phân thành ma trận kề hai chân, và thực hiện 1.000.000 công tắc cạnh ngẫu nhiên để đảm bảo tính ngẫu nhiên. Điều này mất 13.000 giây cho 1 ma trận. Tôi đang mã hóa trong python, sử dụng một phiên bản sửa đổi của chức năng double_edge_swap của networkx.

Có cách nào hiệu quả hơn để tạo các ma trận như vậy không?

+2

tôi đang tìm kiếm tên của vấn đề này. Đây là vấn đề chính của [chụp cắt lớp rời rạc] (https://en.wikipedia.org/wiki/Discrete_tomography) "liên quan đến việc tái tạo hình ảnh nhị phân từ các đường kẻ ngang và dọc của nó" và đối với trường hợp 2 chiều (theo hướng mạng không song song), vấn đề nằm ở P. Thật thú vị khi biết cần 10.000 cái gì có thể tái tạo ngẫu nhiên. –

+0

Bạn nên xác định xem bạn có cần phân phối cụ thể hay không, vì các phương pháp khác nhau có thể cung cấp các bản phân phối hơi khác nhau. – Veedrac

+0

Nó phụ thuộc nếu bạn muốn cải thiện chỉ hiệu quả để tạo ra ma trận, giải pháp tốt sẽ gọi c (hàm để tạo ma trận từ trăn. – ElConrado

Trả lời

2

Tôi nghĩ đầu tiên bạn có thể xây dựng một trường hợp đặc biệt của một ma trận như vậy, và sau đó sử dụng numpy.shuffle Tuy nhiên nhiều khi:

row_sum = 2 
col_sum = 1 
arr  = np.zeros((5, 10)) 
#generate a special case, with given row_sum and col_sum 
for i in range(row_sum): 
    arr.ravel()[i::arr.shape[1]+row_sum] = 1 
arr 

Out[84]: 
array([[ 1., 1., 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 1., 1., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 1., 1., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 1., 1., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0., 1., 1.]]) 

np.random.shuffle(arr) 
#np.random.shuffle(arr.T) to shuffle the columns 
arr 
Out[89]: 
array([[ 0., 0., 0., 0., 1., 1., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0., 1., 1.], 
     [ 0., 0., 1., 1., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 1., 1., 0., 0.], 
     [ 1., 1., 0., 0., 0., 0., 0., 0., 0., 0.]]) 

arr.sum(1) #row sums 
Out[90]: array([ 2., 2., 2., 2., 2.]) 

arr.sum(0) #col sums 
Out[91]: array([ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]) 
+0

Tôi cũng gợi ý là một chút _lazy_ nếu có thể. Chúng ta có thể tạo một ma trận mới bằng cách xác định một danh sách các số hàng ('[2, 4, 1, 3, 0]' trong ví dụ) và đi đến 'np.array' quy mô đầy đủ nếu một phép gán phải được thực hiện hoặc một số loại _history của các thay đổi_ (nhưng tôi không chắc liệu nó có ổn không khi 'làm việc với mảng có kích thước động). – Vovanrock2002

+0

Mảng' numpy' động có thể sẽ không hoạt động, nó đã được sắp xếp trước khi http://stackoverflow.com/questions/ 6950456/how-to-tạo-một-dynamic-array.Tôi đoán một có lẽ đi cho 'Fortran' hoặc' C' cho mảng năng động.Nhưng chờ đợi, đó không còn là một giải pháp * lười biếng *, :) –

+2

Điều gì sẽ xảy ra nếu hàng được nói [6, 5, 6, 4, 6, 7, 4, 5, 4, 4] và các cột [3, 6, 5, 7, 2, 8, 3, 3, 4, 10] thay vì hằng số? Ngay cả khi bạn có một giải pháp đơn giản là xáo trộn không phải lúc nào cũng tạo ra người khác. –

Các vấn đề liên quan