[Commit] nickle/examples apsp.5c,NONE,1.1 shortpaths.5c,NONE,1.1
Bart Massey
commit at keithp.com
Wed Jun 23 02:00:48 PDT 2004
Committed by: bart
Update of /local/src/CVS/nickle/examples
In directory home.keithp.com:/tmp/cvs-serv7423/examples
Added Files:
apsp.5c shortpaths.5c
Log Message:
Added rudimentary SVG output namespace.
Added example: Floyd-Warshall all-pairs shortest-path algorithm.
Added example: program illustrating both of above.
--- NEW FILE: apsp.5c ---
/*
* All-Pairs Shortest Path Computation
* using Floyd-Warshall O(n**3) method
* CLR 2nd ed p. 632
* Bart Massey 2004/06
*/
namespace APSP {
public typedef real distance;
public typedef struct {
distance dist;
int first_hop;
} shortest_path;
public shortest_path[*,*]
compute_paths(distance[*,*] adjacencies) {
int[*] ns = dims(adjacencies);
assert(dim(ns) == 2 && ns[0] == ns[1],
"ill-conditioned adjacencies");
int n = ns[0];
/* set things up */
shortest_path[n,n] path =
{{{dist = -1, first_hop = -1}, ...},...};
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
path[i,j].dist = adjacencies[i,j];
if (i != j && adjacencies[i,j] >= 0)
path[i,j].first_hop = j;
}
}
/* do the computation */
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i == j)
continue;
real dik = path[i,k].dist;
real dkj = path[k,j].dist;
if (dik <= 0 || dkj <= 0)
continue;
real dij = path[i,j].dist;
if (dij <= 0 || dik + dkj < dij) {
path[i,j].dist = dik + dkj;
path[i,j].first_hop = path[i,k].first_hop;
}
}
}
}
return path;
}
}
--- NEW FILE: shortpaths.5c ---
autoimport APSP;
autoimport PRNG;
autoload SVG;
dev_srandom(32);
typedef struct {
int x, y;
} point;
int side = 500;
int blot = 10;
SVG::start(stdout, side, side);
point[10] locns = { [i] = (point){x = randint(side), y = randint(side)} };
for (int i = 0; i < dim(locns); i++)
SVG::spot(stdout, "red", locns[i].x, locns[i].y, blot);
real dist(point p1, point p2) {
return sqrt((p2.x - p1.x) ** 2 +
(p2.y - p1.y) ** 2);
}
distance[dim(locns), dim(locns)] adj = {
[i, j] {
if (randint(2) == 1)
return dist(locns[i], locns[j]);
return -1;
}
};
for (int i = 0; i < dim(locns); i++) {
for (int j = 0; j < i; j++) {
adj[j,i] = adj[i,j];
if (adj[i,j] > 0)
SVG::segment(stdout, "red",
locns[i].x, locns[i].y,
locns[j].x, locns[j].y);
}
}
shortest_path[*,*] path = compute_paths(adj);
int i = randint(dim(locns));
SVG::spot(stdout, "green", locns[i].x, locns[i].y, blot);
for (int j = 0; j < dim(locns); j++) {
if (path[i,j].first_hop == -1)
continue;
SVG::spot(stdout, "blue", locns[j].x, locns[j].y, blot);
for (int k = i; k != j; k = path[k,j].first_hop) {
int m = path[k,j].first_hop;
SVG::segment(stdout, "blue",
locns[k].x, locns[k].y,
locns[m].x, locns[m].y);
}
}
SVG::stop(stdout);
More information about the Commit
mailing list