You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
4.0 KiB
151 lines
4.0 KiB
template <class T> void MRFEnergy<T>::SetAutomaticOrdering() |
|
{ |
|
int dMin; |
|
Node* i; |
|
Node* iMin; |
|
Node* list; |
|
Node* listBoundary; |
|
MRFEdge* e; |
|
|
|
if (m_isEnergyConstructionCompleted) |
|
{ |
|
m_errorFn("Error in SetAutomaticOrdering(): function cannot be called after graph construction is completed"); |
|
} |
|
|
|
printf("Setting automatic ordering... "); |
|
|
|
list = m_nodeFirst; |
|
listBoundary = NULL; |
|
m_nodeFirst = m_nodeLast = NULL; |
|
for (i=list; i; i=i->m_next) |
|
{ |
|
i->m_ordering = 2*m_nodeNum; // will contain remaining degree mod m_nodeNum (i.e. number of edges connecting to nodes in 'listBoundary' and 'list') |
|
// if i->m_ordering \in [2*m_nodeNum; 3*m_nodeNum) - not assigned yet, belongs to 'list' |
|
// if i->m_ordering \in [m_nodeNum; 2*m_nodeNum) - not assigned yet, belongs to 'listBoundary' |
|
// if i->m_ordering \in [0; m_nodeNum ) - assigned, belongs to 'm_nodeFirst' |
|
for (e=i->m_firstForward; e; e=e->m_nextForward) |
|
{ |
|
i->m_ordering ++; |
|
} |
|
for (e=i->m_firstBackward; e; e=e->m_nextBackward) |
|
{ |
|
i->m_ordering ++; |
|
} |
|
} |
|
|
|
while (list) |
|
{ |
|
// find node with the smallest remaining degree in list |
|
dMin = m_nodeNum; |
|
for (i=list; i; i=i->m_next) |
|
{ |
|
assert(i->m_ordering >= 2*m_nodeNum); |
|
if (dMin > i->m_ordering - 2*m_nodeNum) |
|
{ |
|
dMin = i->m_ordering - 2*m_nodeNum; |
|
iMin = i; |
|
} |
|
} |
|
i = iMin; |
|
|
|
// remove i from list |
|
if (i->m_prev) i->m_prev->m_next = i->m_next; |
|
else list = i->m_next; |
|
if (i->m_next) i->m_next->m_prev = i->m_prev; |
|
|
|
// add i to listBoundary |
|
listBoundary = i; |
|
i->m_prev = NULL; |
|
i->m_next = NULL; |
|
i->m_ordering -= m_nodeNum; |
|
|
|
while (listBoundary) |
|
{ |
|
// find node with the smallest remaining degree in listBoundary |
|
dMin = m_nodeNum; |
|
for (i=listBoundary; i; i=i->m_next) |
|
{ |
|
assert(i->m_ordering >= m_nodeNum && i->m_ordering < 2*m_nodeNum); |
|
if (dMin > i->m_ordering - m_nodeNum) |
|
{ |
|
dMin = i->m_ordering - m_nodeNum; |
|
iMin = i; |
|
} |
|
} |
|
i = iMin; |
|
|
|
// remove i from listBoundary |
|
if (i->m_prev) i->m_prev->m_next = i->m_next; |
|
else listBoundary = i->m_next; |
|
if (i->m_next) i->m_next->m_prev = i->m_prev; |
|
|
|
// add i to m_nodeFirst |
|
if (m_nodeLast) |
|
{ |
|
m_nodeLast->m_next = i; |
|
i->m_ordering = m_nodeLast->m_ordering + 1; |
|
} |
|
else |
|
{ |
|
m_nodeFirst = i; |
|
i->m_ordering = 0; |
|
} |
|
i->m_prev = m_nodeLast; |
|
m_nodeLast = i; |
|
i->m_next = NULL; |
|
|
|
// process neighbors of i=m_nodeLast: decrease their remaining degree, |
|
// put them into listBoundary (if they are in list) |
|
for (e=m_nodeLast->m_firstForward; e; e=e->m_nextForward) |
|
{ |
|
assert(m_nodeLast == e->m_tail); |
|
i = e->m_head; |
|
if (i->m_ordering >= m_nodeNum) |
|
{ |
|
i->m_ordering --; // decrease remaining degree of i |
|
if (i->m_ordering >= 2*m_nodeNum) |
|
{ |
|
// remove i from list |
|
if (i->m_prev) i->m_prev->m_next = i->m_next; |
|
else list = i->m_next; |
|
if (i->m_next) i->m_next->m_prev = i->m_prev; |
|
|
|
// add i to listBoundary |
|
if (listBoundary) listBoundary->m_prev = i; |
|
i->m_prev = NULL; |
|
i->m_next = listBoundary; |
|
listBoundary = i; |
|
i->m_ordering -= m_nodeNum; |
|
} |
|
} |
|
} |
|
for (e=m_nodeLast->m_firstBackward; e; e=e->m_nextBackward) |
|
{ |
|
assert(m_nodeLast == e->m_head); |
|
i = e->m_tail; |
|
if (i->m_ordering >= m_nodeNum) |
|
{ |
|
i->m_ordering --; // decrease remaining degree of i |
|
if (i->m_ordering >= 2*m_nodeNum) |
|
{ |
|
// remove i from list |
|
if (i->m_prev) i->m_prev->m_next = i->m_next; |
|
else list = i->m_next; |
|
if (i->m_next) i->m_next->m_prev = i->m_prev; |
|
|
|
// add i to listBoundary |
|
if (listBoundary) listBoundary->m_prev = i; |
|
i->m_prev = NULL; |
|
i->m_next = listBoundary; |
|
listBoundary = i; |
|
i->m_ordering -= m_nodeNum; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
printf("done\n"); |
|
|
|
CompleteGraphConstruction(); |
|
}
|
|
|