Now let's make the node and edge data more sopihisticated. We use as our void * node and edge data the following abstract data types:
struct NodeStruct{
int load;
float time;
Vertex V;
};
struct EdgeStruct{
float capacity;
float loss;
float time;
Vertex V;
};
For convenience, these are entered as gloabl data via the top of the file run.c. Thes data types require the following access functions:
int EdgeStruct_equal(EdgeStruct *a,EdgeStruct *b)
{
return( (a->capacity==b->capacity)
&&(a->loss==b->loss)
&&(a->time==b->time)
&&(a->V.x==b->V.x)
&&(a->V.y==b->V.y) );
}
int NodeStruct_equal(NodeStruct *a,NodeStruct *b)
{
return( (a->load==b->load)
&&(a->time==b->time)
&&(a->V.x==b->V.x)
&&(a->V.y==b->V.y) );
}
void EdgeStruct_entry(EdgeStruct **a,EdgeStruct *b)
{
*a = new EdgeStruct;
(*a)->capacity = b->capacity;
(*a)->loss = b->loss;
(*a)->time = b->time;
(*a)->V.x = b->V.x;
(*a)->V.y = b->V.y;
}
void NodeStruct_entry(NodeStruct **a,NodeStruct *b)
{
(*a) = new NodeStruct;
(*a)->load = b->load;
(*a)->time = b->time;
(*a)->V.x = b->V.x;
(*a)->V.y = b->V.y;
}
ostream& EdgeStruct_show(ostream& out, EdgeStruct *a)
{
out << "Capacity = " << a->capacity << endl;
out << "Loss = " << a->loss << endl;
out << "Vertex = (" << a->V.x << "," << a->V.y << ")" << endl;
return out;
}
ostream& NodeStruct_show(ostream& out, NodeStruct *a)
{
out << "Load = " << a->load << endl;
out << "Time = " << a->time << endl;
out << "Vertex = (" << a->V.x << "," << a->V.y << ")" << endl;
return out;
}
Note how similar in spirit these access functions are to the ones we already developed for the float * and double * data.
The code to initialize the edge and node data is also quite similar: the constructor now uses the new access methods:
T->T = new Graph(EQ_FN(EdgeStruct_equal),DISP_FN(EdgeStruct_show),
ENTRY_FN(EdgeStruct_entry),
EQ_FN(NodeStruct_equal),DISP_FN(NodeStruct_show),
ENTRY_FN(NodeStruct_entry),
T->radius,T->center, //node circle
T->foreground, //fg
T->background, //bg
graph_colors, //graph colors
T->display, //graphics
T->drawable,
T->pixmap,
T->pixmap2,
T->gc);
and the data initialization must deal with these structures:
EdgeStruct *edge_data = new EdgeStruct[NumberEdges];
NodeStruct *node_data = new NodeStruct[NumberNodes];
for(int i = 0;i< NumberNodes; ++i){
node_data[i].load = i;
node_data[i].time = float(i)*float(i);
node_data[i].V.x = i-1;
node_data[i].V.y = i+1;
}
for(int i = 0;i< NumberEdges; ++i){
edge_data[i].capacity = 10.0;
edge_data[i].loss = -i;
edge_data[i].time = float(i)*float(i);
edge_data[i].V.x =10*i-1;
edge_data[i].V.y =10*i+1;
}
T->T->FillData(node_data,sizeof(NodeStruct),edge_data,sizeof(EdgeStruct));
This code generates the following output for a simple graph; the node data now prints out the NodeStruct information for each node:
Graph:
Nodes:
n8 Load = 0
Time = 0
Vertex = (-1,1)
n7 Load = 1
Time = 1
Vertex = (0,2)
n6 Load = 2
Time = 4
Vertex = (1,3)
n5 Load = 3
Time = 9
Vertex = (2,4)
n4 Load = 4
Time = 16
Vertex = (3,5)
n3 Load = 5
Time = 25
Vertex = (4,6)
n2 Load = 6
Time = 36
Vertex = (5,7)
n1 Load = 7
Time = 49
Vertex = (6,8)
Also, the edge data now includes the EdgeStruct information too:
Edges: n2-----(0.513375)---> n1 Capacity = 10
Loss = 0
Vertex = (-1,1)
n3-----(0.941735)---> n7 Capacity = 10
Loss = -1
Vertex = (9,11)
n4-----(1.16603)---> n2 Capacity = 10
Loss = -2
Vertex = (19,21)
n5-----(2.03267)---> n6 Capacity = 10
Loss = -3
Vertex = (29,31)
n6-----(2.29448)---> n6 Capacity = 10
Loss = -4
Vertex = (39,41)
n7-----(2.36909)---> n1 Capacity = 10
Loss = -5
Vertex = (49,51)
n8-----(1.955)---> n4 Capacity = 10
Loss = -6
Vertex = (59,61)