In[]:=
RandomBinaryMatrix[rows_,cols_,n_]:=Normal[SparseArray[RandomSample[Flatten[Table[{i,j}->1,{i,1,rows},{j,1,cols}],1],n],{rows,cols}]]
In[]:=
RandomBinaryVector[elements_,n_]:=Normal[SparseArray[RandomSample[Table[{i}->1,{i,1,elements}],n],{elements}]]
In[]:=
MatrixSwap[m_]:=Module[{total,target,mCoords,swapCandidate,quadCandidates,n,quadCandidate},​​total=Total[m,2];​​target=If[total<(Apply[Times,Dimensions[m]]/2),1,0];​​mCoords=Position[m,target];​​swapCandidate=RandomSample[mCoords,1][[1]];​​quadCandidates=RandomSample[DeleteCases[mCoords,swapCandidate]];​​n=1;​​Until[(quadCandidate={{m[[swapCandidate[[1]],swapCandidate[[2]]]],m[[swapCandidate[[1]],quadCandidates[[n,2]]]]},{m[[quadCandidates[[n,1]],swapCandidate[[2]]]],m[[quadCandidates[[n,1]],quadCandidates[[n,2]]]]}};(swapCandidate[[1]]=!=quadCandidates[[n,1]]&&swapCandidate[[2]]=!=quadCandidates[[n,2]]&&Total[quadCandidate]==={1,1}&&Total[quadCandidate,{2}]==={1,1})||n==(total-1)),n++];​​ReplacePart[m,MapThread[#1->#2&,{{{swapCandidate[[1]],swapCandidate[[2]]},{swapCandidate[[1]],quadCandidates[[n,2]]},{quadCandidates[[n,1]],swapCandidate[[2]]},{quadCandidates[[n,1]],quadCandidates[[n,2]]}},Flatten[Reverse[quadCandidate]]}]]​​]
In[]:=
Options[MatrixRandomize]={Method->"Free","Swaps"->1000};​​​​MatrixRandomize[m_,OptionsPattern[]]:=Module[{rows,cols,rowTotals,colTotals,grandTotal,method},​​{rows,cols}=Dimensions[m];​​rowTotals=Total[m,{2}];​​colTotals=Total[m];​​grandTotal=Total[colTotals];​​method=OptionValue[Method];​​Which[​​method==="Free",​​RandomBinaryMatrix[rows,cols,grandTotal],​​method==="PreserveRowTotals",​​Map[RandomBinaryVector[cols,#]&,rowTotals],​​method==="PreserveColumnTotals",​​Transpose[Map[RandomBinaryVector[rows,#]&,colTotals]],​​method==="PreserveRowAndColumnTotals",​​Nest[MatrixSwap,m,OptionValue["Swaps"]]​​]​​]
Make a nested matrix using sample with weights.
In[]:=
locations=Flatten[Table[{i,j},{i,1,20},{j,1,20}],1];​​weights=1./Map[Apply[Times,#]&,locations];​​testMatrix=Normal[SparseArray[Map[#->1&,RandomSample[weights->locations,200]],{20,20}]];​​r1=MatrixRandomize[testMatrix];​​r2=MatrixRandomize[testMatrix,Method->"PreserveRowTotals"];​​r3=MatrixRandomize[testMatrix,Method->"PreserveColumnTotals"];​​r4=MatrixRandomize[testMatrix,Method->"PreserveRowAndColumnTotals","Swaps"->10000];​​GraphicsRow[Map[ColorNegate[Image[#,ImageSize->150]]&,{testMatrix,r1,r2,r3,r4}]]
Out[]=