void fisheryates_shuffle(term *terms, int n_terms) {
int i;
for (i=n_terms-1; i>=1; i--) {
- int j = (int)(drand48() * (i+1)); // TODO: better rng?
+ // srand48() is called in neatoinit.c, so no need to seed here
+ int j = (int)(drand48() * (i+1));
term temp = terms[i];
terms[i] = terms[j];
}
// single source shortest paths that also builds terms as it goes
// mostly copied from from stuff.c
-void dijkstra_single_source(graph_t *G, node_t *source, term *terms, int *offset) {
+// returns the number of terms built
+int dijkstra_single_source(graph_t *G, node_t *source, term *terms) {
int t;
node_t *v, *u;
for (t = 0; (v = GD_neato_nlist(G)[t]); t++) {
}
ND_dist(source) = 0;
- ND_hops(source) = 0;
neato_enqueue(G, source);
edge_t *e;
+ int offset = 0;
while ((v = neato_dequeue(G))) {
// if the target is fixed then always create a term as shortest paths are not calculated from there
// if not fixed then only create a term if the target index is lower
if (isFixed(v) || ND_id(v)<ND_id(source)) {
- terms[*offset].i = source;
- terms[*offset].j = v;
- terms[*offset].d = ND_dist(v);
- terms[*offset].w = 1 / (terms[*offset].d*terms[*offset].d);
- (*offset)++;
+ terms[offset].i = source;
+ terms[offset].j = v;
+ terms[offset].d = ND_dist(v);
+ terms[offset].w = 1 / (terms[offset].d*terms[offset].d);
+ offset++;
}
for (e = agfstedge(G, v); e; e = agnxtedge(G, e, v)) {
if ((u = agtail(e)) == v)
if (ND_heapindex(u) >= 0) {
heapup(G, u);
} else {
- ND_hops(u) = ND_hops(v) + 1;
neato_enqueue(G, u);
}
}
}
}
+ return offset;
}
void sgd(graph_t *G, /* input graph */
// calculate term values through shortest paths
int offset = 0;
- GD_heap(G) = N_NEW(n + 1, node_t *);
+ GD_heap(G) = N_NEW(n, node_t *);
GD_heapsize(G) = 0;
if (Verbose) {
fprintf(stderr, "calculating shortest paths:");
}
for (i=0; i<n; i++) {
node_t *source = GD_neato_nlist(G)[i];
- if (!isFixed(source))
- dijkstra_single_source(G, source, terms, &offset);
+ if (!isFixed(source)) {
+ offset += dijkstra_single_source(G, source, terms+offset);
+ }
}
free(GD_heap(G));
assert(offset == n_terms);
initial_positions(G, n);
// perform optimisation
- int t;
if (Verbose) {
fprintf(stderr, "solving model:");
start_timer();
}
+ int t;
for (t=0; t<MaxIter; t++) {
fisheryates_shuffle(terms, n_terms);
float eta = eta_max * exp(-lambda * t);