Sketcher: basic graph based system partitioning
This commit is contained in:
parent
1684585733
commit
126b25e690
|
@ -1563,13 +1563,14 @@ bool Sketch::updateGeometry()
|
||||||
|
|
||||||
// solving ==========================================================
|
// solving ==========================================================
|
||||||
|
|
||||||
int Sketch::solve()
|
int Sketch::solve(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
Base::TimeInfo start_time;
|
Base::TimeInfo start_time;
|
||||||
if (!isInitMove) { // make sure we are in single subsystem mode
|
if (!isInitMove) { // make sure we are in single subsystem mode
|
||||||
GCSsys.clearByTag(-1);
|
GCSsys.clearByTag(-1);
|
||||||
GCSsys.clearByTag(-2);
|
GCSsys.clearByTag(-2);
|
||||||
|
isFine = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1580,15 +1581,15 @@ int Sketch::solve()
|
||||||
case 0: // solving with the default DogLeg solver
|
case 0: // solving with the default DogLeg solver
|
||||||
// (or with SQP if we are in moving mode)
|
// (or with SQP if we are in moving mode)
|
||||||
solvername = isInitMove ? "SQP" : "DogLeg";
|
solvername = isInitMove ? "SQP" : "DogLeg";
|
||||||
ret = GCSsys.solve(true, GCS::DogLeg);
|
ret = GCSsys.solve(isFine, GCS::DogLeg);
|
||||||
break;
|
break;
|
||||||
case 1: // solving with the LevenbergMarquardt solver
|
case 1: // solving with the LevenbergMarquardt solver
|
||||||
solvername = "LevenbergMarquardt";
|
solvername = "LevenbergMarquardt";
|
||||||
ret = GCSsys.solve(true, GCS::LevenbergMarquardt);
|
ret = GCSsys.solve(isFine, GCS::LevenbergMarquardt);
|
||||||
break;
|
break;
|
||||||
case 2: // solving with the BFGS solver
|
case 2: // solving with the BFGS solver
|
||||||
solvername = "BFGS";
|
solvername = "BFGS";
|
||||||
ret = GCSsys.solve(true, GCS::BFGS);
|
ret = GCSsys.solve(isFine, GCS::BFGS);
|
||||||
break;
|
break;
|
||||||
case 3: // last resort: augment the system with a second subsystem and use the SQP solver
|
case 3: // last resort: augment the system with a second subsystem and use the SQP solver
|
||||||
solvername = "SQP(augmented system)";
|
solvername = "SQP(augmented system)";
|
||||||
|
@ -1601,7 +1602,7 @@ int Sketch::solve()
|
||||||
GCSsys.addConstraintEqual(*it, &InitParameters[i], -2);
|
GCSsys.addConstraintEqual(*it, &InitParameters[i], -2);
|
||||||
}
|
}
|
||||||
GCSsys.initSolution(Parameters);
|
GCSsys.initSolution(Parameters);
|
||||||
ret = GCSsys.solve(true);
|
ret = GCSsys.solve(isFine);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1647,8 +1648,10 @@ int Sketch::solve()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Sketch::initMove(int geoId, PointPos pos)
|
int Sketch::initMove(int geoId, PointPos pos, bool fine)
|
||||||
{
|
{
|
||||||
|
isFine = fine;
|
||||||
|
|
||||||
geoId = checkGeoId(geoId);
|
geoId = checkGeoId(geoId);
|
||||||
|
|
||||||
GCSsys.clearByTag(-1);
|
GCSsys.clearByTag(-1);
|
||||||
|
|
|
@ -94,7 +94,7 @@ public:
|
||||||
/** initializes a point (or curve) drag by setting the current
|
/** initializes a point (or curve) drag by setting the current
|
||||||
* sketch status as a reference
|
* sketch status as a reference
|
||||||
*/
|
*/
|
||||||
int initMove(int geoId, PointPos pos);
|
int initMove(int geoId, PointPos pos, bool fine=true);
|
||||||
|
|
||||||
/** move this point (or curve) to a new location and solve.
|
/** move this point (or curve) to a new location and solve.
|
||||||
* This will introduce some additional weak constraints expressing
|
* This will introduce some additional weak constraints expressing
|
||||||
|
@ -212,6 +212,7 @@ protected:
|
||||||
std::vector<GCS::Circle> Circles;
|
std::vector<GCS::Circle> Circles;
|
||||||
|
|
||||||
bool isInitMove;
|
bool isInitMove;
|
||||||
|
bool isFine;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// retrieves the index of a point
|
/// retrieves the index of a point
|
||||||
|
|
|
@ -27,9 +27,14 @@
|
||||||
#include "qp_eq.h"
|
#include "qp_eq.h"
|
||||||
#include <Eigen/QR>
|
#include <Eigen/QR>
|
||||||
|
|
||||||
|
#include <boost/graph/adjacency_list.hpp>
|
||||||
|
#include <boost/graph/connected_components.hpp>
|
||||||
|
|
||||||
namespace GCS
|
namespace GCS
|
||||||
{
|
{
|
||||||
|
|
||||||
|
typedef boost::adjacency_list <boost::vecS, boost::vecS, boost::undirectedS> Graph;
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Solver
|
// Solver
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
@ -38,9 +43,7 @@ namespace GCS
|
||||||
System::System()
|
System::System()
|
||||||
: clist(0),
|
: clist(0),
|
||||||
c2p(), p2c(),
|
c2p(), p2c(),
|
||||||
subsys0(0),
|
subsyslist(0),
|
||||||
subsys1(0),
|
|
||||||
subsys2(0),
|
|
||||||
reference(),
|
reference(),
|
||||||
init(false)
|
init(false)
|
||||||
{
|
{
|
||||||
|
@ -48,9 +51,7 @@ System::System()
|
||||||
|
|
||||||
System::System(std::vector<Constraint *> clist_)
|
System::System(std::vector<Constraint *> clist_)
|
||||||
: c2p(), p2c(),
|
: c2p(), p2c(),
|
||||||
subsys0(0),
|
subsyslist(0),
|
||||||
subsys1(0),
|
|
||||||
subsys2(0),
|
|
||||||
reference(),
|
reference(),
|
||||||
init(false)
|
init(false)
|
||||||
{
|
{
|
||||||
|
@ -553,6 +554,28 @@ void System::initSolution(VEC_pD ¶ms)
|
||||||
// - Organizes the rest of constraints into two subsystems for
|
// - Organizes the rest of constraints into two subsystems for
|
||||||
// tag ids >=0 and < 0 respectively and applies the
|
// tag ids >=0 and < 0 respectively and applies the
|
||||||
// system reduction specified in the previous step
|
// system reduction specified in the previous step
|
||||||
|
MAP_pD_I params_index;
|
||||||
|
for (int i=0; i < int(params.size()); ++i)
|
||||||
|
params_index[params[i]] = i;
|
||||||
|
|
||||||
|
Graph g;
|
||||||
|
for (int i=0; i < int(params.size() + clist.size()); i++)
|
||||||
|
boost::add_vertex(g);
|
||||||
|
|
||||||
|
int cvtid = int(params.size());
|
||||||
|
for (std::vector<Constraint *>::const_iterator constr=clist.begin();
|
||||||
|
constr != clist.end(); ++constr, cvtid++) {
|
||||||
|
VEC_pD &cparams = c2p[*constr];
|
||||||
|
for (VEC_pD::const_iterator param=cparams.begin();
|
||||||
|
param != cparams.end(); ++param) {
|
||||||
|
MAP_pD_I::const_iterator it = params_index.find(*param);
|
||||||
|
if (it != params_index.end())
|
||||||
|
boost::add_edge(cvtid, it->second, g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VEC_I components(boost::num_vertices(g));
|
||||||
|
int components_size = boost::connected_components(g, &components[0]);
|
||||||
|
|
||||||
clearReference();
|
clearReference();
|
||||||
for (VEC_pD::const_iterator param=params.begin();
|
for (VEC_pD::const_iterator param=params.begin();
|
||||||
|
@ -564,9 +587,6 @@ void System::initSolution(VEC_pD ¶ms)
|
||||||
reductionmap.clear();
|
reductionmap.clear();
|
||||||
{
|
{
|
||||||
VEC_pD reduced_params=params;
|
VEC_pD reduced_params=params;
|
||||||
MAP_pD_I params_index;
|
|
||||||
for (int i=0; i < int(params.size()); ++i)
|
|
||||||
params_index[params[i]] = i;
|
|
||||||
|
|
||||||
for (std::vector<Constraint *>::const_iterator constr=clist.begin();
|
for (std::vector<Constraint *>::const_iterator constr=clist.begin();
|
||||||
constr != clist.end(); ++constr) {
|
constr != clist.end(); ++constr) {
|
||||||
|
@ -589,27 +609,39 @@ void System::initSolution(VEC_pD ¶ms)
|
||||||
reductionmap[params[i]] = reduced_params[i];
|
reductionmap[params[i]] = reduced_params[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
int i=0;
|
std::vector< std::vector<Constraint *> > clists0(components_size),
|
||||||
std::vector<Constraint *> clist0, clist1, clist2;
|
clists1(components_size),
|
||||||
|
clists2(components_size);
|
||||||
|
int i = int(params.size());
|
||||||
for (std::vector<Constraint *>::const_iterator constr=clist.begin();
|
for (std::vector<Constraint *>::const_iterator constr=clist.begin();
|
||||||
constr != clist.end(); ++constr, i++) {
|
constr != clist.end(); ++constr, i++) {
|
||||||
if (eliminated.count(*constr) == 0) {
|
if (eliminated.count(*constr) == 0) {
|
||||||
|
int id = components[i];
|
||||||
if ((*constr)->getTag() >= 0)
|
if ((*constr)->getTag() >= 0)
|
||||||
clist0.push_back(*constr);
|
clists0[id].push_back(*constr);
|
||||||
else if ((*constr)->getTag() == -1) // move constraints
|
else if ((*constr)->getTag() == -1) // move constraints
|
||||||
clist1.push_back(*constr);
|
clists1[id].push_back(*constr);
|
||||||
else // distance from reference constraints
|
else // distance from reference constraints
|
||||||
clist2.push_back(*constr);
|
clists2[id].push_back(*constr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector< std::vector<double *> > plists(components_size);
|
||||||
|
for (int i=0; i < int(params.size()); ++i) {
|
||||||
|
int id = components[i];
|
||||||
|
plists[id].push_back(params[i]);
|
||||||
|
}
|
||||||
|
|
||||||
clearSubSystems();
|
clearSubSystems();
|
||||||
if (clist0.size() > 0)
|
for (int cid=0; cid < components_size; cid++) {
|
||||||
subsys0 = new SubSystem(clist0, params, reductionmap);
|
subsyslist.push_back(std::vector<SubSystem *>(0));
|
||||||
if (clist1.size() > 0)
|
if (clists0[cid].size() > 0)
|
||||||
subsys1 = new SubSystem(clist1, params, reductionmap);
|
subsyslist[cid].push_back(new SubSystem(clists0[cid], plists[cid], reductionmap));
|
||||||
if (clist2.size() > 0)
|
if (clists1[cid].size() > 0)
|
||||||
subsys2 = new SubSystem(clist2, params, reductionmap);
|
subsyslist[cid].push_back(new SubSystem(clists1[cid], plists[cid], reductionmap));
|
||||||
|
if (clists2[cid].size() > 0)
|
||||||
|
subsyslist[cid].push_back(new SubSystem(clists2[cid], plists[cid], reductionmap));
|
||||||
|
}
|
||||||
init = true;
|
init = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,31 +666,26 @@ int System::solve(VEC_pD ¶ms, bool isFine, Algorithm alg)
|
||||||
|
|
||||||
int System::solve(bool isFine, Algorithm alg)
|
int System::solve(bool isFine, Algorithm alg)
|
||||||
{
|
{
|
||||||
if (subsys0) {
|
bool isReset = false;
|
||||||
resetToReference();
|
// return success by default in order to permit coincidence constraints to be applied
|
||||||
if (subsys2) {
|
// even if no other system has to be solved
|
||||||
int ret = solve(subsys0, subsys2, isFine);
|
int res = Success;
|
||||||
if (subsys1) // give subsys1 higher priority than subsys2
|
for (int cid=0; cid < int(subsyslist.size()); cid++) {
|
||||||
// in this case subsys2 acts like a preconditioner
|
if (subsyslist[cid].size() > 0 && !isReset) {
|
||||||
return solve(subsys0, subsys1, isFine);
|
resetToReference();
|
||||||
else
|
isReset = true;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
else if (subsys1)
|
if (subsyslist[cid].size() == 1)
|
||||||
return solve(subsys0, subsys1, isFine);
|
res = std::max(res, solve(subsyslist[cid][0], isFine, alg));
|
||||||
else
|
else if (subsyslist[cid].size() == 2)
|
||||||
return solve(subsys0, isFine, alg);
|
res = std::max(res, solve(subsyslist[cid][0], subsyslist[cid][1], isFine));
|
||||||
|
else if (subsyslist[cid].size() > 2)
|
||||||
|
// subsystem 1 has higher priority than subsystems 2,3,...
|
||||||
|
// these subsystems act like a preconditioner
|
||||||
|
for (int i=subsyslist[cid].size()-1; i > 0; i--)
|
||||||
|
res = std::max(res, solve(subsyslist[cid][0], subsyslist[cid][i], isFine));
|
||||||
}
|
}
|
||||||
else if (subsys1) {
|
return res;
|
||||||
resetToReference();
|
|
||||||
if (subsys2)
|
|
||||||
return solve(subsys1, subsys2, isFine);
|
|
||||||
else
|
|
||||||
return solve(subsys1, isFine, alg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// return success in order to permit coincidence constraints to be applied
|
|
||||||
return Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int System::solve(SubSystem *subsys, bool isFine, Algorithm alg)
|
int System::solve(SubSystem *subsys, bool isFine, Algorithm alg)
|
||||||
|
@ -1193,25 +1220,11 @@ int System::solve(SubSystem *subsysA, SubSystem *subsysB, bool isFine)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::getSubSystems(std::vector<SubSystem *> &subsysvec)
|
|
||||||
{
|
|
||||||
subsysvec.clear();
|
|
||||||
if (subsys0)
|
|
||||||
subsysvec.push_back(subsys0);
|
|
||||||
if (subsys1)
|
|
||||||
subsysvec.push_back(subsys1);
|
|
||||||
if (subsys2)
|
|
||||||
subsysvec.push_back(subsys2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void System::applySolution()
|
void System::applySolution()
|
||||||
{
|
{
|
||||||
if (subsys2)
|
for (int cid=0; cid < int(subsyslist.size()); cid++)
|
||||||
subsys2->applySolution();
|
for (int i=subsyslist[cid].size()-1; i >= 0; i--)
|
||||||
if (subsys1)
|
subsyslist[cid][i]->applySolution();
|
||||||
subsys1->applySolution();
|
|
||||||
if (subsys0)
|
|
||||||
subsys0->applySolution();
|
|
||||||
|
|
||||||
for (MAP_pD_pD::const_iterator it=reductionmap.begin();
|
for (MAP_pD_pD::const_iterator it=reductionmap.begin();
|
||||||
it != reductionmap.end(); ++it)
|
it != reductionmap.end(); ++it)
|
||||||
|
@ -1303,12 +1316,9 @@ int System::diagnose(VEC_pD ¶ms, VEC_I &conflicting)
|
||||||
void System::clearSubSystems()
|
void System::clearSubSystems()
|
||||||
{
|
{
|
||||||
init = false;
|
init = false;
|
||||||
std::vector<SubSystem *> subsystems;
|
for (int i=0; i < int(subsyslist.size()); i++)
|
||||||
getSubSystems(subsystems);
|
free(subsyslist[i]);
|
||||||
free(subsystems);
|
subsyslist.clear();
|
||||||
subsys0 = NULL;
|
|
||||||
subsys1 = NULL;
|
|
||||||
subsys2 = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double lineSearch(SubSystem *subsys, Eigen::VectorXd &xdir)
|
double lineSearch(SubSystem *subsys, Eigen::VectorXd &xdir)
|
||||||
|
|
|
@ -54,9 +54,12 @@ namespace GCS
|
||||||
std::map<Constraint *,VEC_pD > c2p; // constraint to parameter adjacency list
|
std::map<Constraint *,VEC_pD > c2p; // constraint to parameter adjacency list
|
||||||
std::map<double *,std::vector<Constraint *> > p2c; // parameter to constraint adjacency list
|
std::map<double *,std::vector<Constraint *> > p2c; // parameter to constraint adjacency list
|
||||||
|
|
||||||
SubSystem *subsys0; // has the highest priority, always used as the primary subsystem
|
// each row of subsyslist contains 3 subsystems.
|
||||||
SubSystem *subsys1; // normally used as secondary subsystem, it is considered primary only if subsys0 is missing
|
// the first one has the highest priority, always used as the primary subsystem
|
||||||
SubSystem *subsys2; // has the lowest priority, always used as secondary system
|
// the second one is normally used as secondary subsystem, it is considered primary
|
||||||
|
// only if the first one is missing
|
||||||
|
// the rhird one has the lowest priority, always used as secondary system
|
||||||
|
std::vector< std::vector<SubSystem *> > subsyslist;
|
||||||
void clearSubSystems();
|
void clearSubSystems();
|
||||||
|
|
||||||
MAP_pD_D reference;
|
MAP_pD_D reference;
|
||||||
|
@ -152,7 +155,6 @@ namespace GCS
|
||||||
int solve(SubSystem *subsys, bool isFine=true, Algorithm alg=DogLeg);
|
int solve(SubSystem *subsys, bool isFine=true, Algorithm alg=DogLeg);
|
||||||
int solve(SubSystem *subsysA, SubSystem *subsysB, bool isFine=true);
|
int solve(SubSystem *subsysA, SubSystem *subsysB, bool isFine=true);
|
||||||
|
|
||||||
void getSubSystems(std::vector<SubSystem *> &subsysvec);
|
|
||||||
void applySolution();
|
void applySolution();
|
||||||
void undoSolution();
|
void undoSolution();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user