Graphviz 15.1.1~dev.20260630.1303
Loading...
Searching...
No Matches
country_graph_coloring.c
Go to the documentation of this file.
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 v2.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include "config.h"
12
13#define STANDALONE
15#include <math.h>
16#include "power.h"
17#include <stdbool.h>
18#include <stdlib.h>
19#include <time.h>
20#include <util/gv_math.h>
21#include <util/prisize_t.h>
22
23static size_t get_local_12_norm(size_t n, size_t i, const int *ia,
24 const int *ja, const int *p) {
25 size_t norm = n;
26 for (int j = ia[i]; j < ia[i+1]; j++){
27 if (ja[j] >= 0 && (size_t)ja[j] == i) continue;
28 norm = zmin(norm, (size_t)abs(p[i] - p[ja[j]]));
29 }
30 return norm;
31}
32
33static void get_12_norm(size_t n, const int *ia, const int *ja, int *p,
34 size_t *norm) {
35 /* norm[0] := antibandwidth
36 norm[1] := (\sum_{i\in V} (Min_{{j,i}\in E} |p[i] - p[j]|)/|V|
37 */
38 norm[0] = n; norm[1] = 0;
39 for (size_t i = 0; i < n; i++){
40 size_t tmp = n;
41 for (int j = ia[i]; j < ia[i+1]; j++){
42 if (ja[j] >= 0 && (size_t)ja[j] == i) continue;
43 norm[0] = zmin(norm[0], (size_t)abs(p[i] - p[ja[j]]));
44 tmp = zmin(tmp, (size_t)abs(p[i] - p[ja[j]]));
45 }
46 norm[1] += tmp;
47 }
48 norm[1] /= n;
49}
50
52 int cnt = 1, *ia = A->ia, *ja = A->ja;
53 const size_t n = A->m;
54 size_t norm1[2];
55 clock_t start = clock();
56 FILE *fp = NULL;
57
58 if (Verbose){
59 fprintf(stderr,"saving timing vs antiband data to timing_greedy\n");
60 fp = fopen("timing_greedy","w");
61 }
62 assert(SparseMatrix_is_symmetric(A, true));
63 for (bool improved = true; improved; ) {
64 improved = false;
65 for (size_t i = 0; i < n; i++) {
66 norm1[0] = get_local_12_norm(n, i, ia, ja, p);
67 for (size_t j = 0; j < n; j++) {
68 if (j == i) continue;
69 const size_t norm2 = get_local_12_norm(n, j, ia, ja, p);
70 const int pi = p[i];
71 const int pj = p[j];
72 p[i] = pj;
73 p[j] = pi;
74 const size_t norm11 = get_local_12_norm(n, i, ia, ja, p);
75 const size_t norm22 = get_local_12_norm(n, j, ia, ja, p);
76 if (zmin(norm11, norm22) > zmin(norm1[0], norm2)){
77 improved = true;
78 norm1[0] = norm11;
79 continue;
80 }
81 p[i] = pi;
82 p[j] = pj;
83 }
84 if (i%100 == 0 && Verbose) {
85 get_12_norm(n, ia, ja, p, norm1);
86 fprintf(fp, "%f %" PRISIZE_T " %" PRISIZE_T "\n", (double)(clock() - start) / CLOCKS_PER_SEC,
87 norm1[0], norm1[1]);
88 }
89 }
90 if (Verbose) {
91 get_12_norm(n, ia, ja, p, norm1);
92 fprintf(stderr, "[%d] aband = %" PRISIZE_T ", aband_avg = %" PRISIZE_T "\n", cnt++, norm1[0], norm1[1]);
93 fprintf(fp,"%f %" PRISIZE_T " %" PRISIZE_T "\n", (double)(clock() - start) / CLOCKS_PER_SEC,
94 norm1[0], norm1[1]);
95 }
96 }
97 if (fp != NULL) {
98 fclose(fp);
99 }
100}
101
103 const size_t n = A->m;
104
105 clock_t start = clock();
106 assert(A->m == (size_t)A->n);
108 const int *const ia = A2->ia;
109 const int *const ja = A2->ja;
110
111 /* Laplacian */
113 for (size_t i = 0; i < n; i++){
114 double nrow = 0.;
115 for (int j = ia[i]; j < ia[i+1]; j++){
116 const int jj = ja[j];
117 if (jj != (int)i){
118 nrow ++;
119 L = SparseMatrix_coordinate_form_add_entry(L, (int)i, jj, &(double){-1});
120 }
121 }
122 L = SparseMatrix_coordinate_form_add_entry(L, (int)i, (int)i, &nrow);
123 }
124 {
127 L = new;
128 }
129
130 /* largest eigen vector */
131 double *v = power_method(L, L->n, seed);
132
133 vector_ordering(n, v, p);
134 free(v);
135 if (Verbose)
136 fprintf(stderr, "cpu time for spectral ordering (before greedy) = %f\n",
137 ((double)(clock() - start)) / CLOCKS_PER_SEC);
138
139 clock_t start2 = clock();
140 /* swapping */
142 if (Verbose) {
143 fprintf(stderr, "cpu time for greedy refinement = %f\n",
144 ((double)(clock() - start2)) / CLOCKS_PER_SEC);
145
146 fprintf(stderr, "cpu time for spectral + greedy = %f\n",
147 ((double)(clock() - start)) / CLOCKS_PER_SEC);
148
149 }
150
151 if (A2 != A) SparseMatrix_delete(A2);
153}
SparseMatrix SparseMatrix_new(size_t m, int n, size_t nz, int type, int format)
SparseMatrix SparseMatrix_from_coordinate_format(SparseMatrix A)
SparseMatrix SparseMatrix_symmetrize(SparseMatrix A, bool pattern_symmetric_only)
bool SparseMatrix_is_symmetric(SparseMatrix A, bool test_pattern_symmetry_only)
void SparseMatrix_delete(SparseMatrix A)
@ FORMAT_COORD
#define SparseMatrix_coordinate_form_add_entry(A, irn, jcn, val)
wrap SparseMatrix_coordinate_form_add_entry_ for type safety
@ MATRIX_TYPE_REAL
void country_graph_coloring(int seed, SparseMatrix A, int **p)
static size_t get_local_12_norm(size_t n, size_t i, const int *ia, const int *ja, const int *p)
void improve_antibandwidth_by_swapping(SparseMatrix A, int *p)
static void get_12_norm(size_t n, const int *ia, const int *ja, int *p, size_t *norm)
static double norm(int n, const double *x)
static long seed
Definition exeval.c:1010
#define A(n, t)
Definition expr.h:76
void vector_ordering(size_t n, double *v, int **p)
Definition general.c:88
static bool Verbose
Definition gml2gv.c:26
static attrs_t * L
Definition gmlparse.c:94
void free(void *)
node NULL
Definition grammar.y:181
static int cnt(Dict_t *d, Dtlink_t **set)
Definition graph.c:200
Arithmetic helper functions.
static size_t zmin(size_t a, size_t b)
minimum of two sizes
Definition gv_math.h:32
double * power_method(void *A, int n, int random_seed)
Definition power.c:23
#define PRISIZE_T
Definition prisize_t.h:25