/[drupal]/contributions/sandbox/aronnovak/graph_creating/common.php
ViewVC logotype

Contents of /contributions/sandbox/aronnovak/graph_creating/common.php

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.14 - (show annotations) (download) (as text)
Tue Aug 15 19:18:43 2006 UTC (3 years, 3 months ago) by aronnovak
Branch: MAIN
CVS Tags: HEAD
Changes since 1.13: +67 -30 lines
File MIME type: text/x-php
Beautifiled code and fixed bugs
1 <?php
2 // $Id$
3 /**
4 * Common things in SNA related files
5 *
6 * Store functions, constants that almost all file needs in SNA module
7 * @author Aron Novak <aaron@szentimre.hu
8 * @version 0.1
9 * @package sna
10 */
11
12 /**
13 * The path of data files. This path can be modify trough drupal settings.
14 */
15 define('FILES_PATH', './');
16 /**
17 * The path to the visualization applet
18 */
19 define('APPLET_PATH', 'sites/sna.drupaler.net/applet_tryout/');
20 /**
21 * Set the dba_handler
22 */
23 define('DBA_HANDLER', 'gdbm');
24 if (function_exists('variable_get')) {
25 $files_path = variable_get('sna_data_path', FILES_PATH);
26 $pic_size = variable_get('sna_pic_size', 300);
27 }
28 else {
29 $files_path = FILES_PATH;
30 $pic_size = 300;
31 }
32
33 /**
34 * Here store the whole graph. Should be inaccessible for www user
35 */
36 define('DATA_PATH', $files_path . 'ser.dat');
37 //define('DATA_PATH', './ser.dat');
38 /**
39 * The Graphviz file's path
40 */
41 define('DOT_PATH', $files_path . 'my.dot');
42 /**
43 * The Pajek file's path
44 */
45 define('NET_PATH', $files_path . 'my.net');
46 /**
47 * The minimal tree of shortest route - cache
48 */
49 define('CACHE_PATH', $files_path . 'min_trees');
50
51 /**
52 * Possible options: nodes, buddy, stats
53 */
54 define('GRAPH_SOURCE', 'nodes');
55 /**
56 * At cron-time the script generate the top NUM_CACHE users minimal tree
57 */
58 define('NUM_CACHE', '10');
59 /**
60 * SVG picture width
61 */
62 define('PIC_WIDTH', $pic_size);
63 /**
64 * SVG picture height - same as width, we need 1:1 side proportion!
65 */
66 define('PIC_HEIGHT', PIC_WIDTH);
67 /**
68 * Performace tester helper function. Start a timer and measure the current memory usage
69 *
70 * @return array Startup measured time and memory usage
71 */
72 function res_start() {
73 static $timer_index;
74 $mem_start = function_exists("memory_get_usage") ? memory_get_usage() : 0;
75 timer_start($timer_index);
76 return array(&$timer_index, $mem_start);
77 }
78
79 /**
80 * Performace tester helper function. Compute the diff between res_start's figures.
81 *
82 * @param array $at_start Startup measured time and memory usage
83 */
84 function res_stop($at_start) {
85 $res["time"] = timer_read($at_start[0]) / 1000 . " sec";
86 $res["mem"] = function_exists("memory_get_usage") ? (memory_get_usage() - $at_start[1]) / 1024 . " kB" : "NaN";
87 timer_stop($at_start[0]++);
88 return $res;
89 }
90
91 /**
92 * Lock the data file to avoid data corruption
93 *
94 * @param file_pointer $file_p
95 * @return boolean success or not
96 */
97 function lock($file_p) {
98 while (!flock($file_p, LOCK_EX)) {
99 $i++;
100 usleep(10);
101 if ($i > 10) {
102 return FALSE;
103 }
104 }
105 return TRUE;
106 }
107
108 /**
109 * Get the nickname of a user
110 *
111 * @param user_id $uid Drupal uid of the user
112 * @return nickname The uid's drupal nickname
113 */
114 function get_real_name($uid) {
115 $name_q = "SELECT name FROM users WHERE uid = %d";
116 $name = db_query($name_q, $uid);
117 $line = db_fetch_array($name);
118 return $line["name"];
119 }
120
121 /**
122 * Get from the database all the users' uid
123 *
124 * @return array All the users uid
125 */
126 function get_all_vertices() {
127 $vertices_q = "SELECT uid FROM users WHERE status = 1";
128 $vertices = db_query($vertices_q);
129 while ($line = db_fetch_array($vertices)) {
130 $users[] = $line['uid'];
131 }
132 return $users;
133 }
134
135 /**
136 * Get from the database all the users' uid and name to and assoc array
137 *
138 * @return array All the users uid and name
139 */
140 function get_all_vertices_for_forms() {
141 $vertices_q = "SELECT uid, name FROM users WHERE status = 1";
142 $vertices = db_query($vertices_q);
143 while ($line = db_fetch_array($vertices)) {
144 $users[$line['uid']] = $line['name'];
145 }
146 return $users;
147 }
148
149 /**
150 * Return the number of out-edges
151 *
152 * @param array $edges The adjacentcy list of the graph
153 * @param integer $vertex The vertex's id
154 * @return integer The number of out-edges
155 */
156 function vertex_degree($edges, $vertex) {
157 return count($edges[$vertex]);
158 }
159
160 /**
161 * Check if the minimal tree of <var>$vertex</var> is in cache or not
162 *
163 * @param integer $vertex The vertex's id
164 * @return boolean In cache or not
165 */
166 function is_in_cache($vertex) {
167 if (!$db = dba_open(CACHE_PATH, "c", DBA_HANDLER)) {
168 die("Cannot open database\n");
169 }
170 $data = dba_fetch($vertex, $db);
171 dba_close($db);
172 return $data === FALSE ? FALSE : unserialize($data);
173 }
174
175 /**
176 * Put the generated minimal tree to the cache
177 *
178 * @param integer $vertex The vertex's id
179 * @param array $data The minimal routes tree of $vertex
180 * @return boolean Success or not
181 */
182 function put_in_cache($vertex, $data) {
183 if (!$db = dba_open(CACHE_PATH, "c", DBA_HANDLER)) {
184 return FALSE;
185 }
186
187 if (!dba_insert($vertex, serialize($data), $db)) {
188 dba_close($db);
189 return FALSE;
190 }
191 dba_close($db);
192 return TRUE;
193 }
194
195 /**
196 * Find all the shortest routes from one vertex - Dijkstra algorithm
197 *
198 * @param array $edges The adjacentcy list of the graph
199 * @param integer $a The vertex's id
200 * @return array The minimal tree of routes
201 */
202 function a_to_any($edges, $a, $in_explore = false) {
203 if (!$in_explore) {
204 if ($data = is_in_cache($a)) {
205 return $data;
206 }
207 }
208
209 /* Set start values and load all the vertices in Q row */
210 $Q = array();
211 foreach ($edges as $key => $rel) {
212 $d[$key] = '-'; // Distance from $a
213 $p[$key] = '-';
214 $Q[] = $key;
215 foreach (array_keys($rel) as $child) {
216 $d[$child] = '-'; // Distance from $a
217 $p[$child] = '-';
218 $Q[] = $child;
219 }
220 }
221 /* The distance of start point is 0 */
222 $d[$a] = 0;
223 $Q[] = $a;
224 /* Delete duplicated elements */
225 $Q = array_unique($Q);
226
227 while (count($Q)) {
228 /* Search the minimal d in Q */
229 $u = reset($Q);
230 $min = $d[$u];
231 $min_key = key($Q);
232
233 foreach ($Q as $vk => $vertex) {
234 if (($min > $d[$vertex] || $min === '-') && is_numeric($d[$vertex])) {
235 $min = $d[$vertex];
236 $u = $vertex;
237 $min_key = $vk;
238 }
239 }
240 unset($Q[$min_key]);
241 /* Test the edges of $u vertex */
242 if (isset($edges[$u]) && $d[$u] !== '-') {
243 foreach (array_keys($edges[$u]) as $next) {
244 /* Test if get a shorter route - relaxation */
245 $w = $edges[$u][$next];
246 if ($d[$next] > $d[$u] + $w || $d[$next] === '-') {
247 $d[$next] = $d[$u] + $w;
248 $p[$next] = $u;
249 }
250 }
251 }
252 }
253 $out = array('dist' => $d, 'prev' => $p);
254 put_in_cache($a, $out);
255 return $out;
256 }
257
258 /**
259 * This is the graph's cost function
260 * In a weighted graph or digraph,
261 * each edge is associated with some value,
262 * variously called its cost, weight, length
263 *
264 * @param array $edges The adjacentcy list of the graph
265 * @param integer $a From verticle
266 * @param integer $b To verticle
267 * @return integer The weight of the edge or FALSE if the edge is not set
268 */
269 function get_edge_weight($edges, $a, $b, $min, $max) {
270 if (isset($edges[$a][$b])) {
271 /*
272 * The function is a line. This line contains two points
273 * x1 y1 x2 y2
274 * P1 (min, max_length) and P2 (max, min_length)
275 * min_length: 1 , max_length: 10
276 * The line's equation : y - y1 = (y2 - y1) / (x2 - x1) (x - x1)
277 * The result is a number between 1 and 10. 1 represents the
278 * strongest connection.
279 */
280 if ($max != $min) {
281 $y = (- 9 / ($max - $min) * ($edges[$a][$b] - $min)) + 10;
282 }
283 else { // Avoid division by zero!
284 $y = 1;
285 }
286 return $y;
287 }
288 else { // No edge from a to b
289 return FALSE;
290 }
291 }
292
293 /**
294 * Search the smallest and the biggest value in the <var>$edges</var> array that
295 * represents connection strength
296 *
297 * @param array $edges The adjacentcy list of the graph
298 * @return integer The length of the edge
299 */
300 function get_min_and_max_degree($edges) {
301 static $cached_arr;
302 $degrees = array();
303 if (is_array($cached_arr)) {
304 return $cached_arr;
305 }
306 else {
307 foreach ($edges as $neighbours) {
308 foreach ($neighbours as $degree) {
309 $degrees[] = $degree;
310 }
311 }
312 sort($degrees);
313 $cached_arr = array(reset($degrees), end($degrees));
314 return $cached_arr;
315 }
316 }
317
318 /**
319 * Sort the edges by the number of out-edges
320 *
321 * @param array $edges The adjacentcy list of the graph
322 * @param integer $limit Return the <var>$limit</var> - top of the users
323 * @return array The sorted vertices list
324 */
325 function sort_by_popularity($edges, $limit = -1) {
326 $popularity = array();
327 foreach (array_keys($edges) as $vertex) {
328 $popularity[] = array(vertex_degree($edges, $vertex), $vertex);
329 }
330 usort($popularity, "compare");
331 return $limit === -1 ? $popularity : array_slice($popularity, 0, $limit);
332 }
333
334 /**
335 * Special compare function to sort multi-dimensional array easily
336 *
337 * @param array $a
338 * @param array $b
339 * @return boolean $b is greater than $a
340 */
341 function compare($a, $b) {
342 if ($a[0] < $b[0]) {
343 return TRUE;
344 }
345 else {
346 return FALSE;
347 }
348 }
349
350 /**
351 * Clear the dbm file that store the cached minimal routes
352 *
353 */
354 function clear_cache() {
355 $db = dba_open(CACHE_PATH, "n", DBA_HANDLER);
356 dba_close($db);
357 }
358
359 ?>

  ViewVC Help
Powered by ViewVC 1.1.2