annotate toolboxes/graph_visualisation/graphViz4Matlab/layouts/Randlayout.m @ 0:cc4b1211e677 tip

initial commit to HG from Changeset: 646 (e263d8a21543) added further path and more save "camirversion.m"
author Daniel Wolff
date Fri, 19 Aug 2016 13:07:06 +0200
parents
children
rev   line source
Daniel@0 1 classdef Randlayout < Abstractlayout
Daniel@0 2 % A greedy, random layout - gives a different layout each time its called.
Daniel@0 3 % Matthew Dunham
Daniel@0 4 % University of British Columbia
Daniel@0 5 % http://www.cs.ubc.ca/~mdunham/
Daniel@0 6
Daniel@0 7 properties
Daniel@0 8 xmin; % The left most point on the graph axis in data units
Daniel@0 9 xmax; % The right most point on the graph axis in data units
Daniel@0 10 ymin; % The bottom most point on the graph axis in data units
Daniel@0 11 ymax; % The top most point on the graph axis in data units
Daniel@0 12 adjMatrix; % The adjacency matrix
Daniel@0 13 maxNodeSize; % The maximum diameter of a node in data units
Daniel@0 14 image; % An image for the button that will lanuch this layout
Daniel@0 15 name; % A unique name for instances of this class
Daniel@0 16 shortDescription; % A description for use in the tooltips
Daniel@0 17 nodeSize; % The calculated node size, call dolayout() before accessing
Daniel@0 18 centers; % The calculated node centers in an n-by-2 matrix
Daniel@0 19 seed; % The seed used to generate the last layout.
Daniel@0 20 end
Daniel@0 21
Daniel@0 22
Daniel@0 23
Daniel@0 24 methods
Daniel@0 25
Daniel@0 26 function obj = Randlayout(name,seed)
Daniel@0 27 % constructor - seed is optional.
Daniel@0 28 if(nargin < 1)
Daniel@0 29 obj.name = 'Randlayout';
Daniel@0 30 else
Daniel@0 31 obj.name = name;
Daniel@0 32 end
Daniel@0 33 if(nargin < 2)
Daniel@0 34 seed = 31;
Daniel@0 35 end
Daniel@0 36 obj.seed = seed;
Daniel@0 37 load glicons
Daniel@0 38 obj.image = icons.random;
Daniel@0 39 obj.shortDescription = 'Random Greedy Layout';
Daniel@0 40
Daniel@0 41 end
Daniel@0 42 end
Daniel@0 43
Daniel@0 44 methods(Access = 'protected')
Daniel@0 45
Daniel@0 46 function calcLayout(obj)
Daniel@0 47 rand('twister',obj.seed); randn('state',obj.seed);
Daniel@0 48 obj.seed = obj.seed + 1;
Daniel@0 49 nnodes = size(obj.adjMatrix,1);
Daniel@0 50 obj.nodeSize = min(obj.maxNodeSize,2*(obj.xmax-obj.xmin)/nnodes);
Daniel@0 51 npoints = 25;
Daniel@0 52 locdist = ones(npoints,npoints);
Daniel@0 53 c = floor(0.4*npoints):ceil(0.6*npoints);
Daniel@0 54 locdist(c,c) = 1.5; % slightly favour the center
Daniel@0 55 locdist = locdist./sum(locdist(:)); % discrete distribution over locations
Daniel@0 56 locations = zeros(nnodes,2); % holds indices into locdist
Daniel@0 57 nsize = ceil(npoints*(obj.nodeSize/2)/(obj.xmax - obj.xmin+obj.nodeSize));
Daniel@0 58 for i=1:nnodes
Daniel@0 59 while(true)
Daniel@0 60 [xcandidate,ycandidate] = obj.sample(locdist);
Daniel@0 61 [valid,locdist] = obj.isfree(xcandidate,ycandidate,locdist,nsize);
Daniel@0 62 if(valid)
Daniel@0 63 locations(i,:) = [xcandidate,ycandidate];
Daniel@0 64 locdist = obj.radiate(locdist,locations,npoints);
Daniel@0 65 break;
Daniel@0 66 end
Daniel@0 67 end
Daniel@0 68 end
Daniel@0 69 nedges = sum(obj.adjMatrix,1) + sum(obj.adjMatrix,2)';
Daniel@0 70 [val,perm] = sort(nedges,'descend');
Daniel@0 71 locations = locations(perm,:);
Daniel@0 72 obj.mapLocationsToAxes(locations,npoints);
Daniel@0 73 end
Daniel@0 74
Daniel@0 75 function mapLocationsToAxes(obj,locations,npoints)
Daniel@0 76 % Map sampled locations on a grid to actual points on the graph
Daniel@0 77 % axes.
Daniel@0 78 xndx = locations(:,1); yndx = locations(:,2);
Daniel@0 79 xmin = obj.xmin + obj.nodeSize/2;
Daniel@0 80 xmax = obj.xmax - obj.nodeSize/2;
Daniel@0 81 ymin = obj.ymin + obj.nodeSize/2;
Daniel@0 82 ymax = obj.ymax - obj.nodeSize/2;
Daniel@0 83 xstep = (xmax - xmin) /npoints;
Daniel@0 84 ystep = (ymax - ymin) /npoints;
Daniel@0 85 xpos = xmin+xstep:xstep:xmax;
Daniel@0 86 ypos = ymin+ystep:ystep:ymax;
Daniel@0 87 obj.centers = [xpos(xndx)',ypos(yndx)'];
Daniel@0 88 end
Daniel@0 89
Daniel@0 90 function [valid,locdist2] = isfree(obj,xcandidate,ycandidate,locdist,nsize)
Daniel@0 91 % Check if the sampled location is valid. Regardless, zero out the
Daniel@0 92 % spot so that we don't sample from here again.
Daniel@0 93 xndx = max(1,xcandidate-nsize):min(xcandidate+nsize,size(locdist,2));
Daniel@0 94 yndx = max(1,ycandidate-nsize):min(ycandidate+nsize,size(locdist,1));
Daniel@0 95 nodeArea = locdist(xndx,yndx);
Daniel@0 96 valid = all(nodeArea(:));
Daniel@0 97 locdist2 = locdist;
Daniel@0 98 locdist2(xndx,yndx) = 0;
Daniel@0 99 locdist2 = locdist2 ./sum(locdist(:));
Daniel@0 100 end
Daniel@0 101
Daniel@0 102 function locdist = radiate(obj,locdist,locations,npoints)
Daniel@0 103 % Update the location probability distribution.
Daniel@0 104 n = nnz(locations(:,1));
Daniel@0 105 loczeros = locdist == 0;
Daniel@0 106 for i=1:n
Daniel@0 107 [x y] = meshgrid(1:npoints,1:npoints);
Daniel@0 108 x = x(:); y = y(:);
Daniel@0 109 dist = sqrt((x-locations(i,1)).^2 + (y-locations(i,2)).^2);
Daniel@0 110 locdist = locdist + reshape(dist,npoints,npoints)';
Daniel@0 111 end
Daniel@0 112 locdist(loczeros) = 0;
Daniel@0 113 locdist = locdist ./sum(locdist(:));
Daniel@0 114 end
Daniel@0 115
Daniel@0 116 function [xndx,yndx] = sample(obj,dist)
Daniel@0 117 % Sample a single value from the non-uniform discrete distribution.
Daniel@0 118 if(isnan(dist(1)))
Daniel@0 119 perm = randperm(size(dist,1));
Daniel@0 120 xndx = perm(1);
Daniel@0 121 yndx = perm(2);
Daniel@0 122 return;
Daniel@0 123 end
Daniel@0 124 r = rand;
Daniel@0 125 cumprob = cumsum(dist(:));
Daniel@0 126 s = sum(r > cumprob(1:end-1)) + 1;
Daniel@0 127 [xndx,yndx] = ind2sub(size(dist),s);
Daniel@0 128 end
Daniel@0 129
Daniel@0 130 end
Daniel@0 131
Daniel@0 132
Daniel@0 133
Daniel@0 134 end