53 delete[] chain->
label;
64 candidates =
new RTree<LabelPosition *, double, 2, double>();
65 candidates_sol =
new RTree<LabelPosition *, double, 2, double>();
79 qDeleteAll( mLabelPositions );
80 mLabelPositions.clear();
82 qDeleteAll( mPositionsWithNoCandidates );
84 delete[] inactiveCost;
87 delete candidates_sol;
102 bool *ok =
new bool[nblp];
105 for ( i = 0; i < nblp; i++ )
116 for ( i = 0; i < nbft; i++ )
119 for ( j = 0; j < featNbLp[i]; j++ )
121 if ( !ok[featStartId[i] + j] )
123 if ( mLabelPositions.at( featStartId[i] + j )->getNumOverlaps() == 0 )
126 ok[featStartId[i] + j] =
true;
129 counter += featNbLp[i] - j - 1;
131 for ( k = j + 1; k < featNbLp[i]; k++ )
134 lpid = featStartId[i] + k;
136 lp2 = mLabelPositions.at( lpid );
153 this->nblp -= counter;
168 sol->
s =
new int[nbft];
170 for ( i = 0; i < nbft; i++ )
203 context->
list = list;
226 RTree <LabelPosition *, double, 2, double> *candidates = context->
candidates;
255 context->
list = list;
259 for ( i = 0; i < nbft; i++ )
260 for ( j = 0; j < featNbLp[i]; j++ )
262 label = featStartId[i] + j;
265 list->
insert( label, mLabelPositions.at( label )->getNumOverlaps() );
275 if (
pal->isCanceled() )
285 lp = mLabelPositions.at( label );
287 if ( lp->
getId() != label )
293 sol->
s[probFeatId] = label;
295 for ( i = featStartId[probFeatId]; i < featStartId[probFeatId] + featNbLp[probFeatId]; i++ )
297 ignoreLabel( mLabelPositions.at( i ), list, candidates );
304 candidates->Search( amin, amax,
falpCallback1, reinterpret_cast< void * >( context ) );
305 candidates_sol->Insert( amin, amax, lp );
320 for ( i = 0; i < nbft; i++ )
322 if ( sol->
s[i] == -1 )
324 nbOverlap = std::numeric_limits<int>::max();
325 start_p = featStartId[i];
326 for ( p = 0; p < featNbLp[i]; p++ )
328 lp = mLabelPositions.at( start_p + p );
342 sol->
s[i] = retainedLabel->
getId();
357 int *tmpsol =
nullptr;
358 int *featWrap =
nullptr;
363 double *delta_tmp =
nullptr;
364 double *inactiveCost =
nullptr;
376 bool sub =
nullptr != ctx->
featWrap;
387 if ( feat >= 0 && ctx->
tmpsol[feat] == lp->
getId() )
389 if ( sub && feat < ctx->borderSize )
396 QLinkedList< ElemTrans * >::iterator cur;
399 if ( ( *cur )->feat == feat )
414 inline Chain *Problem::chain(
int seed )
424 double delta_best = std::numeric_limits<double>::max();
429 Chain *retainedChain =
nullptr;
431 int max_degree =
pal->ejChainDeg;
435 QLinkedList<ElemTrans *> *currentChain =
new QLinkedList<ElemTrans *>;
436 QLinkedList<int> *conflicts =
new QLinkedList<int>;
438 int *tmpsol =
new int[nbft];
439 memcpy( tmpsol, sol->
s,
sizeof(
int ) *nbft );
450 context.
feat =
nullptr;
458 seedNbLp = featNbLp[seed];
459 delta_min = std::numeric_limits<double>::max();
465 if ( tmpsol[seed] == -1 )
466 delta -= inactiveCost[seed];
468 delta -= mLabelPositions.at( tmpsol[seed] )->cost();
470 for ( i = -1; i < seedNbLp; i++ )
475 if ( !( tmpsol[seed] == -1 && i == -1 ) && i + featStartId[seed] != tmpsol[seed] )
479 lid = featStartId[seed] + i;
482 lp = mLabelPositions.at( lid );
489 candidates_sol->Search( amin, amax,
chainCallback, reinterpret_cast< void * >( &context ) );
492 if ( conflicts->isEmpty() )
494 if ( !retainedChain || delta + lp->
cost() < delta_best )
498 delete[] retainedChain->
label;
499 delete[] retainedChain->
feat;
503 retainedChain =
new Chain();
506 delta_best = delta + lp->
cost();
508 retainedChain->
degree = currentChain->size() + 1;
509 retainedChain->
feat =
new int[retainedChain->
degree];
510 retainedChain->
label =
new int[retainedChain->
degree];
511 QLinkedList<ElemTrans *>::iterator current = currentChain->begin();
514 while ( current != currentChain->end() )
517 retainedChain->
feat[j] = move->
feat;
522 retainedChain->
feat[j] = seed;
523 retainedChain->
label[j] = lid;
524 retainedChain->
delta = delta + lp->
cost();
529 else if ( conflicts->size() == 1 )
531 if ( delta_tmp < delta_min )
533 delta_min = delta_tmp;
535 next_seed = conflicts->takeFirst();
539 conflicts->takeFirst();
547 newChain->
degree = currentChain->size() + 1 + conflicts->size();
550 QLinkedList<ElemTrans *>::iterator current = currentChain->begin();
554 while ( current != currentChain->end() )
564 newChain->
feat[j] = seed;
565 newChain->
label[j] = lid;
566 newChain->
delta = delta + mLabelPositions.at( newChain->
label[j] )->cost();
570 while ( !conflicts->isEmpty() )
572 int ftid = conflicts->takeFirst();
573 newChain->
feat[j] = ftid;
574 newChain->
label[j] = -1;
575 newChain->
delta += inactiveCost[ftid];
579 if ( newChain->
delta < delta_best )
584 delta_best = newChain->
delta;
585 retainedChain = newChain;
596 if ( !retainedChain || delta + inactiveCost[seed] < delta_best )
600 delete[] retainedChain->
label;
601 delete[] retainedChain->
feat;
604 retainedChain =
new Chain();
606 delta_best = delta + inactiveCost[seed];
608 retainedChain->
degree = currentChain->size() + 1;
609 retainedChain->
feat =
new int[retainedChain->
degree];
610 retainedChain->
label =
new int[retainedChain->
degree];
611 QLinkedList<ElemTrans *>::iterator current = currentChain->begin();
614 while ( current != currentChain->end() )
617 retainedChain->
feat[j] = move->
feat;
622 retainedChain->
feat[j] = seed;
623 retainedChain->
label[j] = -1;
624 retainedChain->
delta = delta + inactiveCost[seed];
636 if ( next_seed == -1 )
640 else if ( currentChain->size() > max_degree )
651 currentChain->append( et );
655 mLabelPositions.at( et->
old_label )->removeFromIndex( candidates_sol );
660 mLabelPositions.at( et->
new_label )->insertIntoIndex( candidates_sol );
664 tmpsol[seed] = retainedLabel;
665 delta += mLabelPositions.at( retainedLabel )->cost();
671 while ( !currentChain->isEmpty() )
673 ElemTrans *et = currentChain->takeFirst();
677 mLabelPositions.at( et->
new_label )->removeFromIndex( candidates_sol );
682 mLabelPositions.at( et->
old_label )->insertIntoIndex( candidates_sol );
693 return retainedChain;
708 int *wrap = ctx->
wrap;
733 bool *ok =
new bool[nbft];
742 context.
wrap =
nullptr;
744 Chain *retainedChain =
nullptr;
746 std::fill( ok, ok + nbft,
false );
761 for ( seed = ( iter + 1 ) % nbft;
762 ok[seed] && seed != iter;
763 seed = ( seed + 1 ) % nbft )
772 iter = ( iter + 1 ) % nbft;
773 retainedChain = chain( seed );
775 if ( retainedChain && retainedChain->
delta < -
EPSILON )
778 for ( i = 0; i < retainedChain->
degree; i++ )
780 fid = retainedChain->
feat[i];
781 lid = retainedChain->
label[i];
783 if ( sol->s[fid] >= 0 )
791 candidates->Search( amin, amax,
nokCallback, &context );
796 if ( sol->s[fid] >= 0 )
803 sol->cost += retainedChain->
delta;
827 QList<LabelPosition *> solList;
829 for ( i = 0; i < nbft; i++ )
831 if ( sol->s[i] != -1 )
833 solList.push_back( mLabelPositions.at( sol->s[i] ) );
835 else if ( returnInactive
836 || mLabelPositions.at( featStartId[i] )->getFeaturePart()->layer()->displayAll()
837 || mLabelPositions.at( featStartId[i] )->getFeaturePart()->alwaysShow() )
839 solList.push_back( mLabelPositions.at( featStartId[i] ) );
841 else if ( unlabeled )
843 unlabeled->push_back( mLabelPositions.at( featStartId[i] ) );
849 unlabeled->append( mPositionsWithNoCandidates );
852 if ( returnInactive )
866 stats->nbObjects = nbft;
867 stats->nbLabelledObjects = 0;
869 stats->nbLayers = nbLabelledLayers;
870 stats->layersNbObjects =
new int[stats->nbLayers];
871 stats->layersNbLabelledObjects =
new int[stats->nbLayers];
873 for ( i = 0; i < stats->nbLayers; i++ )
875 stats->layersName << labelledLayersName[i];
876 stats->layersNbObjects[i] = 0;
877 stats->layersNbLabelledObjects[i] = 0;
882 for ( i = 0; i < nbft; i++ )
884 lyrName = mLabelPositions.at( featStartId[i] )->getFeaturePart()->feature()->provider()->name();
886 for ( j = 0; j < stats->nbLayers; j++ )
888 if ( lyrName == stats->layersName[j] )
896 stats->layersNbObjects[k]++;
897 if ( sol->s[i] >= 0 )
899 stats->layersNbLabelledObjects[k]++;
900 stats->nbLabelledObjects++;
912 void Problem::solution_cost()
922 context.
nbOv = &nbOv;
923 context.
cost = &sol->cost;
930 for ( i = 0; i < nbft; i++ )
932 if ( sol->s[i] == -1 )
934 sol->
cost += inactiveCost[i];
940 lp = mLabelPositions.at( sol->s[i] );
bool isInConflict(LabelPosition *ls)
Check whether or not this overlap with another labelPosition.
static bool compareLabelArea(pal::LabelPosition *l1, pal::LabelPosition *l2)
void getBoundingBox(double amin[2], double amax[2]) const
Returns bounding box - amin: xmin,ymin - amax: xmax,ymax.
Thrown when something is added in a Full set.
bool chainCallback(LabelPosition *lp, void *context)
struct _nokContext NokContext
static bool countFullOverlapCallback(LabelPosition *lp, void *ctx)
int getProblemFeatureId() const
struct pal::_elementary_transformation ElemTrans
static bool removeOverlapCallback(LabelPosition *lp, void *ctx)
QLinkedList< ElemTrans * > * currentChain
bool falpCallback1(LabelPosition *lp, void *ctx)
double cost() const
Returns the candidate label position's geographical cost.
RTree< LabelPosition *, double, 2, double > * candidates
void chain_search()
Test with very-large scale neighborhood.
void insertIntoIndex(RTree< LabelPosition *, double, 2, double > *index)
bool nokCallback(LabelPosition *lp, void *context)
void insert(int key, double p)
void removeFromIndex(RTree< LabelPosition *, double, 2, double > *index)
int getId() const
Returns the id.
static bool countOverlapCallback(LabelPosition *lp, void *ctx)
int getNumOverlaps() const
void delete_chain(Chain *chain)
QLinkedList< int > * conflicts
Summary statistics of labeling problem.
void ignoreLabel(LabelPosition *lp, PriorityQueue *list, RTree< LabelPosition *, double, 2, double > *candidates)
LabelPosition is a candidate feature label position.
bool falpCallback2(LabelPosition *lp, void *ctx)
QList< LabelPosition * > getSolution(bool returnInactive, QList< LabelPosition *> *unlabeled=nullptr)
Solves the labeling problem, selecting the best candidate locations for all labels and returns a list...
void init_sol_empty()
Basic initial solution : every feature to -1.
void decreaseKey(int key)