Anabatic transient commit 7. More Dijkstra bugs correcteds.

* Bug: In Anabatic:
    - Activate the searchArea to limit the area explored by the Dijkstra.
      Uses the bounding boxes of the vertexes/gcells instead of the ones
      the RoutingPads.
    - Always detach contacts from the rings in load(), even if the vertex
      is already marked as target.
    - On reaching a target (non-negative connexId), do not forget to update
      the distance to source.
    - In Edges locator, added support for side selection (needed by the
      monotonic feature).
* New: In Anabatic:
    - Hide the atomic Dijkstra methods (made private).
    - Implementation of the monotonic mode in Dijkstra (for bipoints only).
    - Added a separate function for distance computation between two vertexes,
      now take account of the VIAs costs.
This commit is contained in:
Jean-Paul Chaput 2016-06-10 18:27:06 +02:00
parent 23d6ae55fd
commit c5a9e0b617
6 changed files with 243 additions and 101 deletions

View File

@ -21,6 +21,7 @@
#include "hurricane/Horizontal.h" #include "hurricane/Horizontal.h"
#include "hurricane/Vertical.h" #include "hurricane/Vertical.h"
#include "hurricane/UpdateSession.h" #include "hurricane/UpdateSession.h"
#include "hurricane/DebugSession.h"
#include "anabatic/AnabaticEngine.h" #include "anabatic/AnabaticEngine.h"
#include "anabatic/Dijkstra.h" #include "anabatic/Dijkstra.h"
@ -37,6 +38,7 @@ namespace Anabatic {
using Hurricane::Vertical; using Hurricane::Vertical;
using Hurricane::RoutingPad; using Hurricane::RoutingPad;
using Hurricane::UpdateSession; using Hurricane::UpdateSession;
using Hurricane::DebugSession;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -81,9 +83,40 @@ namespace Anabatic {
// Class : "Anabatic::Dijkstra". // Class : "Anabatic::Dijkstra".
Dijkstra::Mode::~Mode ()
{ }
string Dijkstra::Mode::_getTypeName () const
{ return "Anabatic::Dijkstra::Mode"; }
string Dijkstra::Mode::_getString () const
{
string s = "";
s += (_flags & Standart ) ? 'S' : '-';
s += (_flags & Monotonic) ? 'M' : '-';
return s;
}
float Dijkstra::getDistance ( const Vertex* a, const Vertex* b, const Edge* e )
{
float distance = a->getDistance() + e->getDistance();
Edge* aFrom = a->getFrom();
if (aFrom) {
distance += (aFrom->isHorizontal() xor e->isHorizontal()) ? 3.0 : 0.0;
}
return distance;
}
Dijkstra::Dijkstra ( AnabaticEngine* anabatic ) Dijkstra::Dijkstra ( AnabaticEngine* anabatic )
: _anabatic (anabatic) : _anabatic (anabatic)
, _vertexes () , _vertexes ()
, _mode (Mode::Standart)
, _net (NULL) , _net (NULL)
, _stamp (-1) , _stamp (-1)
, _sources () , _sources ()
@ -109,8 +142,8 @@ namespace Anabatic {
{ {
_net = net; _net = net;
DebugSession::open( _net, 110, 120 );
cdebug.log(111,1) << "Dijkstra::load() " << _net << endl; cdebug.log(111,1) << "Dijkstra::load() " << _net << endl;
UpdateSession::open();
_sources.clear(); _sources.clear();
_targets.clear(); _targets.clear();
@ -133,58 +166,83 @@ namespace Anabatic {
continue; continue;
} }
_searchArea.merge( rpBb ); _searchArea.merge( gcell->getBoundingBox() );
Vertex* vertex = gcell->getObserver<Vertex>(GCell::Observable::Vertex); Vertex* vertex = gcell->getObserver<Vertex>(GCell::Observable::Vertex);
if (vertex->getConnexId() < 0) { if (vertex->getConnexId() < 0) {
vertex->setStamp ( _stamp ); vertex->setStamp ( _stamp );
vertex->setConnexId( _targets.size() ); vertex->setConnexId( _targets.size() );
vertex->setFrom ( NULL ); vertex->setFrom ( NULL );
Contact* gcontact = vertex->getGContact( _net );
rp->getBodyHook()->detach();
rp->getBodyHook()->attach( gcontact->getBodyHook() );
_targets.insert( vertex ); _targets.insert( vertex );
cdebug.log(111) << "Add Vertex: " << vertex << endl; cdebug.log(111) << "Add Vertex: " << vertex << endl;
} }
Contact* gcontact = vertex->getGContact( _net );
rp->getBodyHook()->detach();
rp->getBodyHook()->attach( gcontact->getBodyHook() );
} }
UpdateSession::close(); cdebug.log(111) << "Search area: " << _searchArea << endl;
cdebug.tabw(111,-1); cdebug.tabw(111,-1);
DebugSession::close();
} }
void Dijkstra::selectFirstSource () void Dijkstra::_selectFirstSource ()
{ {
if (_targets.empty()) { if (_targets.empty()) {
cerr << Error( "Dijkstra::selectFirstSource(): %s has no vertexes to route, ignored." cerr << Error( "Dijkstra::_selectFirstSource(): %s has no vertexes to route, ignored."
, getString(_net).c_str() , getString(_net).c_str()
) << endl; ) << endl;
return; return;
} }
Point areaCenter = _searchArea.getCenter();
auto ivertex = _targets.begin();
Vertex* firstSource = *ivertex++;
DbU::Unit minDistance = areaCenter.manhattanDistance( firstSource->getCenter() );
for ( ; ivertex != _targets.end() ; ++ivertex ) { Vertex* firstSource = NULL;
DbU::Unit distance = areaCenter.manhattanDistance( (*ivertex)->getCenter() );
if (distance < minDistance) { if (_mode & Mode::Monotonic) {
minDistance = distance; if (_targets.size() == 2) {
firstSource = *ivertex; auto ivertex = _targets.begin();
Vertex* v1 = *ivertex;
Vertex* v2 = *(++ivertex);
firstSource = (v1->getCenter().getX() <= v2->getCenter().getY()) ? v1 : v2;
} else {
cerr << Error( "Dijkstra::_selectFirstSource(): %s cannot be routed in monotonic mode.\n"
" Must have exactly two terminals (%u), revert to Standart."
, getString(_net).c_str()
, _targets.size()
) << endl;
_mode = Mode::Standart;
}
}
if (not firstSource) {
// Standart routing.
Point areaCenter = _searchArea.getCenter();
auto ivertex = _targets.begin();
firstSource = *ivertex++;
DbU::Unit minDistance = areaCenter.manhattanDistance( firstSource->getCenter() );
for ( ; ivertex != _targets.end() ; ++ivertex ) {
DbU::Unit distance = areaCenter.manhattanDistance( (*ivertex)->getCenter() );
if (distance < minDistance) {
minDistance = distance;
firstSource = *ivertex;
}
} }
} }
_targets.erase ( firstSource ); _targets.erase ( firstSource );
_sources.insert( firstSource ); _sources.insert( firstSource );
cdebug.log(111) << "Dijkstra::selectFirstSource() " << *_sources.begin() << endl; cdebug.log(111) << "Dijkstra::_selectFirstSource() " << *_sources.begin() << endl;
} }
bool Dijkstra::propagate () bool Dijkstra::_propagate ( Flags enabledSides )
{ {
cdebug.log(111,1) << "Dijkstra::propagate() " << _net << endl; cdebug.log(111,1) << "Dijkstra::_propagate() " << _net << endl;
while ( not _queue.empty() ) { while ( not _queue.empty() ) {
_queue.dump(); _queue.dump();
@ -192,8 +250,6 @@ namespace Anabatic {
Vertex* current = _queue.top(); Vertex* current = _queue.top();
_queue.pop(); _queue.pop();
cdebug.log(111) << "Pop: (size:" << _queue.size() << ") " << current << endl;
if ((current->getConnexId() == _connectedsId) or (current->getConnexId() < 0)) { if ((current->getConnexId() == _connectedsId) or (current->getConnexId() < 0)) {
for ( Edge* edge : current->getGCell()->getEdges() ) { for ( Edge* edge : current->getGCell()->getEdges() ) {
@ -202,26 +258,34 @@ namespace Anabatic {
GCell* gneighbor = edge->getOpposite(current->getGCell()); GCell* gneighbor = edge->getOpposite(current->getGCell());
Vertex* vneighbor = gneighbor->getObserver<Vertex>(GCell::Observable::Vertex); Vertex* vneighbor = gneighbor->getObserver<Vertex>(GCell::Observable::Vertex);
if (not _searchArea.contains(vneighbor->getCenter())) continue;
cdebug.log(111) << "| Edge " << edge << endl; cdebug.log(111) << "| Edge " << edge << endl;
cdebug.log(111) << "+ Neighbor: " << vneighbor << endl; cdebug.log(111) << "+ Neighbor: " << vneighbor << endl;
float distance = getDistance( current, vneighbor, edge );
if (vneighbor->getConnexId() == _connectedsId) continue; if (vneighbor->getConnexId() == _connectedsId) continue;
if (vneighbor->getConnexId() >= 0) { if (vneighbor->getConnexId() >= 0) {
vneighbor->setFrom( edge ); vneighbor->setFrom ( edge );
vneighbor->setDistance( distance );
cdebug.log(111) << "Push (before): (size:" << _queue.size() << ")" << endl;
_queue.push( vneighbor ); _queue.push( vneighbor );
cdebug.log(111) << "Push (target): (size:" << _queue.size() << ") " << vneighbor << endl; cdebug.log(111) << "Push (target): (size:" << _queue.size() << ") " << vneighbor << endl;
continue; continue;
} }
float distance = current->getDistance() + edge->getDistance();
if (distance < vneighbor->getDistance()) { if (distance < vneighbor->getDistance()) {
if (vneighbor->getDistance() != Vertex::unreached) _queue.erase( vneighbor ); cdebug.log(111) << "Push (before erase): (size:" << _queue.size() << ") " << vneighbor << endl;
else { if (vneighbor->getDistance() != Vertex::unreached) {
_queue.erase( vneighbor );
_queue.dump();
} else {
vneighbor->setStamp ( _stamp ); vneighbor->setStamp ( _stamp );
vneighbor->setConnexId( -1 ); vneighbor->setConnexId( -1 );
} }
cdebug.log(111) << "Push (after erase): (size:" << _queue.size() << ")" << endl;
vneighbor->setDistance( distance ); vneighbor->setDistance( distance );
vneighbor->setFrom ( edge ); vneighbor->setFrom ( edge );
@ -263,18 +327,27 @@ namespace Anabatic {
} }
void Dijkstra::run () void Dijkstra::run ( Dijkstra::Mode mode )
{ {
cdebug.log(111,1) << "Dijkstra::run() on " << _net << endl; DebugSession::open( _net, 110, 120 );
selectFirstSource(); cdebug.log(111,1) << "Dijkstra::run() on " << _net << " mode:" << mode << endl;
_mode = mode;
_selectFirstSource();
if (_sources.empty()) { if (_sources.empty()) {
cdebug.log(111) << "No source to start, not routed." << endl; cdebug.log(111) << "No source to start, not routed." << endl;
cdebug.tabw(111,-1); cdebug.tabw(111,-1);
return; return;
} }
UpdateSession::open(); Flags enabledEdges = Flags::AllSides;
if (_mode & Mode::Monotonic) {
if ((*_sources.begin())->getCenter().getY() <= (*_targets.begin())->getCenter().getY())
enabledEdges = Flags::EastSide | Flags::NorthSide;
else
enabledEdges = Flags::EastSide | Flags::SouthSide;
}
Vertex* source = *_sources.begin(); Vertex* source = *_sources.begin();
_queue.clear(); _queue.clear();
@ -286,17 +359,17 @@ namespace Anabatic {
<< source << source
<< " _connectedsId:" << _connectedsId << endl; << " _connectedsId:" << _connectedsId << endl;
while ( not _targets.empty() and propagate() ); while ( not _targets.empty() and _propagate(enabledEdges) );
toWires(); _toWires();
_queue.clear(); _queue.clear();
UpdateSession::close();
cdebug.tabw(111,-1); cdebug.tabw(111,-1);
DebugSession::close();
} }
void Dijkstra::toWires () void Dijkstra::_toWires ()
{ {
cdebug.log(111,1) << "Dijkstra::toWires() " << _net << endl; cdebug.log(111,1) << "Dijkstra::toWires() " << _net << endl;

View File

@ -26,14 +26,15 @@ namespace Anabatic {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "Anabatic::GCell_Edges". // Class : "Anabatic::GCell_Edges".
GCell_Edges::Locator::Locator ( const GCell* gcell ) GCell_Edges::Locator::Locator ( const GCell* gcell, Flags filterFlags )
: EdgesHL() : EdgesHL()
, _gcell(gcell) , _gcell (gcell)
, _flags(Flags::EastSide) , _stateFlags (Flags::EastSide)
, _iedge(0) , _filterFlags(filterFlags)
, _iedge (0)
{ {
// cdebug.log(110) << "GCell_Edges::Locator::Locator() " << isValid() << endl; // cdebug.log(110) << "GCell_Edges::Locator::Locator() " << isValid() << endl;
if (_gcell->getEastEdges().empty()) progress(); if (_gcell->getEastEdges().empty() or not _filterFlags.contains(Flags::EastSide)) progress();
} }
@ -46,21 +47,21 @@ namespace Anabatic {
Edge* GCell_Edges::Locator::getElement () const Edge* GCell_Edges::Locator::getElement () const
{ {
if (_flags.contains(Flags::EastSide )) return _gcell->getEastEdges ()[_iedge]; if (_stateFlags.contains(Flags::EastSide )) return _gcell->getEastEdges ()[_iedge];
if (_flags.contains(Flags::NorthSide)) return _gcell->getNorthEdges()[_iedge]; if (_stateFlags.contains(Flags::NorthSide)) return _gcell->getNorthEdges()[_iedge];
if (_flags.contains(Flags::WestSide )) return _gcell->getWestEdges ()[_iedge]; if (_stateFlags.contains(Flags::WestSide )) return _gcell->getWestEdges ()[_iedge];
if (_flags.contains(Flags::SouthSide)) return _gcell->getSouthEdges()[_iedge]; if (_stateFlags.contains(Flags::SouthSide)) return _gcell->getSouthEdges()[_iedge];
return NULL; return NULL;
} }
bool GCell_Edges::Locator::isValid () const bool GCell_Edges::Locator::isValid () const
{ return _flags; } { return _stateFlags; }
void GCell_Edges::Locator::progress () void GCell_Edges::Locator::progress ()
{ {
// cdebug.log(110) << "GCell_Edges::Locator::progress() [from] " << _flags << " iedge:" << _iedge << endl; // cdebug.log(110) << "GCell_Edges::Locator::progress() [from] " << _stateFlags << " iedge:" << _iedge << endl;
// cdebug.log(110) << " East:" << _gcell->getEastEdges().size() // cdebug.log(110) << " East:" << _gcell->getEastEdges().size()
// << " North:" << _gcell->getNorthEdges().size() // << " North:" << _gcell->getNorthEdges().size()
// << " West:" << _gcell->getWestEdges().size() // << " West:" << _gcell->getWestEdges().size()
@ -68,51 +69,51 @@ namespace Anabatic {
// cdebug.log(110) << this << endl; // cdebug.log(110) << this << endl;
++_iedge; ++_iedge;
while (_flags) { while (_stateFlags) {
if (_flags.contains(Flags::EastSide)) { if ((_stateFlags & _filterFlags).contains(Flags::EastSide)) {
if (_iedge < _gcell->getEastEdges().size()) break; if (_iedge < _gcell->getEastEdges().size()) break;
// cdebug.log(110) << "Switching to North side." << endl; // cdebug.log(110) << "Switching to North side." << endl;
_flags = Flags::NorthSide; _stateFlags = Flags::NorthSide;
_iedge = 0; _iedge = 0;
// cdebug.log(110) << this << endl; // cdebug.log(110) << this << endl;
continue; continue;
} }
if (_flags.contains(Flags::NorthSide)) { if ((_stateFlags & _filterFlags).contains(Flags::NorthSide)) {
if (_iedge < _gcell->getNorthEdges().size()) break; if (_iedge < _gcell->getNorthEdges().size()) break;
// cdebug.log(110) << "Switching to West side." << endl; // cdebug.log(110) << "Switching to West side." << endl;
_flags = Flags::WestSide; _stateFlags = Flags::WestSide;
_iedge = 0; _iedge = 0;
// cdebug.log(110) << this << endl; // cdebug.log(110) << this << endl;
continue; continue;
} }
if (_flags.contains(Flags::WestSide)) { if ((_stateFlags & _filterFlags).contains(Flags::WestSide)) {
if (_iedge < _gcell->getWestEdges().size()) break; if (_iedge < _gcell->getWestEdges().size()) break;
// cdebug.log(110) << "Switching to South side." << endl; // cdebug.log(110) << "Switching to South side." << endl;
_flags = Flags::SouthSide; _stateFlags = Flags::SouthSide;
_iedge = 0; _iedge = 0;
continue; continue;
} }
if (_flags.contains(Flags::SouthSide)) { if ((_stateFlags & _filterFlags).contains(Flags::SouthSide)) {
if (_iedge < _gcell->getSouthEdges().size()) break; if (_iedge < _gcell->getSouthEdges().size()) break;
// cdebug.log(110) << "All edges done." << endl; // cdebug.log(110) << "All edges done." << endl;
_flags = 0; _stateFlags = 0;
_iedge = 0; _iedge = 0;
break;; break;;
} }
} }
cdebug.log(110) << "GCell_Edges::Locator::progress() [to] " << _flags << " iedge:" << _iedge << endl; cdebug.log(110) << "GCell_Edges::Locator::progress() [to] " << _stateFlags << " iedge:" << _iedge << endl;
} }
string GCell_Edges::Locator::_getString () const string GCell_Edges::Locator::_getString () const
{ {
string s = "<GCell_Edges::Locator"; string s = "<GCell_Edges::Locator";
if (_flags.contains(Flags::EastSide )) s += " East[" + getString(_iedge) + "]"; if (_stateFlags.contains(Flags::EastSide )) s += " East[" + getString(_iedge) + "]";
if (_flags.contains(Flags::NorthSide)) s += " North[" + getString(_iedge) + "]"; if (_stateFlags.contains(Flags::NorthSide)) s += " North[" + getString(_iedge) + "]";
if (_flags.contains(Flags::WestSide )) s += " West[" + getString(_iedge) + "]"; if (_stateFlags.contains(Flags::WestSide )) s += " West[" + getString(_iedge) + "]";
if (_flags.contains(Flags::SouthSide)) s += " South[" + getString(_iedge) + "]"; if (_stateFlags.contains(Flags::SouthSide)) s += " South[" + getString(_iedge) + "]";
if (_flags == 0) s += " invalid"; if (_stateFlags == 0) s += " invalid";
s += ">"; s += ">";
return s; return s;
} }
@ -123,7 +124,7 @@ namespace Anabatic {
EdgesHL* GCell_Edges::getLocator () const EdgesHL* GCell_Edges::getLocator () const
{ return new Locator (_gcell); } { return new Locator (_gcell,_filterFlags); }
string GCell_Edges::_getString () const string GCell_Edges::_getString () const

View File

@ -395,7 +395,7 @@ namespace Anabatic {
return false; return false;
} }
UpdateSession::open(); //UpdateSession::open();
GCell* row = this; GCell* row = this;
GCell* column = NULL; GCell* column = NULL;
@ -414,7 +414,7 @@ namespace Anabatic {
column = column->vcut( xcut ); column = column->vcut( xcut );
} }
UpdateSession::close(); //UpdateSession::close();
return true; return true;
} }

View File

@ -152,6 +152,31 @@ namespace Anabatic {
} }
void anabaticTest_5 ( AnabaticEngine* engine )
{
Cell* cell = engine->getCell();
cell->flattenNets( Cell::Flags::BuildRings );
cell->createRoutingPadRings( Cell::Flags::BuildRings );
//DebugSession::addToTrace( cell->getNet("alu_out(3)") );
DebugSession::addToTrace( cell->getNet("imuxe.not_aux2") );
UpdateSession::open();
engine->getSouthWestGCell()->doGrid();
Dijkstra* dijkstra = new Dijkstra ( engine );
for ( Net* net : cell->getNets() ) {
if (net->isPower() or net->isClock()) continue;
dijkstra->load( net );
dijkstra->run();
}
delete dijkstra;
UpdateSession::close();
}
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "Anabatic::GraphicAnabaticEngine". // Class : "Anabatic::GraphicAnabaticEngine".
@ -304,7 +329,8 @@ namespace Anabatic {
//anabaticTest_1( engine ); //anabaticTest_1( engine );
//anabaticTest_2( engine ); //anabaticTest_2( engine );
//anabaticTest_3( engine ); //anabaticTest_3( engine );
anabaticTest_4( engine ); //anabaticTest_4( engine );
anabaticTest_5( engine );
if (_viewer) _viewer->emitCellChanged(); if (_viewer) _viewer->emitCellChanged();
} }

View File

@ -50,7 +50,7 @@ namespace Anabatic {
static void notify ( Vertex*, unsigned flags ); static void notify ( Vertex*, unsigned flags );
public: public:
inline Vertex ( GCell* ); inline Vertex ( GCell* );
inline Vertex ( size_t id ); //inline Vertex ( size_t id );
inline ~Vertex (); inline ~Vertex ();
inline unsigned int getId () const; inline unsigned int getId () const;
inline GCell* getGCell () const; inline GCell* getGCell () const;
@ -92,19 +92,18 @@ namespace Anabatic {
, _distance(unreached) , _distance(unreached)
, _from (NULL) , _from (NULL)
{ {
//gcell->setLookup<Vertex>( this );
gcell->setObserver( GCell::Observable::Vertex, &_observer ); gcell->setObserver( GCell::Observable::Vertex, &_observer );
} }
inline Vertex::Vertex ( size_t id ) // inline Vertex::Vertex ( size_t id )
: _id (id) // : _id (id)
, _gcell (NULL) // , _gcell (NULL)
, _observer((Vertex*)0x1) // To trick the NULL detection. // , _observer((Vertex*)0x1) // To trick the NULL detection.
, _connexId(-1) // , _connexId(-1)
, _stamp (-1) // , _stamp (-1)
, _distance(unreached) // , _distance(unreached)
, _from (NULL) // , _from (NULL)
{ } // { }
inline Vertex::~Vertex () { } inline Vertex::~Vertex () { }
inline unsigned int Vertex::getId () const { return _id; } inline unsigned int Vertex::getId () const { return _id; }
@ -165,11 +164,22 @@ namespace Anabatic {
inline bool PriorityQueue::empty () const { return _queue.empty(); } inline bool PriorityQueue::empty () const { return _queue.empty(); }
inline size_t PriorityQueue::size () const { return _queue.size(); } inline size_t PriorityQueue::size () const { return _queue.size(); }
inline void PriorityQueue::push ( Vertex* v ) { _queue.insert(v); } inline void PriorityQueue::push ( Vertex* v ) { _queue.insert(v); }
inline void PriorityQueue::erase ( Vertex* v ) { _queue.erase(v); }
inline Vertex* PriorityQueue::top () { return _queue.empty() ? NULL : *_queue.begin(); } inline Vertex* PriorityQueue::top () { return _queue.empty() ? NULL : *_queue.begin(); }
inline void PriorityQueue::pop () { _queue.erase(_queue.begin()); }
inline void PriorityQueue::clear () { _queue.clear(); } inline void PriorityQueue::clear () { _queue.clear(); }
inline void PriorityQueue::pop ()
{
cdebug.log(111) << "Pop: (size:" << _queue.size() << ") " << *_queue.begin() << std::endl;
_queue.erase(_queue.begin());
}
inline void PriorityQueue::erase ( Vertex* v )
{
for ( auto ivertex = _queue.begin() ; ivertex != _queue.end() ; ++ivertex ) {
if (*ivertex == v) { _queue.erase( ivertex ); break; }
}
}
inline void PriorityQueue::dump () const inline void PriorityQueue::dump () const
{ {
if (cdebug.enabled(111)) { if (cdebug.enabled(111)) {
@ -187,20 +197,40 @@ namespace Anabatic {
class Dijkstra { class Dijkstra {
public: public:
Dijkstra ( AnabaticEngine* ); // Mode sub-classe.
~Dijkstra (); class Mode : public Hurricane::BaseFlags {
public:
enum Flag { NoMode = 0
, Standart = (1<<0)
, Monotonic = (1<<1)
};
public:
inline Mode ( unsigned int flags=NoMode );
inline Mode ( BaseFlags );
virtual ~Mode ();
virtual std::string _getTypeName () const;
virtual std::string _getString () const;
};
public: public:
void load ( Net* ); float getDistance ( const Vertex*, const Vertex*, const Edge* );
void run (); public:
bool propagate (); Dijkstra ( AnabaticEngine* );
void selectFirstSource (); ~Dijkstra ();
void toWires (); public:
inline bool isBipoint () const;
void load ( Net* );
void run ( Mode mode=Mode::Standart );
private: private:
Dijkstra ( const Dijkstra& ); Dijkstra ( const Dijkstra& );
Dijkstra& operator= ( const Dijkstra& ); Dijkstra& operator= ( const Dijkstra& );
bool _propagate ( Flags enabledSides );
void _selectFirstSource ();
void _toWires ();
private: private:
AnabaticEngine* _anabatic; AnabaticEngine* _anabatic;
vector<Vertex*> _vertexes; vector<Vertex*> _vertexes;
Mode _mode;
Net* _net; Net* _net;
int _stamp; int _stamp;
VertexSet _sources; VertexSet _sources;
@ -211,10 +241,17 @@ namespace Anabatic {
}; };
inline Dijkstra::Mode::Mode ( unsigned int flags ) : BaseFlags(flags) { }
inline Dijkstra::Mode::Mode ( BaseFlags base ) : BaseFlags(base) { }
inline bool Dijkstra::isBipoint () const { return _net and (_targets.size()+_sources.size() == 2); }
} // Anabatic namespace. } // Anabatic namespace.
GETSTRING_POINTER_SUPPORT(Anabatic::Vertex); GETSTRING_POINTER_SUPPORT(Anabatic::Vertex);
IOSTREAM_POINTER_SUPPORT(Anabatic::Vertex); IOSTREAM_POINTER_SUPPORT(Anabatic::Vertex);
INSPECTOR_PV_SUPPORT(Anabatic::Dijkstra::Mode);
#endif // ANABATIC_DIJKSTRA_H #endif // ANABATIC_DIJKSTRA_H

View File

@ -58,7 +58,7 @@ namespace Anabatic {
// Sub-Class: Locator. // Sub-Class: Locator.
class Locator : public EdgesHL { class Locator : public EdgesHL {
public: public:
Locator ( const GCell* gcell ); Locator ( const GCell* gcell, Flags filterFlags );
inline Locator ( const Locator& ); inline Locator ( const Locator& );
virtual Edge* getElement () const; virtual Edge* getElement () const;
virtual EdgesHL* getClone () const; virtual EdgesHL* getClone () const;
@ -67,41 +67,46 @@ namespace Anabatic {
virtual string _getString () const; virtual string _getString () const;
protected: protected:
const GCell* _gcell; const GCell* _gcell;
Flags _flags; Flags _stateFlags;
Flags _filterFlags;
size_t _iedge; size_t _iedge;
}; };
// GCell_Edges. // GCell_Edges.
public: public:
inline GCell_Edges ( const GCell* gcell ); inline GCell_Edges ( const GCell* gcell, Flags filterFlags=Flags::AllSides );
inline GCell_Edges ( const GCell_Edges& ); inline GCell_Edges ( const GCell_Edges& );
virtual EdgesHC* getClone () const; virtual EdgesHC* getClone () const;
virtual EdgesHL* getLocator () const; virtual EdgesHL* getLocator () const;
virtual string _getString () const; virtual string _getString () const;
protected: protected:
const GCell* _gcell; const GCell* _gcell;
Flags _filterFlags;
}; };
inline GCell_Edges::Locator::Locator ( const Locator &locator ) inline GCell_Edges::Locator::Locator ( const Locator &locator )
: EdgesHL() : EdgesHL()
, _gcell(locator._gcell) , _gcell (locator._gcell)
, _flags(locator._flags) , _stateFlags (locator._stateFlags)
, _iedge(locator._iedge) , _filterFlags(locator._filterFlags)
, _iedge (locator._iedge)
{ {
// cdebug.log(110) << "GCell_Edges::Locator::Locator(const Locator&)" << std::endl; // cdebug.log(110) << "GCell_Edges::Locator::Locator(const Locator&)" << std::endl;
} }
inline GCell_Edges::GCell_Edges ( const GCell* gcell ) inline GCell_Edges::GCell_Edges ( const GCell* gcell, Flags filterFlags )
: EdgesHC() : EdgesHC()
, _gcell(gcell) , _gcell (gcell)
, _filterFlags(filterFlags)
{ } { }
inline GCell_Edges::GCell_Edges ( const GCell_Edges& edges ) inline GCell_Edges::GCell_Edges ( const GCell_Edges& edges )
: EdgesHC() : EdgesHC()
, _gcell(edges._gcell) , _gcell (edges._gcell)
, _filterFlags(edges._filterFlags)
{ } { }