circuit.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /*************************************************************************
  2. * Copyright (c) 2011 AT&T Intellectual Property
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * https://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors: Details at https://graphviz.org
  9. *************************************************************************/
  10. /*
  11. * this implements the resistor circuit current model for
  12. * computing node distance, as an alternative to shortest-path.
  13. * likely it could be improved by using edge weights, somehow.
  14. * Return 1 if successful; 0 otherwise (e.g., graph is disconnected).
  15. */
  16. #include <neatogen/neato.h>
  17. int solveCircuit(int nG, double **Gm, double **Gm_inv)
  18. {
  19. double sum;
  20. int i, j;
  21. if (Verbose)
  22. fprintf(stderr, "Calculating circuit model");
  23. /* set diagonal entries to sum of conductances but ignore nth node */
  24. for (i = 0; i < nG; i++) {
  25. sum = 0.0;
  26. for (j = 0; j < nG; j++)
  27. if (i != j)
  28. sum += Gm[i][j];
  29. Gm[i][i] = -sum;
  30. }
  31. return matinv(Gm, Gm_inv, nG - 1);
  32. }
  33. int circuit_model(graph_t * g, int nG)
  34. {
  35. double **Gm;
  36. double **Gm_inv;
  37. int rv;
  38. long i, j;
  39. node_t *v;
  40. edge_t *e;
  41. Gm = new_array(nG, nG, 0.0);
  42. Gm_inv = new_array(nG, nG, 0.0);
  43. /* set non-diagonal entries */
  44. for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
  45. for (e = agfstedge(g, v); e; e = agnxtedge(g, e, v)) {
  46. i = AGSEQ(agtail(e));
  47. j = AGSEQ(aghead(e));
  48. if (i == j)
  49. continue;
  50. /* conductance is 1/resistance */
  51. Gm[i][j] = Gm[j][i] = -1.0 / ED_dist(e); /* negate */
  52. }
  53. }
  54. rv = solveCircuit(nG, Gm, Gm_inv);
  55. if (rv)
  56. for (i = 0; i < nG; i++) {
  57. for (j = 0; j < nG; j++) {
  58. GD_dist(g)[i][j] =
  59. Gm_inv[i][i] + Gm_inv[j][j] - 2.0 * Gm_inv[i][j];
  60. }
  61. }
  62. free_array(Gm);
  63. free_array(Gm_inv);
  64. return rv;
  65. }