69 using typename base_type::graph_type;
70 using typename base_type::graph_vertex_type;
71 using typename base_type::graph_edge_type;
72 using typename base_type::vertex_iterator_type;
73 using typename base_type::edge_iterator_type;
74 using typename base_type::edge_weight_type;
87 double m_stitch_weight;
98 edge_weight_type
operator()(int32_t v, int8_t origp, int8_t newp, std::vector<int8_t>
const& vPartition)
const
100 typedef typename boost::graph_traits<graph_type>::out_edge_iterator out_edge_iterator_type;
101 out_edge_iterator_type ei, eie;
103 edge_weight_type gain = (origp >= 0)? 0 : boost::num_edges(
graph)*boost::num_vertices(
graph);
104 for (boost::tie(ei, eie) = boost::out_edges(v,
graph); ei != eie; ++ei)
106 graph_vertex_type t = boost::target(*ei,
graph);
107 int8_t pt = vPartition[t];
108#ifdef DEBUG_SDPCOLORING
112 if (pt < 0)
continue;
113 edge_weight_type w = boost::get(boost::edge_weight,
graph, *ei);
116 gain += (pt == newp)? -w : (pt == origp)? w : 0;
132 void write_sdp_sol(std::string
const& filename,
struct blockmatrix
const& X)
const;
136 void print_blockrec(
const char* label, blockrec
const& block)
const;
160 void set_sparseblock_entry(
struct sparseblock& block, int32_t entryid, int32_t i, int32_t j,
double value)
const;
165 void round_sol(
struct blockmatrix
const& X);
173 void coloring_algos(graph_type
const& g, std::vector<int8_t>& vColor)
const;
181 virtual void coloring_by_FM(graph_type
const& mg, std::vector<int8_t>& vColor)
const;
199 std::cout<<
"start csdp!";
200 clock_t solve_start = clock();
212 struct blockmatrix C;
214 struct constraintmatrix *constraints;
216 struct blockmatrix X,Z;
221 vertex_iterator_type vi, vie;
222 edge_iterator_type ei, eie;
224 uint32_t num_vertices = boost::num_vertices(this->
m_graph);
225 uint32_t num_edges = boost::num_edges(this->
m_graph);
227 uint32_t num_conflict_edges = 0;
228 uint32_t num_stitch_edges = 0;
229 for (boost::tie(ei, eie) = boost::edges(this->
m_graph); ei != eie; ++ei)
232 num_conflict_edges += 1;
234 num_stitch_edges += 1;
236 limboAssertMsg(num_edges > 0 && num_conflict_edges > 0,
"no edges or conflict edges found, no need to solve SDP");
238 uint32_t num_variables = num_vertices+num_conflict_edges;
239 uint32_t num_constraints = num_conflict_edges+num_vertices;
243 C.blocks = (
struct blockrec *)malloc((C.nblocks+1)*
sizeof(
struct blockrec));
248 for (boost::tie(ei, eie) = boost::edges(this->
m_graph); ei != eie; ++ei)
250 graph_vertex_type s = boost::source(*ei, this->
m_graph);
251 graph_vertex_type t = boost::target(*ei, this->
m_graph);
258 int32_t idx1 = ijtok(s,t,C.blocks[1].blocksize);
259 int32_t idx2 = ijtok(t,s,C.blocks[1].blocksize);
260 C.blocks[1].data.mat[idx1] = alpha;
261 C.blocks[1].data.mat[idx2] = alpha;
274 b = (
double *)malloc((num_constraints+1)*
sizeof(
double));
275 limboAssertMsg(b,
"Failed to allocate storage for right hand side of constraints b");
278 double beta = -2.0/(this->
color_num()-1.0);
279 for (uint32_t i = 1, ie = num_constraints+1; i != ie; ++i)
281 if (i <= num_conflict_edges)
289 constraints=(
struct constraintmatrix *)malloc((num_constraints+1)*
sizeof(
struct constraintmatrix));
290 limboAssertMsg(constraints,
"Failed to allocate storage for constraints");
293 for (boost::tie(ei, eie) = boost::edges(this->
m_graph); ei != eie; ++ei)
297 graph_vertex_type s = boost::source(*ei, this->
m_graph);
298 graph_vertex_type t = boost::target(*ei, this->
m_graph);
303 struct constraintmatrix& constr = constraints[cnt];
305 constr.blocks = NULL;
308 for (uint32_t i = 2; i != 0; --i)
310 struct sparseblock* blockptr;
322 blockptr->next = constr.blocks;
323 constr.blocks = blockptr;
329 for (boost::tie(vi, vie) = boost::vertices(this->
m_graph); vi != vie; ++vi)
331 graph_vertex_type v = *vi;
333 struct constraintmatrix& constr = constraints[cnt];
335 constr.blocks = NULL;
339 blockptr->next = constr.blocks;
340 constr.blocks = blockptr;
344#ifdef DEBUG_SDPCOLORING
345 write_prob((
char*)
"problem.sdpa", num_variables, num_constraints, C, b, constraints);
351 initsoln(num_variables, num_constraints, C, b, constraints, &X, &y, &Z);
354 struct paramstruc params;
356 initparams(¶ms, &printlevel);
364 int ret =
limbo::solvers::easy_sdp_ext<int>(num_variables, num_constraints, C, b, constraints, 0.0, &X, &y, &Z, &pobj, &dobj, params, printlevel);
368 clock_t solve_end = clock();
369 limboPrint(kDEBUG,
"SDP solver takes %g seconds with %u nodes\n", (
double)(solve_end - solve_start)/CLOCKS_PER_SEC, num_vertices);
375 free_prob(num_variables, num_constraints, C, b, constraints, X, y, Z);
377#ifdef DEBUG_LPCOLORING
384 limboPrint(kDEBUG,
"SDP coloring cost %g\n", final_cost);
443#ifdef DEBUG_SDPCOLORING
447 std::vector<graph_vertex_type> vParent (boost::num_vertices(this->
m_graph));
448 std::vector<uint32_t> vRank (vParent.size());
450 disjoint_set_type::SubsetHelper<graph_vertex_type, uint32_t> gp (vParent, vRank);
453 struct blockrec const& block = X.blocks[1];
454 limboAssertMsg(block.blockcategory == MATRIX,
"mismatch of block category");
455 for (int32_t i = 1; i <= block.blocksize; ++i)
456 for (int32_t j = i+1; j <= block.blocksize; ++j)
458 double ent = block.data.mat[ijtok(i, j, block.blocksize)];
460 disjoint_set_type::union_set(gp, i-1, j-1);
464 std::vector<graph_vertex_type> vG2MG (vParent.size(), std::numeric_limits<graph_vertex_type>::max());
465 uint32_t mg_count = 0;
466 for (uint32_t i = 0, ie = vParent.size(); i != ie; ++i)
468 vG2MG[i] = mg_count++;
469 for (uint32_t i = 0, ie = vParent.size(); i != ie; ++i)
471 vG2MG[i] = vG2MG.at(disjoint_set_type::find_set(gp, i));
472#ifdef DEBUG_SDPCOLORING
473 limboAssert(mg_count == disjoint_set_type::count_sets(gp));
475 graph_type mg (mg_count);
477 edge_iterator_type ei, eie;
478 for (boost::tie(ei, eie) = boost::edges(this->
m_graph); ei != eie; ++ei)
480 graph_edge_type
const& e = *ei;
481 graph_vertex_type s = boost::source(e, this->
m_graph);
482 graph_vertex_type t = boost::target(e, this->
m_graph);
483 graph_vertex_type ms = vG2MG.at(s);
484 graph_vertex_type mt = vG2MG.at(t);
485 if(ms == mt)
continue;
486 std::pair<graph_edge_type, bool> me = boost::edge(ms, mt, mg);
490 w += boost::get(boost::edge_weight, mg, me.first);
492 me = boost::add_edge(ms, mt, mg);
493 boost::put(boost::edge_weight, mg, me.first, w);
494#ifdef DEBUG_SDPCOLORING
495 limboAssert(boost::get(boost::edge_weight, mg, me.first) != 0);
498#ifdef DEBUG_SDPCOLORING
505 std::vector<int8_t> vMColor (mg_count, -1);
509 vertex_iterator_type vi, vie;
510 for (boost::tie(vi, vie) = boost::vertices(this->
m_graph); vi != vie; ++vi)
512 graph_vertex_type v = *vi;
513 this->
m_vColor[v] = vMColor.at(vG2MG.at(v));
514#ifdef DEBUG_SDPCOLORING
524 uint32_t num_vertices = boost::num_vertices(mg);
526 limboPrint(kDEBUG,
"SDP merged coloring with %u nodes\n", num_vertices);
539 graph_simplification_type gs (mg, this->
color_num());
540 gs.simplify(graph_simplification_type::HIDE_SMALL_DEGREE);
545 std::vector<std::vector<int8_t> > mSubColor (gs.num_component());
546 std::vector<std::vector<graph_vertex_type> > mSimpl2Orig (gs.num_component());
548 for (uint32_t sub_comp_id = 0; sub_comp_id < gs.num_component(); ++sub_comp_id)
552 std::vector<int8_t>& vSubColor = mSubColor[sub_comp_id];
553 std::vector<graph_vertex_type>& vSimpl2Orig = mSimpl2Orig[sub_comp_id];
555 gs.simplified_graph_component(sub_comp_id, sg, vSimpl2Orig);
557 vSubColor.assign(boost::num_vertices(sg), -1);
559#ifdef DEBUG_SDPCOLORING
564#ifdef DEBUG_SDPCOLORING
570 clock_t recover_start = clock();
574 gs.recover(vMColor, mSubColor, mSimpl2Orig);
581 gs.recover_hide_small_degree(vMColor);
583 clock_t recover_end = clock();
584 std::cout <<
"Coloring recovery takes " << (double)(recover_end - recover_start)/CLOCKS_PER_SEC <<
"s." << std::endl;
585 ::cout <<
"SDP final result : ";
586 for(uint32_t i = 0; i < vMColor.size(); i++)
587 std::cout <<
unsigned(vMColor[i]) <<
" ";
588 std::cout << std::endl;
652 uint32_t matrix_size = 0;
653 for (int32_t blk = 1; blk <= X.nblocks; ++blk)
654 matrix_size += X.blocks[blk].blocksize;
657 std::vector<std::vector<double> > mSol (matrix_size, std::vector<double>(matrix_size, 0.0));
659 int32_t index_offset = 0;
660 for (int32_t blk = 1; blk <= X.nblocks; ++blk)
662 switch (X.blocks[blk].blockcategory)
665 for (int32_t i = 1; i <= X.blocks[blk].blocksize; ++i)
667 double ent = X.blocks[blk].data.vec[i];
669 mSol[index_offset+i-1][index_offset+i-1] = ent;
673 for (int32_t i = 1; i <= X.blocks[blk].blocksize; ++i)
674 for (int32_t j = i; j <= X.blocks[blk].blocksize; ++j)
676 double ent = X.blocks[blk].data.mat[ijtok(i, j, X.blocks[blk].blocksize)];
678 mSol[index_offset+i-1][index_offset+j-1] = ent;
684 index_offset += X.blocks[blk].blocksize;
688 std::ofstream out (filename.c_str());
689 limboAssertMsg(out.good(),
"failed to open file %s for write\n", filename.c_str());
690 for (std::vector<std::vector<double> >::const_iterator it1 = mSol.begin(), it1e = mSol.end(); it1 != it1e; ++it1)
692 const char* prefix =
"";
693 for (std::vector<double>::const_iterator it2 = it1->begin(), it2e = it1->end(); it2 != it2e; ++it2)
695 out << prefix << *it2;
int easy_sdp_ext(int n, int k, struct blockmatrix C, double *a, struct constraintmatrix *constraints, double constant_offset, struct blockmatrix *pX, double **py, struct blockmatrix *pZ, double *ppobj, double *pdobj, struct paramstruc const ¶ms, int const &printlevel)
API to call Csdp solver.