--- /dev/null
+#include "adt/array.h"
+#include "assert.h"
+
+#include "pbqp_edge_t.h"
+#include "pbqp_node_t.h"
+#include "html_dumper.h"
+#include "kaps.h"
+#include "pbqp_t.h"
+
+/* print vector */
+static void dump_vector(FILE *f, vector *vec)
+{
+ unsigned index;
+ assert(vec);
+
+ fprintf(f, "<span class=\"vector\">( ");
+ unsigned len = vec->len;
+ assert(len> 0);
+ for (index = 0; index < len; ++index) {
+ fprintf(f, "%6d", vec->entries[index].data);
+ }
+ fprintf(f, " )</span>\n");
+}
+
+static void dump_matrix(FILE *f, pbqp_matrix *mat)
+{
+ unsigned row, col;
+ assert(mat);
+ num *p = mat->entries;
+
+ assert(mat->cols > 0);
+ assert(mat->rows > 0);
+ fprintf(f, "\t\\begin{pmatrix}\n");
+ for (row = 0; row < mat->rows; ++row) {
+ fprintf(f, "\t %6d", *p++);
+ for (col = 1; col < mat->cols; ++col) {
+ fprintf(f, "& %6d", *p++);
+ }
+ fprintf(f, "\\\\\n");
+ }
+ fprintf(f, "\t\\end{pmatrix}\n");
+}
+
+static void dump_edge_costs(pbqp *pbqp)
+{
+ unsigned src_index;
+
+ assert(pbqp);
+ assert(pbqp->dump_file);
+
+ fputs("<p>", pbqp->dump_file);
+ for (src_index = 0; src_index < pbqp->num_nodes; ++src_index) {
+ pbqp_node *src_node = get_node(pbqp, src_index);
+ unsigned edge_index;
+ unsigned len = ARR_LEN(src_node->edges);
+ for (edge_index = 0; edge_index < len; ++edge_index) {
+ pbqp_edge *edge = src_node->edges[edge_index];
+ unsigned tgt_index = edge->tgt;
+ if (src_index < tgt_index) {
+ fputs("<tex>\n", pbqp->dump_file);
+ fprintf(pbqp->dump_file, "\t\\overline\n{C}_{%d,%d}=\n",
+ src_index, tgt_index);
+ dump_matrix(pbqp->dump_file, edge->costs);
+ fputs("</tex><br>", pbqp->dump_file);
+ }
+ }
+ }
+ fputs("</p>", pbqp->dump_file);
+}
+
+static void dump_node_costs(pbqp *pbqp)
+{
+ unsigned index;
+
+ assert(pbqp);
+ assert(pbqp->dump_file);
+
+ /* dump node costs */
+ fputs("<p>", pbqp->dump_file);
+ for (index = 0; index < pbqp->num_nodes; ++index) {
+ pbqp_node *node = get_node(pbqp, index);
+ fprintf(pbqp->dump_file, "\tc<sub>%d</sub> = ", index);
+ dump_vector(pbqp->dump_file, node->costs);
+ fputs("<br>\n", pbqp->dump_file);
+ }
+ fputs("</p>", pbqp->dump_file);
+}
+
+static void dump_section(FILE *f, int level, char *txt)
+{
+ assert(f);
+
+ fprintf(f, "<h%d>%s</h%d>\n", level, txt, level);
+}
+
+void dump_graph(pbqp *pbqp)
+{
+ unsigned src_index;
+
+ assert(pbqp != NULL);
+ assert(pbqp->dump_file != NULL);
+
+ fputs("<p>\n<graph>\n\tgraph input {\n", pbqp->dump_file);
+ for (src_index = 0; src_index < pbqp->num_nodes; ++src_index) {
+ fprintf(pbqp->dump_file, "\t n%d;\n", src_index);
+ }
+
+ for (src_index = 0; src_index < pbqp->num_nodes; ++src_index) {
+ pbqp_node *node = get_node(pbqp, src_index);
+ unsigned len = ARR_LEN(node->edges);
+ unsigned edge_index;
+ for (edge_index = 0; edge_index < len; ++edge_index) {
+ unsigned tgt_index = node->edges[edge_index]->tgt;
+
+ if (src_index < tgt_index) {
+ fprintf(pbqp->dump_file, "\t n%d -- n%d;\n", src_index,
+ tgt_index);
+ }
+ }
+ }
+ fputs("\t}\n</graph>\n</p>\n", pbqp->dump_file);
+}
+
+void dump_input(pbqp *pbqp)
+{
+ assert(pbqp);
+ assert(pbqp->dump_file);
+
+ dump_section(pbqp->dump_file, 1, "1. PBQP Problem");
+ dump_section(pbqp->dump_file, 2, "1.1 Topology");
+ dump_graph(pbqp);
+ dump_section(pbqp->dump_file, 2, "1.2 Cost Vectors");
+ dump_node_costs(pbqp);
+ dump_section(pbqp->dump_file, 2, "1.3 Cost Matrices");
+ dump_edge_costs(pbqp);
+}
--- /dev/null
+#ifndef KAPS_HTML_DUMPER_H
+#define KAPS_HTML_DUMPER_H
+
+#include "pbqp_t.h"
+
+void dump_input(pbqp *pbqp);
+
+#endif /* KAPS_HTML_DUMPER_H */
#include "adt/array.h"
#include "kaps.h"
+#include "matrix.h"
+#include "pbqp_edge.h"
#include "pbqp_edge_t.h"
#include "pbqp_node.h"
#include "pbqp_node_t.h"
#include "vector.h"
-pbqp_node *get_node(pbqp *pbqp, int index)
+pbqp_node *get_node(pbqp *pbqp, unsigned index)
{
return pbqp->nodes[index];
}
-pbqp_edge *get_edge(pbqp *pbqp, int src_index, int tgt_index)
+pbqp_edge *get_edge(pbqp *pbqp, unsigned src_index, unsigned tgt_index)
{
int i;
int len;
- if (src_index < tgt_index) {
+ if (tgt_index < src_index) {
return get_edge(pbqp, tgt_index, src_index);
}
pbqp_node *src_node = get_node(pbqp, src_index);
assert(src_node);
- pbqp_node *tgt_node = get_node(pbqp, tgt_index);
- assert(tgt_node);
+ assert(get_node(pbqp, tgt_index));
len = ARR_LEN(src_node->edges);
for (i = 0; i < len; ++i) {
pbqp_edge *cur_edge = src_node->edges[i];
- if (cur_edge->tgt == tgt_node) {
+ if (cur_edge->tgt == tgt_index) {
return cur_edge;
}
}
return NULL;
}
-pbqp *alloc_pbqp(int number_nodes)
+pbqp *alloc_pbqp(unsigned number_nodes)
{
pbqp* pbqp = xmalloc(sizeof(*pbqp));
xfree(pbqp);
}
-void add_node_costs(pbqp *pbqp, int node_index, vector *costs)
+void add_node_costs(pbqp *pbqp, unsigned node_index, vector *costs)
{
pbqp_node *node = get_node(pbqp, node_index);
if (node == NULL) {
node = alloc_node(pbqp, costs);
+ pbqp->nodes[node_index] = node;
} else {
vector_add(node->costs, costs);
}
}
-void add_edge_costs(pbqp *pbqp, int src_index, int tgt_index, matrix *costs)
+void add_edge_costs(pbqp *pbqp, unsigned src_index, unsigned tgt_index,
+ pbqp_matrix *costs)
{
pbqp_edge *edge = get_edge(pbqp, src_index, tgt_index);
if (edge == NULL) {
edge = alloc_edge(pbqp, src_index, tgt_index, costs);
} else {
- matrix_add(edge->costs, costs);
+ pbqp_matrix_add(edge->costs, costs);
}
}
+
+num get_solution(pbqp *pbqp)
+{
+ return pbqp->solution;
+}
+
+void set_dumpfile(pbqp *pbqp, FILE *f)
+{
+ assert(pbqp);
+ pbqp->dump_file = f;
+}
/**
* Create an empty PBQP instance with the given number of nodes.
*/
-pbqp* alloc_pbqp(int number_nodes);
+pbqp* alloc_pbqp(unsigned number_nodes);
/**
* Free the given PBQP.
/**
* Add costs vector to given node.
*/
-void add_node_costs(pbqp *pbqp, int node_index, vector *costs);
+void add_node_costs(pbqp *pbqp, unsigned node_index, vector *costs);
/**
* Add costs matrix between given nodes.
*/
-void add_edge_costs(pbqp *pbqp, int src_index, int tgt_index, matrix *costs);
+void add_edge_costs(pbqp *pbqp, unsigned src_index, unsigned tgt_index, pbqp_matrix *costs);
-pbqp_edge *get_edge(pbqp *pbqp, int src_index, int tgt_index);
-pbqp_node *get_node(pbqp *pbqp, int index);
+pbqp_edge *get_edge(pbqp *pbqp, unsigned src_index, unsigned tgt_index);
+pbqp_node *get_node(pbqp *pbqp, unsigned index);
+
+num get_solution(pbqp *pbqp);
+
+void set_dumpfile(pbqp *pbqp, FILE *f);
#endif /* KAPS_KAPS_H */
#include "pbqp_t.h"
#include "matrix.h"
-matrix *matrix_copy(pbqp *pbqp, matrix *m)
+pbqp_matrix *pbqp_matrix_alloc(pbqp *pbqp, unsigned rows, unsigned cols)
+{
+ pbqp_matrix *mat;
+ unsigned index;
+
+ assert(cols> 0);
+ assert(rows> 0);
+
+ unsigned length = rows * cols;
+
+ mat = obstack_alloc(&pbqp->obstack, sizeof(*mat) + sizeof(num) * (length - 1));
+ assert(mat);
+
+ mat->cols = cols;
+ mat->rows = rows;
+ for (index = 0; index < length; ++index) {
+ mat->entries[index] = 0;
+ }
+
+ return mat;
+}
+
+pbqp_matrix *pbqp_matrix_copy(pbqp *pbqp, pbqp_matrix *m)
{
int i;
int len;
- matrix *copy = obstack_alloc(&pbqp->obstack, sizeof(*copy));
+ pbqp_matrix *copy = obstack_alloc(&pbqp->obstack, sizeof(*copy));
assert(copy);
return copy;
}
-void matrix_add(matrix *sum, matrix *summand)
+void pbqp_matrix_add(pbqp_matrix *sum, pbqp_matrix *summand)
{
int i;
int len;
sum->entries[i] += summand->entries[i];
}
}
+
+void pbqp_matrix_set(pbqp_matrix *mat, unsigned row, unsigned col, num value)
+{
+ assert(mat);
+ assert(col < mat->cols);
+ assert(row < mat->rows);
+
+ mat->entries[row * mat->cols + col] = value;
+}
#include "matrix_t.h"
+pbqp_matrix *pbqp_matrix_alloc(pbqp *pbqp, unsigned rows, unsigned cols);
+
/* Copy the given matrix. */
-matrix *matrix_copy(pbqp *pbqp, matrix *m);
+pbqp_matrix *pbqp_matrix_copy(pbqp *pbqp, pbqp_matrix *m);
/* sum += summand */
-void matrix_add(matrix *sum, matrix *summand);
+void pbqp_matrix_add(pbqp_matrix *sum, pbqp_matrix *summand);
+
+void pbqp_matrix_set(pbqp_matrix *mat, unsigned row, unsigned col, num value);
#endif /* KAPS_MATRIX_H */
#ifndef KAPS_MATRIX_T_H
#define KAPS_MATRIX_T_H
-typedef struct matrix matrix;
+#include "pbqp_t.h"
-struct matrix {
- int rows;
- int cols;
- int entries[];
+typedef struct pbqp_matrix pbqp_matrix;
+
+struct pbqp_matrix {
+ unsigned rows;
+ unsigned cols;
+ num entries[];
};
#endif /* KAPS_MATRIX_T_H */
#include "pbqp_node_t.h"
#include "pbqp_t.h"
-pbqp_edge *alloc_edge(pbqp *pbqp, int src_index, int tgt_index, matrix *costs)
+pbqp_edge *alloc_edge(pbqp *pbqp, int src_index, int tgt_index, pbqp_matrix *costs)
{
if (tgt_index < src_index) {
return alloc_edge(pbqp, tgt_index, src_index, costs);
pbqp_node *src_node = get_node(pbqp, src_index);
assert(src_node);
- edge->src = src_node;
pbqp_node *tgt_node = get_node(pbqp, tgt_index);
assert(tgt_node);
- edge->tgt = tgt_node;
- edge->costs = matrix_copy(pbqp, costs);
+ edge->costs = pbqp_matrix_copy(pbqp, costs);
/*
* Connect edge with incident nodes. Since the edge is allocated, we know
* that it don't appear in the edge lists of the nodes.
*/
ARR_APP1(pbqp_edge *, src_node->edges, edge);
- edge->src = src_node;
+ edge->src = src_index;
ARR_APP1(pbqp_edge *, tgt_node->edges, edge);
- edge->tgt = tgt_node;
+ edge->tgt = tgt_index;
return edge;
}
#include "pbqp_t.h"
-pbqp_edge *alloc_edge(pbqp *pbqp, int src_index, int tgt_index, matrix *costs);
+pbqp_edge *alloc_edge(pbqp *pbqp, int src_index, int tgt_index, pbqp_matrix *costs);
#endif /* KAPS_PBQP_EDGE_H */
#include "pbqp_t.h"
struct pbqp_edge {
- pbqp_node *src; /* Source node. */
- pbqp_node *tgt; /* Target node. */
- matrix *costs; /* Cost matrix. */
+ unsigned src; /* Source index. */
+ unsigned tgt; /* Target index. */
+ pbqp_matrix *costs; /* Cost matrix. */
};
#endif /* KAPS_PBQP_EDGE_T_H */
#define KAPS_PBQP_T_H
#include <limits.h>
+#include <stdio.h>
#include "adt/obstack.h"
+typedef int num;
+
#include "matrix_t.h"
#include "vector_t.h"
-typedef int num;
-
typedef struct pbqp_edge pbqp_edge;
typedef struct pbqp_node pbqp_node;
typedef struct pbqp pbqp;
-static const num INF_COST = INT_MAX;
+static const num INF_COSTS = INT_MAX;
struct pbqp {
struct obstack obstack; /* Obstack. */
num solution; /* Computed solution. */
size_t num_nodes; /* Number of PBQP nodes. */
pbqp_node **nodes; /* Nodes of PBQP. */
+ FILE *dump_file; /* File to dump in. */
};
#endif /* KAPS_PBQP_T_H */
#include "adt/array.h"
+#include "pbqp_t.h"
#include "vector.h"
+vector *vector_alloc(pbqp *pbqp, unsigned length)
+{
+ vector *vec;
+ unsigned index;
+
+ assert(length > 0);
+ vec = obstack_alloc(&pbqp->obstack, sizeof(*vec) + sizeof(vec_elem) * (length - 1));
+ assert(vec);
+
+ vec->len = length;
+ for (index = 0; index < length; ++index) {
+ vec->entries[index].data = 0;
+#if EXT_GRS_DEBUG
+ vec->entries[index].name = NULL;
+#endif
+ }
+
+ return vec;
+}
+
vector *vector_copy(pbqp *pbqp, vector *v)
{
int i;
len = sum->len;
for (i = 0; i < len; ++i) {
- sum->entries[i] += summand->entries[i];
+ sum->entries[i].data += summand->entries[i].data;
}
}
+
+void vector_set(vector *vec, unsigned index, num value)
+{
+ assert(index < vec->len);
+ vec->entries[index].data = value;
+}
+
+#if EXT_GRS_DEBUG
+void vector_set_description(vector *vec, unsigned index, char *name)
+{
+ assert(index < vec->len);
+ vec->entries[index].name = name;
+}
+#endif
#include "vector_t.h"
+vector *vector_alloc(pbqp *pbqp, unsigned length);
+
/* Copy the given vector. */
vector *vector_copy(pbqp *pbqp, vector *v);
/* sum += summand */
void vector_add(vector *sum, vector *summand);
+void vector_set(vector *vec, unsigned index, num value);
+
+#if EXT_GRS_DEBUG
+void vector_set_description(vector *vec, unsigned index, char *name);
+#endif
+
#endif /* KAPS_VECTOR_H */
#ifndef KAPS_VECTOR_T_H
#define KAPS_VECTOR_T_H
+#include "../debug.h"
+
#include "pbqp_t.h"
-struct vector;
+typedef struct vec_elem vec_elem;
+
+struct vec_elem {
+ num data;
+#if EXT_GRS_DEBUG
+ char *name;
+#endif
+};
+
typedef struct vector vector;
struct vector {
- int len;
- int entries[];
+ unsigned len;
+ vec_elem entries[];
};
#endif /* KAPS_VECTOR_T_H */