3
$\begingroup$

I am generating a random N x N matrix, but with a certain restriction. What I'm trying to do is that when there's a "1" in a position, all neighboring positions must turn to "0" (so if [i,j] = 1, then [i+1,j] = [i-1,j] = [i,j-1] = [i, j+1] = 0.)

Currently I am working with something like this:

Num = 10
mat = RandomInteger[{0,1},{Num, Num}]

Table[If[themat[[i,j]] == 1, themat[[i+1,j]]==0, themat[[i,j]]]

However, I keep getting the error that "Part specification i is neither a machine-sized integer nor a list of machine-sized integers". Could someone please help me with this? Thank you!

$\endgroup$
  • $\begingroup$ Look at your last line of code. Assuming mat[[row,col]] notation. What happens if it finds a 1 in row 10? When you have figured that out then think about finding a 1 in column 10 or row 1 or column 1 or in each of the four corners? That should be enough of a hint for you to fix the code. Using Table may not be the easiest method to understand in this case. $\endgroup$ – Bill Nov 7 '14 at 1:49
  • $\begingroup$ @WayneFullen does this only apply to internal elements, i.e. what about corners of array ({1,1},{1,num},{num,1},{num,num}) or boundary? $\endgroup$ – ubpdqn Nov 7 '14 at 3:58
1
$\begingroup$

Your problem is not well defined because you do not specify adequately what you mean by "random." You imply that the only entries are 0 and 1. Is that what you want? Do you have a required proportion P of 1s in the entire matrix where P< 0.5)? There are numerous trivial "solutions," for instance setting the entries of the entire matrix to 0 except a single entry to 1.

Please specify your requirements very crisply and completely.

$\endgroup$
  • $\begingroup$ Sorry for not being clear; what I'm looking for is a uniform distribution for the entire matrix, where the probability of 0 or 1 is equal (the only exception is when there are neighboring 1's, I would want to change those to 0's). $\endgroup$ – Wayne Fullen Nov 7 '14 at 0:52
  • $\begingroup$ David, you address the unclear issues very nicely, but this might be better off as a comment (yet) . @WayneFullen please add all necessary info to the question. $\endgroup$ – Yves Klett Nov 7 '14 at 7:24
  • $\begingroup$ If your matrix has 50% 1s and 50% 0s and obeys your neighborhood restriction, isn't the only solution equivalent to a checkerboard? $\endgroup$ – David G. Stork Nov 8 '14 at 0:32
1
$\begingroup$

Starting data, biased to zero for a reason that will become apparent:

Num = 10
SeedRandom[0]
mat = RandomChoice[{4, 1} -> {0, 1}, {Num, Num}];

$\left( \begin{array}{cccccccccc} 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 0 \\ 0 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 1 & 1 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 1 & 0 \\ 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ \end{array} \right)$

A matrix with zero in every position that in the original has a one in one of the eight neighboring places:

ker = 1 - BoxMatrix[0, 3]

mask = 1 - Unitize@ListCorrelate[ker, mat, {2, 2}]
{{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}

$\left( \begin{array}{cccccccccc} 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 1 & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 1 & 1 & 1 & 0 & 0 & 0 & 0 \\ 1 & 1 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 1 \\ 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 1 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ \end{array} \right)$

Multiply (simple multiplication, not matrix multiplication) the two and you get:

mask * mat // MatrixForm

$\left( \begin{array}{cccccccccc} 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \end{array} \right)$

As you can see only three ones survive.

$\endgroup$
1
$\begingroup$
ClearAll[filterF];
filterF[mat_, cornerneighbors_: True] := Block[{ker = If[cornerneighbors, 1 - BoxMatrix[0, 3],
   {{0, 1, 0}, {1, 0, 1}, {0, 1, 0}}]},
   Developer`PartitionMap[If[FreeQ[ker #, 1], #[[2, 2]], 0] &, mat, {3, 3}, 1, 2, mat]]

Using Mr.Wizard's example:

SeedRandom[0];
mat = RandomChoice[{4, 1} -> {0, 1}, {10, 10}];
Row[Labeled[MatrixForm@#, #2, Top] & @@@ {{mat, "mat"},
   {filterF@mat, "filterF@mat"}, {filterF[mat, False],"filterF[mat,False]" }}, Spacer[10]]

enter image description here

$\endgroup$
0
$\begingroup$

Here's my attempt to arrive at what I think you meant. However, I doubt that this matrix will have a random distribution since it was processed from a random matrix.

Module[{onePositions,aloneOnePositions,onePositionsDeleted,newMatrix,redHighLight},
(* All positions of 1 *)
onePositions=Position[mat,1];

(* All positions of 1 that are not in the neighborhood of any previous positions *)
aloneOnePositions=onePositions//.{a___,b_,c___,d_,e___}/;d==b+{0,1}||d==b+{1,0}:>{a,b,c,e};

(* All positions of 1 that are in the neighborhood of any previous positions *)
onePositionsDeleted=Complement[onePositions,aloneOnePositions];

(* New matrix is formed by replacing all positions of 1 in the neighboorhood of any previous positions to 0 *)
newMatrix=ReplacePart[mat,onePositionsDeleted->0];

(* Display and compare *)
redHighLight[m_]:=ReplacePart[m,aloneOnePositions->Style[1,Red]]//Grid;
redHighLight/@{mat,newMatrix}//Grid[{{"mat","newMatrix"},#},Frame->All]&
]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.