53 delete[] chain->
label;
65 candidates =
new RTree<LabelPosition *, double, 2, double>();
66 candidates_sol =
new RTree<LabelPosition *, double, 2, double>();
67 candidates_subsol =
nullptr;
82 qDeleteAll( mLabelPositions );
83 mLabelPositions.clear();
85 delete[] inactiveCost;
88 delete candidates_sol;
90 delete candidates_subsol;
102 return ( reinterpret_cast< SubPart * >( l ) )->borderSize > (
reinterpret_cast< SubPart *
>( r ) )->borderSize;
116 bool *ok =
new bool[nblp];
119 for ( i = 0; i < nblp; i++ )
130 for ( i = 0; i < nbft; i++ )
133 for ( j = 0; j < featNbLp[i]; j++ )
135 if ( !ok[featStartId[i] + j] )
137 if ( mLabelPositions.at( featStartId[i] + j )->getNumOverlaps() == 0 )
140 ok[featStartId[i] + j] =
true;
143 counter += featNbLp[i] - j - 1;
145 for ( k = j + 1; k < featNbLp[i]; k++ )
148 lpid = featStartId[i] + k;
150 lp2 = mLabelPositions.at( lpid );
167 this->nblp -= counter;
182 sol->
s =
new int[nbft];
184 for ( i = 0; i < nbft; i++ )
220 context->
list = list;
243 RTree <LabelPosition *, double, 2, double> *candidates = context->
candidates;
272 context->
list = list;
276 for ( i = 0; i < nbft; i++ )
277 for ( j = 0; j < featNbLp[i]; j++ )
279 label = featStartId[i] + j;
282 list->
insert( label, mLabelPositions.at( label )->getNumOverlaps() );
292 if (
pal->isCanceled() )
302 lp = mLabelPositions.at( label );
304 if ( lp->
getId() != label )
310 sol->
s[probFeatId] = label;
312 for ( i = featStartId[probFeatId]; i < featStartId[probFeatId] + featNbLp[probFeatId]; i++ )
314 ignoreLabel( mLabelPositions.at( i ), list, candidates );
321 candidates->Search( amin, amax,
falpCallback1, reinterpret_cast< void * >( context ) );
322 candidates_sol->Insert( amin, amax, lp );
337 for ( i = 0; i < nbft; i++ )
339 if ( sol->
s[i] == -1 )
341 nbOverlap = std::numeric_limits<int>::max();
342 start_p = featStartId[i];
343 for ( p = 0; p < featNbLp[i]; p++ )
345 lp = mLabelPositions.at( start_p + p );
359 sol->
s[i] = retainedLabel->
getId();
378 bool *ok =
new bool[nbft];
380 int r =
pal->popmusic_r;
384 candidates_subsol =
new RTree<LabelPosition *, double, 2, double>();
392 labelPositionCost =
new double[all_nblp];
393 nbOlap =
new int[all_nblp];
395 featWrap =
new int[nbft];
396 memset( featWrap, -1,
sizeof(
int ) *nbft );
399 int *isIn =
new int[nbft];
401 memset( isIn, 0,
sizeof(
int ) *nbft );
404 for ( i = 0; i < nbft; i++ )
406 parts[i] =
subPart( r, i, isIn );
424 for ( i = ( seed + 1 ) % nbft; ok[i] && i !=
seed; i = ( i + 1 ) % nbft )
427 if ( i == seed && ok[seed] )
435 current = parts[
seed];
439 candidates_subsol->RemoveAll();
441 for ( i = 0; i < current->
subSize; i++ )
443 current->
sol[i] = sol->
s[current->
sub[i]];
444 if ( current->
sol[i] != -1 )
446 mLabelPositions.at( current->
sol[i] )->insertIntoIndex( candidates_subsol );
450 switch ( searchMethod )
478 ok[current->
sub[i]] =
false;
481 for ( i = current->
borderSize; i < current->subSize; i++ )
484 if ( sol->
s[current->
sub[i]] != -1 )
486 mLabelPositions.at( sol->
s[current->
sub[i]] )->removeFromIndex( candidates_sol );
489 sol->
s[current->
sub[i]] = current->
sol[i];
491 if ( current->
sol[i] != -1 )
493 mLabelPositions.at( current->
sol[i] )->insertIntoIndex( candidates_sol );
496 ok[current->
sub[i]] =
false;
507 delete[] labelPositionCost;
510 for ( i = 0; i < nbft; i++ )
512 delete[] parts[i]->
sub;
513 delete[] parts[i]->
sol;
531 int *isIn = context->
isIn;
532 QLinkedList<int> *queue = context->
queue;
548 QLinkedList<int> *queue =
new QLinkedList<int>;
549 QLinkedList<int> *ri =
new QLinkedList<int>;
565 context.
queue = queue;
568 queue->append( featseed );
573 while ( ri->size() < r && !queue->isEmpty() )
575 id = queue->takeFirst();
578 featS = featStartId[id];
581 for ( i = featS; i < featS + p; i++ )
583 lp = mLabelPositions.at( i );
588 candidates->Search( amin, amax,
subPartCallback, reinterpret_cast< void * >( &context ) );
595 sub =
new int[n + nb];
599 while ( !queue->isEmpty() )
601 sub[i] = queue->takeFirst();
606 while ( !ri->isEmpty() )
608 sub[i] = ri->takeFirst();
623 subPart->
seed = featseed;
634 context.
nbOv = nbOverlap;
635 context.
cost = &cost;
645 lp = mLabelPositions.at( label_id );
656 cost = inactiveCost[part->
sub[feat_id]];
672 for ( i = 0; i < part->
subSize; i++ )
694 return ( reinterpret_cast< Triple * >( tl ) )->cost < (
reinterpret_cast< Triple *
>( tr ) )->cost;
698 double candidateBaseFactor,
double *candidateFactor,
699 int minCandidateListSize,
double reductionFactor,
700 int minTabuTSize,
double tabuFactor,
int *tenure,
int n )
703 if ( *candidateFactor > candidateBaseFactor )
704 *candidateFactor /= reductionFactor;
706 if ( iteration % m == 0 )
708 *tenure = minTabuTSize +
static_cast< int >( tabuFactor * nbOverlap );
709 *candidateListSize = minCandidateListSize +
static_cast< int >( *candidateFactor * nbOverlap );
711 if ( *candidateListSize > n )
712 *candidateListSize = n;
719 double *candidateFactor,
int minCandidateListSize,
double growingFactor,
int n )
721 if ( *candidateListSize < n )
722 *candidateFactor = *candidateFactor * growingFactor;
723 *candidateListSize = minCandidateListSize +
static_cast< int >( *candidateFactor * nbOverlap );
725 if ( *candidateListSize > n )
726 *candidateListSize = n;
736 double *labelPositionCost =
nullptr;
737 int *nbOlap =
nullptr;
739 int *featWrap =
nullptr;
758 if ( feat_id >= 0 && ctx->
sol[feat_id] == lp->
getId() )
760 if ( ( feat_id2 = feat_id - ctx->
borderSize ) >= 0 )
778 int *sub = part->
sub;
779 int *sol = part->
sol;
784 int *best_sol =
new int[subSize];
790 int *tabu_list =
new int[probSize];
820 int minTabuTSize = 9;
821 double tabuFactor = 0.5;
823 int minCandidateListSize = 18;
825 double candidateBaseFactor = 0.73;
827 double growingFactor = 15;
828 double reductionFactor = 1.3;
830 int candidateListSize = minCandidateListSize;
831 double candidateFactor = candidateBaseFactor;
837 max_it = probSize *
pal->tabuMaxIt;
838 itwImp = probSize *
pal->tabuMinIt;
846 for ( i = 0; i < subSize; i++ )
847 featWrap[sub[i]] = i;
849 for ( i = 0; i < subSize; i++ )
851 j = featStartId[sub[i]];
852 for ( lp = 0; lp < featNbLp[sub[i]]; lp++ )
859 first_lp = ( displayAll ? 0 : -1 );
860 for ( i = 0; i < probSize; i++ )
865 candidateList[i] =
new Triple();
866 candidateList[i]->
feat_id = i + borderSize;
867 candidateList[i]->
label_id = sol[i + borderSize];
869 candidateListUnsorted[i] = candidateList[i];
871 if ( sol[i + borderSize] >= 0 )
873 j = sol[i + borderSize];
874 candidateList[i]->
cost = labelPositionCost[j];
879 candidateList[i]->
cost = inactiveCost[sub[i + borderSize]];
886 for ( i = 0; i < subSize; i++ )
890 cur_cost += inactiveCost[sub[i]];
894 nbOverlap += nbOlap[sol[i]];
895 cur_cost += labelPositionCost[sol[i]];
901 best_cost = cur_cost;
902 initial_cost = cur_cost;
903 memcpy( best_sol, sol,
sizeof(
int ) * ( subSize ) );
908 while ( it < stop_it && best_cost >=
EPSILON )
910 actualizeTabuCandidateList( m, it, nbOverlap, &candidateListSize, candidateBaseFactor, &candidateFactor, minCandidateListSize, reductionFactor, minTabuTSize, tabuFactor, &tenure, probSize );
911 delta_min = std::numeric_limits<double>::max();
917 for ( i = 0; i < candidateListSize; i++ )
919 feat_id = candidateList[i]->
feat_id;
920 feat_sub_id = sub[feat_id];
921 label_id = candidateList[i]->
label_id;
923 int oldPos = ( label_id < 0 ? -1 : label_id - featStartId[feat_sub_id] );
926 p = featNbLp[feat_sub_id];
930 for ( j = first_lp; j < p; j++ )
935 if ( sol[feat_id] < 0 )
937 delta = -inactiveCost[feat_sub_id];
941 delta = -labelPositionCost[sol[feat_id]];
942 delta -= nbOlap[sol[feat_id]] * ( inactiveCost[feat_sub_id] + mLabelPositions.at( label_id )->cost() );
947 delta += labelPositionCost[featStartId[feat_sub_id] + j];
948 delta += nbOlap[featStartId[feat_sub_id] + j] * ( inactiveCost[feat_sub_id] + mLabelPositions.at( featStartId[feat_sub_id] + j )->cost() );
952 delta += inactiveCost[feat_sub_id];
956 authorized = ( tabu_list[feat_id - borderSize] <= it ) || ( cur_cost + delta < best_cost );
958 if ( delta < delta_min && authorized )
960 choosed_feat = feat_id;
965 choosed_label = featStartId[feat_sub_id] + j;
975 if ( choosed_feat >= 0 )
978 int old_label = sol[choosed_feat];
980 tabu_list[choosed_feat - borderSize] = it + tenure;
981 sol[choosed_feat] = choosed_label;
982 candidateList[candidateId]->
label_id = choosed_label;
984 if ( old_label != -1 )
985 mLabelPositions.at( old_label )->removeFromIndex( candidates_subsol );
988 double local_inactive = inactiveCost[sub[choosed_feat]];
990 if ( choosed_label != -1 )
992 candidateList[candidateId]->
cost = labelPositionCost[choosed_label];
993 candidateList[candidateId]->
nbOverlap = nbOlap[choosed_label];
997 candidateList[candidateId]->
cost = local_inactive;
998 candidateList[candidateId]->
nbOverlap = 1;
1001 cur_cost += delta_min;
1016 if ( old_label >= 0 )
1018 lp = mLabelPositions.at( old_label );
1028 if ( choosed_label >= 0 )
1030 lp = mLabelPositions.at( choosed_label );
1045 if ( best_cost - cur_cost >
EPSILON )
1047 best_cost = cur_cost;
1048 memcpy( best_sol, sol,
sizeof(
int ) * ( subSize ) );
1049 stop_it = it + itwImp;
1050 if ( stop_it > max_it )
1058 &candidateFactor, minCandidateListSize, growingFactor, probSize );
1063 memcpy( sol, best_sol,
sizeof(
int ) * ( subSize ) );
1065 for ( i = 0; i < subSize; i++ )
1066 featWrap[sub[i]] = -1;
1068 for ( i = 0; i < probSize; i++ )
1069 delete candidateList[i];
1071 delete[] candidateList;
1072 delete[] candidateListUnsorted;
1077 return initial_cost - best_cost;
1087 int *tmpsol =
nullptr;
1088 int *featWrap =
nullptr;
1089 int *feat =
nullptr;
1093 double *delta_tmp =
nullptr;
1094 double *inactiveCost =
nullptr;
1106 bool sub =
nullptr != ctx->
featWrap;
1117 if ( feat >= 0 && ctx->
tmpsol[feat] == lp->
getId() )
1119 if ( sub && feat < ctx->borderSize )
1126 QLinkedList< ElemTrans * >::iterator cur;
1129 if ( ( *cur )->feat == feat )
1135 if ( !ctx->
conflicts->contains( feat ) )
1155 int *sub = part->
sub;
1156 int *sol = part->
sol;
1161 double delta_best = std::numeric_limits<double>::max();
1166 Chain *retainedChain =
nullptr;
1168 int max_degree =
pal->ejChainDeg;
1172 QLinkedList<ElemTrans *> *currentChain =
new QLinkedList<ElemTrans *>;
1173 QLinkedList<int> *conflicts =
new QLinkedList<int>;
1175 int *tmpsol =
new int[subSize];
1176 memcpy( tmpsol, sol,
sizeof(
int ) *subSize );
1187 context.
feat =
nullptr;
1193 while ( seed != -1 )
1195 subseed = sub[
seed];
1196 seedNbLp = featNbLp[subseed];
1197 delta_min = std::numeric_limits<double>::max();
1202 if ( tmpsol[seed] == -1 )
1203 delta -= inactiveCost[subseed];
1205 delta -= mLabelPositions.at( tmpsol[seed] )->cost();
1208 for ( i = -1; i < seedNbLp; i++ )
1213 if ( !( tmpsol[seed] == -1 && i == -1 ) && i + featStartId[subseed] != tmpsol[seed] )
1217 lid = featStartId[subseed] + i;
1220 lp = mLabelPositions.at( lid );
1228 candidates_subsol->Search( amin, amax,
chainCallback, reinterpret_cast< void * >( &context ) );
1231 if ( conflicts->isEmpty() )
1233 if ( !retainedChain || delta + lp->
cost() < delta_best )
1236 if ( retainedChain )
1238 delete[] retainedChain->
label;
1239 delete[] retainedChain->
feat;
1243 retainedChain =
new Chain();
1246 delta_best = delta + lp->
cost();
1248 retainedChain->
degree = currentChain->size() + 1;
1249 retainedChain->
feat =
new int[retainedChain->
degree];
1250 retainedChain->
label =
new int[retainedChain->
degree];
1251 QLinkedList< ElemTrans * >::iterator current = currentChain->begin();
1254 while ( current != currentChain->end() )
1257 retainedChain->
feat[j] = move->
feat;
1263 retainedChain->
label[j] = lid;
1264 retainedChain->
delta = delta + mLabelPositions.at( retainedChain->
label[j] )->cost();
1269 else if ( conflicts->size() == 1 )
1271 if ( delta_tmp < delta_min )
1273 delta_min = delta_tmp;
1274 retainedLabel = lid;
1275 next_seed = conflicts->takeFirst();
1279 conflicts->takeFirst();
1287 newChain->
degree = currentChain->size() + 1 + conflicts->size();
1290 QLinkedList<ElemTrans *>::iterator current = currentChain->begin();
1293 while ( current != currentChain->end() )
1303 newChain->
label[j] = lid;
1304 newChain->
delta = delta + mLabelPositions.at( newChain->
label[j] )->cost();
1308 while ( !conflicts->isEmpty() )
1310 int ftid = conflicts->takeFirst();
1311 newChain->
feat[j] = ftid;
1312 newChain->
label[j] = -1;
1313 newChain->
delta += inactiveCost[sub[ftid]];
1317 if ( newChain->
delta < delta_best )
1319 if ( retainedChain )
1322 delta_best = newChain->
delta;
1323 retainedChain = newChain;
1333 if ( !retainedChain || delta + inactiveCost[subseed] < delta_best )
1335 if ( retainedChain )
1337 delete[] retainedChain->
label;
1338 delete[] retainedChain->
feat;
1341 retainedChain =
new Chain();
1343 delta_best = delta + inactiveCost[subseed];
1345 retainedChain->
degree = currentChain->size() + 1;
1346 retainedChain->
feat =
new int[retainedChain->
degree];
1347 retainedChain->
label =
new int[retainedChain->
degree];
1348 QLinkedList<ElemTrans *>::iterator current = currentChain->begin();
1351 while ( current != currentChain->end() )
1354 retainedChain->
feat[j] = move->
feat;
1360 retainedChain->
label[j] = -1;
1361 retainedChain->
delta = delta + inactiveCost[subseed];
1373 if ( next_seed == -1 )
1377 else if ( currentChain->size() > max_degree )
1387 currentChain->append( et );
1391 mLabelPositions.at( et->
old_label )->removeFromIndex( candidates_subsol );
1396 mLabelPositions.at( et->
new_label )->insertIntoIndex( candidates_subsol );
1399 tmpsol[
seed] = retainedLabel;
1400 delta += mLabelPositions.at( retainedLabel )->cost();
1405 while ( !currentChain->isEmpty() )
1407 ElemTrans *et = currentChain->takeFirst();
1411 mLabelPositions.at( et->
new_label )->removeFromIndex( candidates_subsol );
1416 mLabelPositions.at( et->
old_label )->insertIntoIndex( candidates_subsol );
1421 delete currentChain;
1427 return retainedChain;
1431 inline Chain *Problem::chain(
int seed )
1441 double delta_best = std::numeric_limits<double>::max();
1446 Chain *retainedChain =
nullptr;
1448 int max_degree =
pal->ejChainDeg;
1452 QLinkedList<ElemTrans *> *currentChain =
new QLinkedList<ElemTrans *>;
1453 QLinkedList<int> *conflicts =
new QLinkedList<int>;
1455 int *tmpsol =
new int[nbft];
1456 memcpy( tmpsol, sol->s,
sizeof(
int ) *nbft );
1467 context.
feat =
nullptr;
1473 while ( seed != -1 )
1475 seedNbLp = featNbLp[
seed];
1476 delta_min = std::numeric_limits<double>::max();
1482 if ( tmpsol[seed] == -1 )
1483 delta -= inactiveCost[
seed];
1485 delta -= mLabelPositions.at( tmpsol[seed] )->cost();
1487 for ( i = -1; i < seedNbLp; i++ )
1492 if ( !( tmpsol[seed] == -1 && i == -1 ) && i + featStartId[seed] != tmpsol[seed] )
1496 lid = featStartId[
seed] + i;
1499 lp = mLabelPositions.at( lid );
1506 candidates_sol->Search( amin, amax,
chainCallback, reinterpret_cast< void * >( &context ) );
1509 if ( conflicts->isEmpty() )
1511 if ( !retainedChain || delta + lp->
cost() < delta_best )
1513 if ( retainedChain )
1515 delete[] retainedChain->
label;
1516 delete[] retainedChain->
feat;
1520 retainedChain =
new Chain();
1523 delta_best = delta + lp->
cost();
1525 retainedChain->
degree = currentChain->size() + 1;
1526 retainedChain->
feat =
new int[retainedChain->
degree];
1527 retainedChain->
label =
new int[retainedChain->
degree];
1528 QLinkedList<ElemTrans *>::iterator current = currentChain->begin();
1531 while ( current != currentChain->end() )
1534 retainedChain->
feat[j] = move->
feat;
1540 retainedChain->
label[j] = lid;
1541 retainedChain->
delta = delta + lp->
cost();
1546 else if ( conflicts->size() == 1 )
1548 if ( delta_tmp < delta_min )
1550 delta_min = delta_tmp;
1551 retainedLabel = lid;
1552 next_seed = conflicts->takeFirst();
1556 conflicts->takeFirst();
1564 newChain->
degree = currentChain->size() + 1 + conflicts->size();
1567 QLinkedList<ElemTrans *>::iterator current = currentChain->begin();
1571 while ( current != currentChain->end() )
1582 newChain->
label[j] = lid;
1583 newChain->
delta = delta + mLabelPositions.at( newChain->
label[j] )->cost();
1587 while ( !conflicts->isEmpty() )
1589 int ftid = conflicts->takeFirst();
1590 newChain->
feat[j] = ftid;
1591 newChain->
label[j] = -1;
1592 newChain->
delta += inactiveCost[ftid];
1596 if ( newChain->
delta < delta_best )
1598 if ( retainedChain )
1601 delta_best = newChain->
delta;
1602 retainedChain = newChain;
1613 if ( !retainedChain || delta + inactiveCost[seed] < delta_best )
1615 if ( retainedChain )
1617 delete[] retainedChain->
label;
1618 delete[] retainedChain->
feat;
1621 retainedChain =
new Chain();
1623 delta_best = delta + inactiveCost[
seed];
1625 retainedChain->
degree = currentChain->size() + 1;
1626 retainedChain->
feat =
new int[retainedChain->
degree];
1627 retainedChain->
label =
new int[retainedChain->
degree];
1628 QLinkedList<ElemTrans *>::iterator current = currentChain->begin();
1631 while ( current != currentChain->end() )
1634 retainedChain->
feat[j] = move->
feat;
1640 retainedChain->
label[j] = -1;
1641 retainedChain->
delta = delta + inactiveCost[
seed];
1653 if ( next_seed == -1 )
1657 else if ( currentChain->size() > max_degree )
1668 currentChain->append( et );
1672 mLabelPositions.at( et->
old_label )->removeFromIndex( candidates_sol );
1677 mLabelPositions.at( et->
new_label )->insertIntoIndex( candidates_sol );
1681 tmpsol[
seed] = retainedLabel;
1682 delta += mLabelPositions.at( retainedLabel )->cost();
1688 while ( !currentChain->isEmpty() )
1690 ElemTrans *et = currentChain->takeFirst();
1694 mLabelPositions.at( et->
new_label )->removeFromIndex( candidates_sol );
1699 mLabelPositions.at( et->
old_label )->insertIntoIndex( candidates_sol );
1704 delete currentChain;
1710 return retainedChain;
1721 int *sub = part->
sub;
1722 int *sol = part->
sol;
1724 int *best_sol =
new int[subSize];
1726 for ( i = 0; i < subSize; i++ )
1728 featWrap[sub[i]] = i;
1729 best_sol[i] = sol[i];
1732 double initial_cost;
1733 double cur_cost = 0;
1734 double best_cost = 0;
1745 int *tabu_list =
new int[subSize];
1747 Chain *current_chain =
nullptr;
1756 int tenure =
pal->tenure;
1758 for ( i = 0; i < subSize; i++ )
1764 initial_cost = cur_cost;
1765 best_cost = cur_cost;
1769 maxit = probSize *
pal->tabuMaxIt;
1771 itwimp = probSize *
pal->tabuMinIt;
1776 for ( i = 0; i < borderSize; i++ )
1777 tabu_list[i] = maxit;
1779 for ( i = 0; i < probSize; i++ )
1780 tabu_list[i + borderSize] = -1;
1782 while ( it < stop_it )
1784 seed = ( it % probSize ) + borderSize;
1786 current_chain = chain( part, seed );
1787 if ( current_chain )
1792 if ( tabu_list[seed] < it || ( cur_cost + current_chain->
delta ) - best_cost < 0.0 )
1795 for ( i = 0; i < current_chain->
degree; i++ )
1797 fid = current_chain->
feat[i];
1798 lid = current_chain->
label[i];
1800 if ( sol[fid] >= 0 )
1802 mLabelPositions.at( sol[fid] )->removeFromIndex( candidates_subsol );
1806 if ( sol[fid] >= 0 )
1808 mLabelPositions.at( lid )->insertIntoIndex( candidates_subsol );
1811 tabu_list[fid] = it + tenure;
1814 cur_cost += current_chain->
delta;
1817 if ( best_cost - cur_cost >
EPSILON )
1819 best_cost = cur_cost;
1820 memcpy( best_sol, sol,
sizeof(
int ) *subSize );
1822 stop_it = ( it + itwimp > maxit ? maxit : it + itwimp );
1830 memcpy( sol, best_sol,
sizeof(
int ) *subSize );
1850 for ( i = 0; i < subSize; i++ )
1851 featWrap[sub[i]] = -1;
1857 return initial_cost - best_cost;
1867 int *sub = part->
sub;
1868 int *sol = part->
sol;
1870 int *best_sol =
new int[subSize];
1872 for ( i = 0; i < subSize; i++ )
1874 featWrap[sub[i]] = i;
1877 double initial_cost;
1878 double cur_cost = 0;
1879 double best_cost = 0;
1890 int *tabu_list =
new int[subSize];
1892 Chain *retainedChain =
nullptr;
1893 Chain *current_chain =
nullptr;
1902 int tenure =
pal->tenure;
1909 for ( i = 0; i < subSize; i++ )
1915 initial_cost = cur_cost;
1916 best_cost = cur_cost;
1920 maxit = probSize *
pal->tabuMaxIt;
1922 itwimp = probSize *
pal->tabuMinIt;
1926 for ( i = 0; i < borderSize; i++ )
1927 tabu_list[i] = maxit;
1930 for ( i = 0; i < probSize; i++ )
1932 tabu_list[i + borderSize] = -1;
1934 candidates[i] =
new Triple();
1935 candidates[i]->
feat_id = i + borderSize;
1936 candidatesUnsorted[i] = candidates[i];
1938 candidates[i]->
cost = ( sol[i + borderSize] == -1 ? inactiveCost[i + borderSize] : mLabelPositions.at( sol[i + borderSize] )->cost() );
1943 int candidateListSize;
1944 candidateListSize = int (
pal->candListSize * static_cast< double >( probSize ) + 0.5 );
1946 if ( candidateListSize > probSize )
1947 candidateListSize = probSize;
1949 while ( it < stop_it )
1951 retainedChain =
nullptr;
1953 for ( itC = 0; itC < candidateListSize; itC++ )
1955 seed = candidates[itC]->
feat_id;
1957 current_chain = chain( part, seed );
1959 if ( current_chain )
1962 if ( tabu_list[seed] < it || ( cur_cost + current_chain->
delta ) - best_cost < 0.0 )
1964 if ( !retainedChain )
1966 retainedChain = current_chain;
1971 retainedChain = current_chain;
1985 if ( retainedChain )
1987 for ( i = 0; i < retainedChain->
degree; i++ )
1989 fid = retainedChain->
feat[i];
1990 lid = retainedChain->
label[i];
1992 if ( sol[fid] >= 0 )
1993 mLabelPositions.at( sol[fid] )->removeFromIndex( candidates_subsol );
1998 mLabelPositions.at( lid )->insertIntoIndex( candidates_subsol );
2000 tabu_list[fid] = it + tenure;
2001 candidatesUnsorted[fid - borderSize]->
cost = ( lid == -1 ? inactiveCost[sub[fid]] : mLabelPositions.at( lid )->cost() );
2005 cur_cost += retainedChain->
delta;
2009 if ( best_cost - cur_cost >
EPSILON )
2011 best_cost = cur_cost;
2012 memcpy( best_sol, sol,
sizeof(
int ) * subSize );
2014 stop_it = ( it + itwimp > maxit ? maxit : it + itwimp );
2021 memcpy( sol, best_sol,
sizeof(
int ) *subSize );
2023 for ( i = 0; i < probSize; i++ )
2024 delete candidates[i];
2026 delete[] candidates;
2027 delete[] candidatesUnsorted;
2029 for ( i = 0; i < subSize; i++ )
2030 featWrap[sub[i]] = -1;
2036 return initial_cost - best_cost;
2041 QLinkedList<LabelPosition *> *list =
reinterpret_cast< QLinkedList<LabelPosition *>*
>( ctx );
2048 void Problem::check_solution()
2050 int *solution =
new int[nbft];
2060 QLinkedList<LabelPosition *> *list =
new QLinkedList<LabelPosition *>;
2062 candidates_sol->Search( amin, amax,
checkCallback, reinterpret_cast< void * >( list ) );
2066 for ( i = 0; i < nbft; i++ )
2069 if ( sol->s[i] >= 0 )
2073 if ( list->size() != nbActive )
2078 while ( !list->isEmpty() )
2083 solution[probFeatId] = lp->
getId();
2093 int *wrap =
nullptr;
2101 int *wrap = ctx->
wrap;
2126 bool *ok =
new bool[nbft];
2135 context.
wrap =
nullptr;
2137 Chain *retainedChain =
nullptr;
2141 for ( i = 0; i < nbft; i++ )
2159 for ( seed = ( iter + 1 ) % nbft;
2160 ok[
seed] && seed != iter;
2161 seed = ( seed + 1 ) % nbft )
2170 iter = ( iter + 1 ) % nbft;
2171 retainedChain = chain( seed );
2173 if ( retainedChain && retainedChain->
delta < -
EPSILON )
2176 for ( i = 0; i < retainedChain->
degree; i++ )
2178 fid = retainedChain->
feat[i];
2179 lid = retainedChain->
label[i];
2181 if ( sol->s[fid] >= 0 )
2189 candidates->Search( amin, amax,
nokCallback, &context );
2194 if ( sol->s[fid] >= 0 )
2201 sol->cost += retainedChain->
delta;
2225 QList<LabelPosition *> solList;
2232 for ( i = 0; i < nbft; i++ )
2234 if ( sol->s[i] != -1 )
2236 solList.push_back( mLabelPositions.at( sol->s[i] ) );
2238 else if ( returnInactive
2239 || mLabelPositions.at( featStartId[i] )->getFeaturePart()->layer()->displayAll()
2240 || mLabelPositions.at( featStartId[i] )->getFeaturePart()->alwaysShow() )
2242 solList.push_back( mLabelPositions.at( featStartId[i] ) );
2247 if ( returnInactive )
2261 stats->nbObjects = nbft;
2262 stats->nbLabelledObjects = 0;
2264 stats->nbLayers = nbLabelledLayers;
2265 stats->layersNbObjects =
new int[stats->nbLayers];
2266 stats->layersNbLabelledObjects =
new int[stats->nbLayers];
2268 for ( i = 0; i < stats->nbLayers; i++ )
2270 stats->layersName << labelledLayersName[i];
2271 stats->layersNbObjects[i] = 0;
2272 stats->layersNbLabelledObjects[i] = 0;
2277 for ( i = 0; i < nbft; i++ )
2279 lyrName = mLabelPositions.at( featStartId[i] )->getFeaturePart()->feature()->provider()->name();
2281 for ( j = 0; j < stats->nbLayers; j++ )
2283 if ( lyrName == stats->layersName[j] )
2291 stats->layersNbObjects[k]++;
2292 if ( sol->s[i] >= 0 )
2294 stats->layersNbLabelledObjects[k]++;
2295 stats->nbLabelledObjects++;
2307 void Problem::solution_cost()
2318 context.
nbOv = &nbOv;
2319 context.
cost = &sol->cost;
2326 for ( i = 0; i < nbft; i++ )
2328 if ( sol->s[i] == -1 )
2330 sol->
cost += inactiveCost[i];
2336 lp = mLabelPositions.at( sol->s[i] );
bool isInConflict(LabelPosition *ls)
Check whether or not this overlap with another labelPosition.
double popmusic_chain(SubPart *part)
POPMUSIC, chain.
bool borderSizeInc(void *l, void *r)
static bool compareLabelArea(pal::LabelPosition *l1, pal::LabelPosition *l2)
double compute_feature_cost(SubPart *part, int feat_id, int label_id, int *nbOverlap)
int probSize
of features in problem
bool subPartCallback(LabelPosition *lp, void *ctx)
QLinkedList< int > * queue
Thrown when something is added in a Full set.
double cost() const
Returns the candidate label position's geographical cost.
bool chainCallback(LabelPosition *lp, void *context)
Is slower and best than TABU, worse and faster than TABU_CHAIN.
bool checkCallback(LabelPosition *lp, void *ctx)
struct _nokContext NokContext
static bool countFullOverlapCallback(LabelPosition *lp, void *ctx)
struct pal::_elementary_transformation ElemTrans
static bool removeOverlapCallback(LabelPosition *lp, void *ctx)
QLinkedList< ElemTrans * > * currentChain
Is a little bit better than CHAIN but slower.
bool falpCallback1(LabelPosition *lp, void *ctx)
bool updateCandidatesCost(LabelPosition *lp, void *context)
RTree< LabelPosition *, double, 2, double > * candidates
void chain_search()
Test with very-large scale neighborhood.
int getProblemFeatureId() const
SubPart * subPart(int r, int featseed, int *isIn)
void getBoundingBox(double amin[2], double amax[2]) const
Returns bounding box - amin: xmin,ymin - amax: xmax,ymax.
void seed(uint32_t value)
static void sort(void **items, int N, bool(*greater)(void *l, void *r))
Sort an array of pointers.
void insertIntoIndex(RTree< LabelPosition *, double, 2, double > *index)
double popmusic_tabu(SubPart *part)
bool nokCallback(LabelPosition *lp, void *context)
void actualizeTabuCandidateList(int m, int iteration, int nbOverlap, int *candidateListSize, double candidateBaseFactor, double *candidateFactor, int minCandidateListSize, double reductionFactor, int minTabuTSize, double tabuFactor, int *tenure, int n)
void insert(int key, double p)
void popmusic()
popmusic framework
void removeFromIndex(RTree< LabelPosition *, double, 2, double > *index)
double * labelPositionCost
void actualizeCandidateList(int nbOverlap, int *candidateListSize, double, double *candidateFactor, int minCandidateListSize, double growingFactor, int n)
struct pal::_subpart SubPart
int * sub
wrap bw sub feat and main feat
static bool countOverlapCallback(LabelPosition *lp, void *ctx)
double compute_subsolution_cost(SubPart *part, int *s, int *nbOverlap)
void delete_chain(Chain *chain)
QLinkedList< int > * conflicts
int subSize
total # features (prob + border)
Summary statistics of labeling problem.
void ignoreLabel(LabelPosition *lp, PriorityQueue *list, RTree< LabelPosition *, double, 2, double > *candidates)
LabelPosition is a candidate feature label position.
int getNumOverlaps() const
bool decreaseCost(void *tl, void *tr)
bool falpCallback2(LabelPosition *lp, void *ctx)
SearchMethod
Search method to use.
int borderSize
of features bounding the problem
double popmusic_tabu_chain(SubPart *part)
POPMUSIC, Tabu search with chain'.
void init_sol_empty()
Basic initial solution : every feature to -1.
int getId() const
Returns the id.
QList< LabelPosition * > getSolution(bool returnInactive)
int seed
first feat in sub part
void decreaseKey(int key)