|
Graphviz
2.29.20120523.0446
|
00001 /* $Id$ $Revision$ */ 00002 /* vim:set shiftwidth=4 ts=8: */ 00003 00004 /************************************************************************* 00005 * Copyright (c) 2011 AT&T Intellectual Property 00006 * All rights reserved. This program and the accompanying materials 00007 * are made available under the terms of the Eclipse Public License v1.0 00008 * which accompanies this distribution, and is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * 00011 * Contributors: See CVS logs. Details at http://www.graphviz.org/ 00012 *************************************************************************/ 00013 00014 /* 00015 * this implements the resistor circuit current model for 00016 * computing node distance, as an alternative to shortest-path. 00017 * likely it could be improved by using edge weights, somehow. 00018 * Return 1 if successful; 0 otherwise (e.g., graph is disconnected). 00019 */ 00020 #include "neato.h" 00021 00022 int solveCircuit(int nG, double **Gm, double **Gm_inv) 00023 { 00024 double sum; 00025 int i, j; 00026 00027 if (Verbose) 00028 fprintf(stderr, "Calculating circuit model"); 00029 00030 /* set diagonal entries to sum of conductances but ignore nth node */ 00031 for (i = 0; i < nG; i++) { 00032 sum = 0.0; 00033 for (j = 0; j < nG; j++) 00034 if (i != j) 00035 sum += Gm[i][j]; 00036 Gm[i][i] = -sum; 00037 } 00038 return matinv(Gm, Gm_inv, nG - 1); 00039 } 00040 00041 int circuit_model(graph_t * g, int nG) 00042 { 00043 double **Gm; 00044 double **Gm_inv; 00045 int rv; 00046 long i, j; 00047 node_t *v; 00048 edge_t *e; 00049 00050 Gm = new_array(nG, nG, 0.0); 00051 Gm_inv = new_array(nG, nG, 0.0); 00052 00053 /* set non-diagonal entries */ 00054 for (v = agfstnode(g); v; v = agnxtnode(g, v)) { 00055 for (e = agfstedge(g, v); e; e = agnxtedge(g, e, v)) { 00056 i = AGSEQ(agtail(e)); 00057 j = AGSEQ(aghead(e)); 00058 if (i == j) 00059 continue; 00060 /* conductance is 1/resistance */ 00061 Gm[i][j] = Gm[j][i] = -1.0 / ED_dist(e); /* negate */ 00062 } 00063 } 00064 00065 rv = solveCircuit(nG, Gm, Gm_inv); 00066 00067 if (rv) 00068 for (i = 0; i < nG; i++) { 00069 for (j = 0; j < nG; j++) { 00070 GD_dist(g)[i][j] = 00071 Gm_inv[i][i] + Gm_inv[j][j] - 2.0 * Gm_inv[i][j]; 00072 } 00073 } 00074 free_array(Gm); 00075 free_array(Gm_inv); 00076 return rv; 00077 }
1.7.5