diff toolboxes/graph_visualisation/graphViz4Matlab/layouts/Randlayout.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolboxes/graph_visualisation/graphViz4Matlab/layouts/Randlayout.m	Tue Feb 10 15:05:51 2015 +0000
@@ -0,0 +1,134 @@
+classdef Randlayout < Abstractlayout
+% A greedy, random layout - gives a different layout each time its called. 
+% Matthew Dunham
+% University of British Columbia 
+% http://www.cs.ubc.ca/~mdunham/
+
+     properties
+        xmin;               % The left most point on the graph axis in data units           
+        xmax;               % The right most point on the graph axis in data units
+        ymin;               % The bottom most point on the graph axis in data units
+        ymax;               % The top most point on the graph axis in data units
+        adjMatrix;          % The adjacency matrix
+        maxNodeSize;        % The maximum diameter of a node in data units
+        image;              % An image for the button that will lanuch this layout
+        name;               % A unique name for instances of this class
+        shortDescription;   % A description for use in the tooltips
+        nodeSize;           % The calculated node size, call dolayout() before accessing
+        centers;            % The calculated node centers in an n-by-2 matrix
+        seed;               % The seed used to generate the last layout. 
+     end
+    
+    
+     
+     methods
+         
+         function obj = Randlayout(name,seed)
+         % constructor - seed is optional. 
+            if(nargin < 1)
+                obj.name = 'Randlayout';
+            else
+                obj.name = name;
+            end
+            if(nargin < 2)
+                seed = 31;
+            end
+            obj.seed = seed;
+            load glicons
+            obj.image = icons.random;
+            obj.shortDescription = 'Random Greedy Layout';
+             
+         end
+     end
+     
+     methods(Access = 'protected')
+       
+         function calcLayout(obj)
+             rand('twister',obj.seed); randn('state',obj.seed);
+             obj.seed = obj.seed + 1;
+             nnodes = size(obj.adjMatrix,1);
+             obj.nodeSize = min(obj.maxNodeSize,2*(obj.xmax-obj.xmin)/nnodes);
+             npoints = 25;
+             locdist = ones(npoints,npoints);
+             c = floor(0.4*npoints):ceil(0.6*npoints);
+             locdist(c,c) = 1.5;                 % slightly favour the center
+             locdist = locdist./sum(locdist(:)); % discrete distribution over locations
+             locations = zeros(nnodes,2);        % holds indices into locdist
+             nsize = ceil(npoints*(obj.nodeSize/2)/(obj.xmax - obj.xmin+obj.nodeSize));
+             for i=1:nnodes
+                while(true)
+                    [xcandidate,ycandidate] = obj.sample(locdist);
+                    [valid,locdist] = obj.isfree(xcandidate,ycandidate,locdist,nsize);
+                    if(valid)
+                       locations(i,:) = [xcandidate,ycandidate];
+                       locdist = obj.radiate(locdist,locations,npoints);
+                       break; 
+                    end
+                end
+             end
+             nedges = sum(obj.adjMatrix,1) + sum(obj.adjMatrix,2)';
+             [val,perm] = sort(nedges,'descend');
+             locations = locations(perm,:);
+             obj.mapLocationsToAxes(locations,npoints);
+         end
+         
+         function mapLocationsToAxes(obj,locations,npoints)
+         % Map sampled locations on a grid to actual points on the graph
+         % axes. 
+             xndx = locations(:,1); yndx = locations(:,2);
+             xmin = obj.xmin + obj.nodeSize/2;
+             xmax = obj.xmax - obj.nodeSize/2;
+             ymin = obj.ymin + obj.nodeSize/2;
+             ymax = obj.ymax - obj.nodeSize/2;
+             xstep = (xmax - xmin) /npoints;
+             ystep = (ymax - ymin) /npoints;
+             xpos = xmin+xstep:xstep:xmax;
+             ypos = ymin+ystep:ystep:ymax;
+             obj.centers =  [xpos(xndx)',ypos(yndx)'];
+         end
+         
+         function [valid,locdist2] = isfree(obj,xcandidate,ycandidate,locdist,nsize)
+         % Check if the sampled location is valid. Regardless, zero out the
+         % spot so that we don't sample from here again. 
+             xndx = max(1,xcandidate-nsize):min(xcandidate+nsize,size(locdist,2));
+             yndx = max(1,ycandidate-nsize):min(ycandidate+nsize,size(locdist,1));
+             nodeArea = locdist(xndx,yndx);
+             valid = all(nodeArea(:));
+             locdist2 = locdist;
+             locdist2(xndx,yndx) = 0;
+             locdist2 = locdist2 ./sum(locdist(:));
+         end
+         
+         function locdist = radiate(obj,locdist,locations,npoints)
+         % Update the location probability distribution.
+             n = nnz(locations(:,1));
+             loczeros = locdist == 0;
+             for i=1:n             
+                 [x y] = meshgrid(1:npoints,1:npoints);
+                 x = x(:); y = y(:);
+                 dist = sqrt((x-locations(i,1)).^2 + (y-locations(i,2)).^2);
+                 locdist = locdist +  reshape(dist,npoints,npoints)';       
+             end
+             locdist(loczeros) = 0;
+             locdist = locdist ./sum(locdist(:));
+         end
+ 
+        function [xndx,yndx] = sample(obj,dist)
+        % Sample a single value from the non-uniform discrete distribution. 
+            if(isnan(dist(1)))
+                perm = randperm(size(dist,1));
+                xndx = perm(1);
+                yndx = perm(2);
+                return;
+            end
+            r = rand;
+            cumprob = cumsum(dist(:));
+            s = sum(r > cumprob(1:end-1)) + 1;
+            [xndx,yndx] = ind2sub(size(dist),s);
+        end
+        
+     end
+    
+    
+    
+end
\ No newline at end of file