Commit 4fa88f91 authored by Christopher Alfeld's avatar Christopher Alfeld

Added the features and desires code.

Added a basic README

Added two tests for features/desires.
parent 60b27581
running
-------
Typically assign is run in the following method:
assign -b -t <ptop> <top>
-h provides a brief help listing. -a does nothing. -b prevents the
GUI. -t specifies a ptop file. -o does very little of use.
ptop format
-----------
Each line is one either:
node <node> <types> [- <features>]
<node> is a string identifier for the node.
<types> is a space separated list of <type>:<number>.
<type> is a string identifier for the type.
<number> is the number of virtual nodes of that type that can fit.
There is a special type of "switch" which indicates that the node is a
switch.
<features> is a space separated list of <feature>:<cost>
<feature> is a string identifier of the feature.
<cost> is the cost of the feature being wasted.
OR
link <link> <src>[:<smac>] <dst>[:<dmac>] <bw> <numb>
<link> is a string identifier for the link.
<src>,<dst> are the source and destination nodes.
<smac>,<dmac> are optional arguments which are the MAC addresses or any
other string to distinguish the ports of the nodes. If committed
the string "(null)" is used instead.
<bw> is the bandwidth, an integer.
<num> is the number of links between those two pairs.
Note: <smac> and <dmac> should not be present on switch<->switch links.
top format
----------
Each line is either:
node <node> <type> [<desires>]
<node> is a string identifier for the node.
<type> is the type of the node.
<desires> is a space separated list of <desire>:<weight>
<desire> is a string identifier of the desire.
<weight> is the cost of not having the desire fulfilled.
A weight >= 1.0 will also result in a violation if
not filled.
features and desires
--------------------
Each physical node has feature/cost pairs associated with it. Each
virtual node has desire/weight pairs associated with it. When a
mapping is made any unused features add their cost to the score and
any unfulfilled desires add their weight to the score. Fulfilled
desires/used features add nothing to the score.
compile type options
--------------------
-DVERBOSE adds temperature output and functions as a crude progress meter.
-DSCORE_DEBUG adds a large amount of output detailing in great detail
what is going on.
-DSCORE_DEBUG_MORE adds even more output.
......@@ -4,6 +4,7 @@
#include <LEDA/map.h>
#include <LEDA/graph_iterator.h>
#include <LEDA/node_pq.h>
#include <LEDA/sortseq.h>
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
......@@ -278,6 +279,7 @@ int assign()
cout << " no_connect: " << vinfo.no_connection << endl;
cout << " link_users: " << vinfo.link_users << endl;
cout << " bandwidth: " << vinfo.bandwidth << endl;
cout << " desires: " << vinfo.desires << endl;
return 0;
}
......
node S switch
node n1 pc:1 - abone:0.05
node n2 pc:1 - abone:0.05
node n3 pc:1 - abone:0.05
node n4 pc:1 - abone:0.05
node n5 pc:1 - abone:0.05
node m1 pc:1 - special:0.2
node m2 pc:1
node m3 pc:1
node m4 pc:1
node m5 pc:1
link l1 n1 S 100 4
link l2 n2 S 100 4
link l3 n3 S 100 4
link l4 n4 S 100 4
link l5 n5 S 100 4
link k1 m1 S 100 4
link k2 m2 S 100 4
link k3 m3 S 100 4
link k4 m4 S 100 4
link k5 m5 S 100 4
node A pc special:0.5
node B pc
node C pc
link l1 A B 100
link l2 A C 100
link l3 B C 100
......@@ -15,6 +15,7 @@
#include <LEDA/dictionary.h>
#include <LEDA/map.h>
#include <LEDA/graph_iterator.h>
#include <LEDA/sortseq.h>
#include <iostream.h>
#include <string.h>
#include <stdio.h>
......@@ -67,7 +68,8 @@ int parse_ptop(tb_pgraph &PG, istream& i)
PG[no1].max_load = 0;
PG[no1].current_load = 0;
PG[no1].pnodes_used=0;
while ((scur = strsep(&snext," ")) != NULL) {
while ((scur = strsep(&snext," ")) != NULL &&
(strcmp(scur,"-"))) {
char *t,*load=scur;
int iload;
t = strsep(&load,":");
......@@ -89,6 +91,20 @@ int parse_ptop(tb_pgraph &PG, istream& i)
PG[no1].types.insert(stype,iload);
}
}
/* Either end of line or - . Read in features */
while ((scur = strsep(&snext," ")) != NULL) {
char *feature=scur;
double icost;
char *t;
t = strsep(&feature,":");
string sfeat(t);
if ((! feature) || sscanf(feature,"%lg",&icost) != 1) {
fprintf(stderr,"Bad cost specifier for %s\n",t);
icost = 0.01;
}
PG[no1].features.insert(sfeat,icost);
}
/* Done */
if (! isswitch)
pnodes[n++]=no1;
nmap.insert(s, no1);
......
......@@ -11,6 +11,7 @@
#include <LEDA/map.h>
#include <LEDA/graph_iterator.h>
#include <LEDA/node_pq.h>
#include <LEDA/sortseq.h>
#include "common.h"
#include "virtual.h"
......@@ -25,7 +26,7 @@ int parse_top(tb_vgraph &G, istream& i)
node no1;
string s1, s2;
char inbuf[255];
char n1[32], n2[32], type[32];
char n1[32], n2[32];
char lname[32];
int num_nodes = 0;
int bw;
......@@ -39,18 +40,35 @@ int parse_top(tb_vgraph &G, istream& i)
if (strlen(inbuf) == 0) { continue; }
if (!strncmp(inbuf, "node", 4)) {
if (sscanf(inbuf, "node %s %s", n1, type) < 1) {
char *snext = inbuf;
char *scur = strsep(&snext," ");
if (strcmp("node",scur) != 0) {
fprintf(stderr, "bad node line: %s\n", inbuf);
} else {
scur=strsep(&snext," ");
num_nodes++;
string s1(n1);
string s1(scur);
no1 = G.new_node();
unassigned_nodes.insert(no1,random());
G[no1].name=strdup(n1);
G[no1].name=strdup(scur);
G[no1].posistion = 0;
G[no1].no_connections=0;
nmap.insert(s1, no1);
G[no1].type=string(type);
scur=strsep(&snext," ");
G[no1].type=string(scur);
/* Read in desires */
while ((scur=strsep(&snext," ")) != NULL) {
char *desire = scur;
char *t;
double iweight;
t = strsep(&desire,":");
string sdesire(t);
if ((! desire) || sscanf(desire,"%lg",&iweight) != 1) {
fprintf(stderr,"Bad desire specifier for %s\n",t);
iweight = 0.01;
}
G[no1].desires.insert(sdesire,iweight);
}
}
} else if (!strncmp(inbuf, "link", 4)) {
r=sscanf(inbuf, "link %s %s %s %d", lname, n1, n2,&bw);
......
......@@ -16,6 +16,7 @@ public:
}
dictionary<string,int> types; // contains max nodes for each type
sortseq<string,double> features; // contains cost of each feature
string current_type;
bool typed; // has it been typed
int max_load; // maxmium load for current type
......@@ -36,7 +37,7 @@ public:
friend istream & operator>>(istream &i, const tb_plink& edge)
{
return i;
}
}
int bandwidth; // maximum bandwidth of this link
int bw_used; // how much is used
int users; // number of users in direct links
......
......@@ -14,6 +14,7 @@
#include <LEDA/dictionary.h>
#include <LEDA/map.h>
#include <LEDA/graph_iterator.h>
#include <LEDA/sortseq.h>
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
......@@ -234,6 +235,48 @@ void remove_node(node n)
SADD(SCORE_UNASSIGNED);
vinfo.unassigned++;
violated++;
// features/desires
seq_item desire;
seq_item feature;
double value;
for (desire = vnoder.desires.min_item();desire;
desire = vnoder.desires.succ(desire)) {
feature = pnoder.features.lookup(vnoder.desires.key(desire));
#ifdef SCORE_DEBUG
cerr << " desire = " << vnoder.desires.key(desire) \
<< " " << vnoder.desires.inf(desire) << "\n";
#endif
if (!feature) {
// Unmatched desire. Remove cost.
#ifdef SCORE_DEBUG
cerr << " unmatched\n";
#endif
value = vnoder.desires.inf(desire);
SSUB(SCORE_DESIRE*value);
if (value >= 1) {
violated--;
vinfo.desires--;
}
}
}
for (feature = pnoder.features.min_item();feature;
feature = pnoder.features.succ(feature)) {
desire = vnoder.desires.lookup(pnoder.features.key(feature));
#ifdef SCORE_DEBUG
cerr << " feature = " << pnoder.features.key(feature) \
<< " " << pnoder.features.inf(feature) << "\n";
#endif
if (! desire) {
// Unused feature. Remove weight
#ifdef SCORE_DEBUG
cerr << " unused\n";
#endif
value = pnoder.features.inf(feature);
SSUB(SCORE_FEATURE*value);
}
}
#ifdef SCORE_DEBUG
fprintf(stderr," new score = %.2f new violated = %d\n",score,violated);
#endif
......@@ -463,6 +506,47 @@ int add_node(node n,int ploc)
vinfo.unassigned--;
violated--;
// features/desires
seq_item desire;
seq_item feature;
double value;
for (desire = vnoder.desires.min_item();desire;
desire = vnoder.desires.succ(desire)) {
feature = pnoder.features.lookup(vnoder.desires.key(desire));
#ifdef SCORE_DEBUG
cerr << " desire = " << vnoder.desires.key(desire) \
<< " " << vnoder.desires.inf(desire) << "\n";
#endif
if (!feature) {
// Unmatched desire. Add cost.
#ifdef SCORE_DEBUG
cerr << " unmatched\n";
#endif
value = vnoder.desires.inf(desire);
SADD(SCORE_DESIRE*value);
if (value >= 1) {
violated++;
vinfo.desires++;
}
}
}
for (feature = pnoder.features.min_item();feature;
feature = pnoder.features.succ(feature)) {
desire = vnoder.desires.lookup(pnoder.features.key(feature));
#ifdef SCORE_DEBUG
cerr << " feature = " << pnoder.features.key(feature) \
<< " " << pnoder.features.inf(feature) << "\n";
#endif
if (! desire) {
// Unused feature. Add weight
#ifdef SCORE_DEBUG
cerr << " unused\n";
#endif
value = pnoder.features.inf(feature);
SADD(SCORE_FEATURE*value);
}
}
#ifdef SCORE_DEBUG
fprintf(stderr," posistion = %d\n",vnoder.posistion);
fprintf(stderr," new score = %.2f new violated = %d\n",score,violated);
......
......@@ -30,12 +30,19 @@ const float SCORE_UNASSIGNED = 1;
// Cost of going over bandwidth
const float SCORE_OVER_BANDWIDTH = 0.5;
// Multiplier for desire costs
const float SCORE_DESIRE = 1;
// Multiplier for feature weights
const float SCORE_FEATURE = 1;
typedef struct {
int unassigned;
int pnode_load;
int no_connection;
int link_users;
int bandwidth;
int desires;
} violated_info;
extern float score;
......
......@@ -15,6 +15,7 @@ public:
return i;
}
sortseq<string,double> desires; // contains weight of each desire
int posistion; // index into pnode array
int no_connections; // how many unfulfilled connections from this node
string type;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment