Generating a matrix of 0s and 1s with constrained domains
4 commentaires
Réponses (2)
Hi @bil,
You mentioned, “I'd like to generate an n x n matrix of 0s and 1s with the constraint that the number of domain walls is equal to m. I define a domain wall by isolating the 1s in the matrix and then counting how many of its adjacent partners (left, right, up, down) are 0. The only way I can think of doing this so far is just iterating over all 2^(n*n) possible matrices and then picking out the right ones but I'm wondering if there is some pattern that I can exploit here. If it helps, we can assume periodic boundary conditions so that the edges of the matrix are connected to each other.Any thoughts appreciated!”
Please see my response to your comments below.
To efficiently generate the matrix with the specified number of domain walls, you can utilize combinatorial design rather than brute force. One approach is to construct the matrix iteratively while keeping track of the number of domain walls. Here are steps for implementation, Start with a zero matrix. Add 1s in such a way that each addition either creates a new domain wall or maintains existing ones. After each addition, check if the total number of domain walls matches m. If it exceeds m, backtrack and adjust placements. Make sure that when checking neighbors for domain walls, you consider wrapping around the edges. Here is a MATLAB function that generates such a matrix while ensuring that the number of domain walls equals m.
function matrix = generateMatrixWithDomainWalls(n, m) % Initialize an n x n zero matrix matrix = zeros(n);
% Function to calculate current number of domain walls function numWalls = countDomainWalls(mat) numWalls = 0; for i = 1:n for j = 1:n % Check right neighbor (with periodic conditions) if mat(i,j) == 1 && mat(i, mod(j,n)+1) == 0 numWalls = numWalls + 1; end % Check down neighbor (with periodic conditions) if mat(i,j) == 1 && mat(mod(i,n)+1,j) == 0 numWalls = numWalls + 1; end end end end
% Randomly place ones until we reach desired wall count while true % Randomly fill the matrix with ones and zeros matrix = randi([0, 1], n, n);
% Count the current number of domain walls currentWalls = countDomainWalls(matrix);
% If it matches m, break; otherwise, repeat if currentWalls == m break; end end
disp('Generated Matrix:'); disp(matrix); disp(['Number of Domain Walls: ', num2str(countDomainWalls(matrix))]); end
% Example usage: n = 5; % Size of the matrix m = 8; % Desired number of domain walls generateMatrixWithDomainWalls(n, m);
So, in the above code, my method uses random generation until a valid configuration is found, which may not be optimal for large matrices or high values of m. Further optimizations could involve backtracking or more intelligent placements based on existing configurations. Also, when you try to experiment with different values of n and m, you might notice certain statistical properties emerge regarding how densely packed the ones are relative to their adjacency constraints. However, by implementing this approach, you should be able to generate matrices efficiently while satisfying your constraints on domain walls. Feel free to modify and expand upon this code according to your specific needs!
Please let me know if you have any further questions.
1 commentaire
1 commentaire
Hi @ John D'Errico,
Your understanding of the matrix domain problem is indeed correct. In MATLAB, you can represent the matrix as a graph where nodes correspond to zero elements, and edges connect adjacent zeros. The conncomp function from the MATLAB graph toolbox can effectively identify connected components, allowing you to discern distinct domains.
For example, consider the following MATLAB code snippet to analyze the matrix:
M = [0 0 0 0 0; 0 1 1 1 0; 0 1 0 1 0; 0 1 1 1 0; 0 0 0 0 0]; [row, col] = find(M == 0); % Find zero elements G = graph(); % Create an empty graph
% Add edges for adjacent zeros for i = 1:length(row) for j = -1:1:1 for k = -1:1:1 if abs(j) ~= abs(k) % Ensure horizontal or vertical adjacency continue; end neighbor_row = row(i) + j; neighbor_col = col(i) + k; if neighbor_row > 0 && neighbor_row <= size(M, 1) && ... neighbor_col > 0 && neighbor_col <= size(M, 2) && ... M(neighbor_row, neighbor_col) == 0 G = addedge(G, sub2ind(size(M), row(i), col(i)), ... sub2ind(size(M), neighbor_row, neighbor_col)); end end end end
% Find connected components components = conncomp(G); disp(components);
Please see attached.
This code constructs a graph from the matrix and identifies connected components, effectively addressing your query. However, creating a matrix with a specific number of walls introduces complexity, as it requires careful design to maintain connectivity while adhering to the wall constraints. I do agree with you that further clarification on the properties of walls would be beneficial for a more tailored solution.
You are extremely knowledgeable and I do respect and appreciate your knowledge being shared with all of us. Great teamwork.
Voir également
Catégories
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!