Graphviz 16.0.1~dev.20260815.2250
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 zabs(size_t a, size_t b) {
24 if (a > b)
25 return a - b;
26 return b - a;
27}
28
29static size_t get_local_12_norm(size_t n, size_t i, const int *ia,
30 const int *ja, const size_t *p) {
31 size_t norm = n;
32 for (int j = ia[i]; j < ia[i+1]; j++){
33 if (ja[j] >= 0 && (size_t)ja[j] == i) continue;
34 norm = zmin(norm, zabs(p[i], p[ja[j]]));
35 }
36 return norm;
37}
38
39static void get_12_norm(size_t n, const int *ia, const int *ja, const size_t *p,
40 size_t *norm) {
41 /* norm[0] := antibandwidth
42 norm[1] := (\sum_{i\in V} (Min_{{j,i}\in E} |p[i] - p[j]|)/|V|
43 */
44 norm[0] = n; norm[1] = 0;
45 for (size_t i = 0; i < n; i++){
46 size_t tmp = n;
47 for (int j = ia[i]; j < ia[i+1]; j++){
48 if (ja[j] >= 0 && (size_t)ja[j] == i) continue;
49 norm[0] = zmin(norm[0], zabs(p[i], p[ja[j]]));
50 tmp = zmin(tmp, zabs(p[i], p[ja[j]]));
51 }
52 norm[1] += tmp;
53 }
54 norm[1] /= n;
55}
56
58 int cnt = 1, *ia = A->ia, *ja = A->ja;
59 const size_t n = A->m;
60 size_t norm1[2];
61 clock_t start = clock();
62 FILE *fp = NULL;
63
64 if (Verbose){
65 fprintf(stderr,"saving timing vs antiband data to timing_greedy\n");
66 fp = fopen("timing_greedy","w");
67 }
68 assert(SparseMatrix_is_symmetric(A, true));
69 for (bool improved = true; improved; ) {
70 improved = false;
71 for (size_t i = 0; i < n; i++) {
72 norm1[0] = get_local_12_norm(n, i, ia, ja, p);
73 for (size_t j = 0; j < n; j++) {
74 if (j == i) continue;
75 const size_t norm2 = get_local_12_norm(n, j, ia, ja, p);
76 const size_t pi = p[i];
77 const size_t pj = p[j];
78 p[i] = pj;
79 p[j] = pi;
80 const size_t norm11 = get_local_12_norm(n, i, ia, ja, p);
81 const size_t norm22 = get_local_12_norm(n, j, ia, ja, p);
82 if (zmin(norm11, norm22) > zmin(norm1[0], norm2)){
83 improved = true;
84 norm1[0] = norm11;
85 continue;
86 }
87 p[i] = pi;
88 p[j] = pj;
89 }
90 if (i%100 == 0 && Verbose) {
91 get_12_norm(n, ia, ja, p, norm1);
92 fprintf(fp, "%f %" PRISIZE_T " %" PRISIZE_T "\n", (double)(clock() - start) / CLOCKS_PER_SEC,
93 norm1[0], norm1[1]);
94 }
95 }
96 if (Verbose) {
97 get_12_norm(n, ia, ja, p, norm1);
98 fprintf(stderr, "[%d] aband = %" PRISIZE_T ", aband_avg = %" PRISIZE_T "\n", cnt++, norm1[0], norm1[1]);
99 fprintf(fp,"%f %" PRISIZE_T " %" PRISIZE_T "\n", (double)(clock() - start) / CLOCKS_PER_SEC,
100 norm1[0], norm1[1]);
101 }
102 }
103 if (fp != NULL) {
104 fclose(fp);
105 }
106}
107
109 const size_t n = A->m;
110
111 clock_t start = clock();
112 assert(A->m == (size_t)A->n);
114 const int *const ia = A2->ia;
115 const int *const ja = A2->ja;
116
117 /* Laplacian */
119 for (size_t i = 0; i < n; i++){
120 double nrow = 0.;
121 for (int j = ia[i]; j < ia[i+1]; j++){
122 const int jj = ja[j];
123 if (jj != (int)i){
124 nrow ++;
125 L = SparseMatrix_coordinate_form_add_entry(L, (int)i, jj, &(double){-1});
126 }
127 }
128 L = SparseMatrix_coordinate_form_add_entry(L, (int)i, (int)i, &nrow);
129 }
130 {
133 L = new;
134 }
135
136 /* largest eigen vector */
137 double *v = power_method(L, L->n, seed);
138
139 size_t *const p = vector_ordering(n, v);
140 free(v);
141 if (Verbose)
142 fprintf(stderr, "cpu time for spectral ordering (before greedy) = %f\n",
143 ((double)(clock() - start)) / CLOCKS_PER_SEC);
144
145 clock_t start2 = clock();
146 /* swapping */
148 if (Verbose) {
149 fprintf(stderr, "cpu time for greedy refinement = %f\n",
150 ((double)(clock() - start2)) / CLOCKS_PER_SEC);
151
152 fprintf(stderr, "cpu time for spectral + greedy = %f\n",
153 ((double)(clock() - start)) / CLOCKS_PER_SEC);
154
155 }
156
157 if (A2 != A) SparseMatrix_delete(A2);
159 return p;
160}
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)
@ MATRIX_TYPE_REAL
@ FORMAT_COORD
#define SparseMatrix_coordinate_form_add_entry(A, irn, jcn, val)
wrap SparseMatrix_coordinate_form_add_entry_ for type safety
static size_t get_local_12_norm(size_t n, size_t i, const int *ia, const int *ja, const size_t *p)
void improve_antibandwidth_by_swapping(SparseMatrix A, size_t *p)
static size_t zabs(size_t a, size_t b)
size_t * country_graph_coloring(int seed, SparseMatrix A)
static void get_12_norm(size_t n, const int *ia, const int *ja, const size_t *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
size_t * vector_ordering(size_t n, double *v)
Definition general.c:84
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:204
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