34 #define _CRT_SECURE_NO_DEPRECATE
52 #include "linkedlist.hpp"
61 #define UNUSED(x) (void)x;
71 delete[] chain->
label;
76 Problem::Problem() : nbLabelledLayers( 0 ), labelledLayersName( NULL ), nblp( 0 ), all_nblp( 0 ), nbft( 0 ), displayAll( false ),
77 scale( 0 ), labelPositionCost( NULL ), nbOlap( NULL ),
78 labelpositions( NULL ), featStartId( NULL ), featNbLp( NULL ), inactiveCost( NULL ), sol( NULL ), nbActive( 0 ), nbOverlap( 0.0 ),
86 candidates =
new RTree<LabelPosition*, double, 2, double>();
87 candidates_sol =
new RTree<LabelPosition*, double, 2, double>();
88 candidates_subsol = NULL;
106 delete[] featStartId;
110 for ( i = 0; i < nbLabelledLayers; i++ )
111 delete[] labelledLayersName[i];
113 delete[] labelledLayersName;
115 for ( i = 0; i < all_nblp; i++ )
116 delete labelpositions[i];
118 if ( labelpositions )
119 delete[] labelpositions;
122 delete[] inactiveCost;
125 delete candidates_sol;
127 if ( candidates_subsol )
129 delete candidates_subsol;
143 return ((
SubPart* ) l )->borderSize < ((
SubPart* ) r )->borderSize;
148 return ((
SubPart* ) l )->borderSize > ((
SubPart* ) r )->borderSize;
153 return ((
Ft* ) l )->inactiveCost < ((
Ft* ) r )->inactiveCost;
158 return ((
Ft* ) l )->nbOverlap > ((
Ft* ) r )->nbOverlap;
174 bool *ok =
new bool[nblp];
177 for ( i = 0; i < nblp; i++ )
188 for ( i = 0; i < nbft; i++ )
191 for ( j = 0; j < featNbLp[i]; j++ )
193 if ( !ok[featStartId[i] + j] )
195 if ( labelpositions[featStartId[i] + j]->getNumOverlaps() == 0 )
198 ok[featStartId[i] + j] =
true;
201 counter += featNbLp[i] - j - 1;
203 for ( k = j + 1; k < featNbLp[i]; k++ )
206 lpid = featStartId[i] + k;
208 lp2 = labelpositions[lpid];
226 this->nblp -= counter;
228 std::cout <<
"problem reduce to " << nblp <<
" candidates which makes " << nbOverlap <<
" overlaps" << std::endl;
248 sol->
s =
new int[nbft];
250 for ( i = 0; i < nbft; i++ )
285 context->
list = list;
307 RTree <LabelPosition*, double, 2, double> *candidates = ((
FalpContext* ) ctx )->candidates;
324 std::cout <<
"Init solution FALP" << std::endl;
340 context->
list = list;
344 for ( i = 0; i < nbft; i++ )
345 for ( j = 0; j < featNbLp[i]; j++ )
347 label = featStartId[i] + j;
348 list->
insert( label, (
double ) labelpositions[label]->getNumOverlaps() );
363 lp = labelpositions[label];
365 if ( lp->
getId() != label )
367 std::cout <<
"Error: " << lp->
getId() <<
" <--> " << label << std::endl;
371 sol->
s[probFeatId] = label;
374 std::cout <<
"sol->s[" << lp->
probFeat <<
"] :" << label << std::endl;
377 for ( i = featStartId[probFeatId]; i < featStartId[probFeatId] + featNbLp[probFeatId]; i++ )
379 ignoreLabel( labelpositions[i], list, candidates );
387 candidates->Search( amin, amax,
falpCallback1, (
void* ) context );
388 candidates_sol->Insert( amin, amax, lp );
403 for ( i = 0; i < nbft; i++ )
405 if ( sol->
s[i] == -1 )
408 start_p = featStartId[i];
409 for ( p = 0; p < featNbLp[i]; p++ )
411 lp = labelpositions[start_p+p];
425 sol->
s[i] = retainedLabel->
getId();
445 bool *ok =
new bool[nbft];
447 int r = pal->popmusic_r;
451 candidates_subsol =
new RTree<LabelPosition*, double, 2, double>();
458 clock_t start_time = clock();
459 clock_t create_part_time;
460 clock_t init_sol_time;
467 int subPartTotalSize = 0;
470 labelPositionCost =
new double[all_nblp];
471 nbOlap =
new int[all_nblp];
473 featWrap =
new int[nbft];
474 memset( featWrap, -1,
sizeof(
int ) *nbft );
477 int *isIn =
new int[nbft];
479 memset( isIn, 0,
sizeof(
int ) *nbft );
482 for ( i = 0; i < nbft; i++ )
484 parts[i] =
subPart( r, i, isIn );
486 subPartTotalSize += parts[i]->
subSize;
495 create_part_time = clock();
496 std::cout <<
" SubPart (averagesize: " << subPartTotalSize / nbft <<
") creation: " << ( double )( create_part_time - start_time ) / ( double ) CLOCKS_PER_SEC << std::endl;
502 init_sol_time = clock();
503 std::cout <<
" Compute initial solution: " << ( double )( init_sol_time - create_part_time ) / ( double ) CLOCKS_PER_SEC;
509 std::cerr <<
"\t" << sol->
cost <<
"\t" << nbActive <<
"\t" << ( double ) nbActive / (
double ) nbft;
510 std::cout <<
" (solution cost: " << sol->
cost <<
", nbDisplayed: " << nbActive <<
"(" << ( double ) nbActive / (
double ) nbft <<
"%)" << std::endl;
521 for ( i = ( seed + 1 ) % nbft; ok[i] && i !=
seed; i = ( i + 1 ) % nbft )
524 if ( i == seed && ok[seed] )
532 current = parts[
seed];
536 candidates_subsol->RemoveAll();
538 for ( i = 0; i < current->
subSize; i++ )
540 current->
sol[i] = sol->
s[current->
sub[i]];
541 if ( current->
sol[i] != -1 )
549 switch ( searchMethod )
566 std::cerr <<
"Unknown search method..." << std::endl;
579 std::cout <<
"Update solution from subpart, current cost:" << std::endl;
581 std::cout <<
"Delta > EPSILON: update solution" << std::endl;
582 std::cout <<
"after modif cost:" << std::endl;
587 ok[current->
sub[i]] =
false;
590 for ( i = current->
borderSize; i < current->subSize; i++ )
593 if ( sol->
s[current->
sub[i]] != -1 )
598 sol->
s[current->
sub[i]] = current->
sol[i];
600 if ( current->
sol[i] != -1 )
605 ok[current->
sub[i]] =
false;
611 std::cout <<
"subpart not improved" << std::endl;
619 search_time = clock();
620 std::cout <<
" Improved solution: " << ( double )( search_time - start_time ) / ( double ) CLOCKS_PER_SEC <<
" (solution cost: " << sol->
cost <<
", nbDisplayed: " << nbActive <<
" (" << (
double ) nbActive / ( double ) nbft <<
")" << std::endl;
623 std::cerr <<
"\t" << subPartTotalSize;
626 std::cerr <<
"\tpop_tabu\t";
628 std::cerr <<
"\tpop_tabu_chain\t";
630 std::cerr <<
"\tpop_chain\t";
632 std::cerr << r <<
"\t" << popit <<
"\t" << ( create_part_time - start_time ) / (
double ) CLOCKS_PER_SEC <<
"\t" << ( init_sol_time - create_part_time ) / (
double ) CLOCKS_PER_SEC <<
"\t" << ( search_time - init_sol_time ) / (
double ) CLOCKS_PER_SEC <<
"\t" << ( search_time - start_time ) / (
double ) CLOCKS_PER_SEC <<
"\t" << sol->
cost <<
"\t" << nbActive <<
"\t" << ( double ) nbActive / (
double ) nbft;
636 delete[] labelPositionCost;
639 for ( i = 0; i < nbft; i++ )
641 delete[] parts[i]->
sub;
642 delete[] parts[i]->
sol;
669 queue->push_back(
id );
679 LinkedList<int> *queue =
new LinkedList<int> (
intCompare );
680 LinkedList<int> *ri =
new LinkedList<int> (
intCompare );
696 context.
queue = queue;
699 queue->push_back( featseed );
704 while ( ri->size() < r && queue->size() > 0 )
706 id = queue->pop_front();
709 featS = featStartId[id];
712 for ( i = featS; i < featS + p; i++ )
714 lp = labelpositions[i];
730 while ( queue->size() > 0 )
732 sub[i] = queue->pop_front();
737 while ( ri->size() > 0 )
739 sub[i] = ri->pop_front();
754 subPart->
seed = featseed;
768 context.
nbOv = nbOverlap;
769 context.
cost = &cost;
779 lp = labelpositions[label_id];
790 cost = inactiveCost[part->
sub[feat_id]];
806 for ( i = 0; i < part->
subSize; i++ )
828 return ((
Triple* ) tl )->cost < ((
Triple* ) tr )->cost;
833 return ((
Triple* ) tl )->cost > ((
Triple* ) tr )->cost;
839 double candidateBaseFactor,
double *candidateFactor,
840 int minCandidateListSize,
double reductionFactor,
841 int minTabuTSize,
double tabuFactor,
int *tenure,
int n )
844 if ( *candidateFactor > candidateBaseFactor )
845 *candidateFactor /= reductionFactor;
847 if ( iteration % m == 0 )
849 *tenure = minTabuTSize + ( int )( tabuFactor * nbOverlap );
850 *candidateListSize = minCandidateListSize + ( int )( *candidateFactor * nbOverlap );
852 if ( *candidateListSize > n )
853 *candidateListSize = n;
860 double *candidateFactor,
int minCandidateListSize,
double growingFactor,
int n )
863 candidateBaseFactor += 0;
865 if ( *candidateListSize < n )
866 *candidateFactor = *candidateFactor * growingFactor;
867 *candidateListSize = minCandidateListSize + ( int )( *candidateFactor * nbOverlap );
869 if ( *candidateListSize > n )
870 *candidateListSize = n;
902 if ( feat_id >= 0 && ctx->
sol[feat_id] == lp->
getId() )
904 if (( feat_id2 = feat_id - ctx->
borderSize ) >= 0 )
920 std::cout <<
"Subpart: Tabu Search" << std::endl;
926 int *sub = part->
sub;
927 int *sol = part->
sol;
932 int * best_sol =
new int[subSize];
938 int *tabu_list =
new int[probSize];
968 int minTabuTSize = 9;
969 double tabuFactor = 0.5;
971 int minCandidateListSize = 18;
973 double candidateBaseFactor = 0.73;
975 double growingFactor = 15;
976 double reductionFactor = 1.3;
978 int candidateListSize = minCandidateListSize;
979 double candidateFactor = candidateBaseFactor;
985 max_it = probSize * pal->tabuMaxIt;
986 itwImp = probSize * pal->tabuMinIt;
994 for ( i = 0; i < subSize; i++ )
995 featWrap[sub[i]] = i;
997 for ( i = 0; i < subSize; i++ )
999 j = featStartId[sub[i]];
1000 for ( lp = 0; lp < featNbLp[sub[i]]; lp++ )
1010 first_lp = ( displayAll ? 0 : -1 );
1011 for ( i = 0; i < probSize; i++ )
1016 candidateList[i] =
new Triple();
1017 candidateList[i]->
feat_id = i + borderSize;
1018 candidateList[i]->
label_id = sol[i+borderSize];
1020 candidateListUnsorted[i] = candidateList[i];
1022 if ( sol[i+borderSize] >= 0 )
1024 j = sol[i+borderSize];
1025 candidateList[i]->
cost = labelPositionCost[j];
1026 candidateList[i]->
nbOverlap = nbOlap[j];
1030 candidateList[i]->
cost = inactiveCost[sub[i+borderSize]];
1037 for ( i = 0; i < subSize; i++ )
1041 cur_cost += inactiveCost[sub[i]];
1045 nbOverlap += nbOlap[sol[i]];
1046 cur_cost += labelPositionCost[sol[i]];
1052 best_cost = cur_cost;
1053 initial_cost = cur_cost;
1054 memcpy( best_sol, sol,
sizeof(
int ) *( subSize ) );
1059 while ( it < stop_it && best_cost >=
EPSILON )
1062 std::cout <<
" ITERATION : " << it <<
" stop: " << stop_it << std::endl;
1064 actualizeTabuCandidateList( m, it, nbOverlap, &candidateListSize, candidateBaseFactor, &candidateFactor, minCandidateListSize, reductionFactor, minTabuTSize, tabuFactor, &tenure, probSize );
1065 delta_min = DBL_MAX;
1071 for ( i = 0; i < candidateListSize; i++ )
1073 feat_id = candidateList[i]->
feat_id;
1074 feat_sub_id = sub[feat_id];
1075 label_id = candidateList[i]->
label_id;
1077 int oldPos = ( label_id < 0 ? -1 : label_id - featStartId[feat_sub_id] );
1080 p = featNbLp[feat_sub_id];
1084 for ( j = first_lp; j < p; j++ )
1089 if ( sol[feat_id] < 0 )
1091 delta = -inactiveCost[feat_sub_id];
1095 delta = -labelPositionCost[sol[feat_id]];
1096 delta -= nbOlap[sol[feat_id]] * ( inactiveCost[feat_sub_id] + labelpositions[label_id]->
getCost() );
1101 delta += labelPositionCost[featStartId[feat_sub_id] + j];
1102 delta += nbOlap[featStartId[feat_sub_id] + j] * ( inactiveCost[feat_sub_id] + labelpositions[featStartId[feat_sub_id] + j]->
getCost() );
1106 delta += inactiveCost[feat_sub_id];
1110 std::cout <<
" test moving " << oldPos <<
" to " << featStartId[feat_sub_id] + j << std::endl;
1111 std::cout <<
" new pos makes " << nbOlap[featStartId[feat_sub_id] + j] <<
" overlaps" << std::endl;
1112 std::cout <<
" delta is : " << delta << std::endl;
1115 authorized = ( tabu_list[feat_id - borderSize] <= it ) || ( cur_cost + delta < best_cost );
1118 if ( tabu_list[feat_id - borderSize] > it )
1120 std::cout <<
" Move is tabu" << std::endl;
1124 std::cout <<
" Move is ok" << std::endl;
1127 if ( delta < delta_min && authorized )
1130 std::cout <<
" keep move" << std::endl;
1131 std::cout <<
" choosed_feat: " << feat_id << std::endl;
1133 std::cout <<
" choosed_label: " << j << std::endl;
1135 std::cout <<
" choosed_label: " << featStartId[feat_sub_id] + j << std::endl;
1137 std::cout <<
" delta: " << delta << std::endl;
1140 choosed_feat = feat_id;
1145 choosed_label = featStartId[feat_sub_id] + j;
1151 else if ( !authorized )
1153 std::cout <<
" tabu" << std::endl;
1157 std::cout <<
" no good enough" << std::endl;
1165 if ( choosed_feat >= 0 )
1168 std::cout <<
" Apply move:" << std::endl;
1169 std::cout <<
" feat: " << choosed_feat << std::endl;
1170 std::cout <<
" label: " << choosed_label << std::endl;
1171 std::cout <<
" delta: " << delta_min << std::endl << std::endl;
1174 int old_label = sol[choosed_feat];
1176 tabu_list[choosed_feat-borderSize] = it + tenure;
1177 sol[choosed_feat] = choosed_label;
1178 candidateList[candidateId]->
label_id = choosed_label;
1180 if ( old_label != -1 )
1184 double local_inactive = inactiveCost[sub[choosed_feat]];
1186 if ( choosed_label != -1 )
1188 candidateList[candidateId]->
cost = labelPositionCost[choosed_label];
1189 candidateList[candidateId]->
nbOverlap = nbOlap[choosed_label];
1193 candidateList[candidateId]->
cost = local_inactive;
1194 candidateList[candidateId]->
nbOverlap = 1;
1197 cur_cost += delta_min;
1212 if ( old_label >= 0 )
1214 lp = labelpositions[old_label];
1218 context.
diff_cost = -local_inactive - labelpositions[old_label]->
getCost();
1219 context.
lp = labelpositions[old_label];
1224 if ( choosed_label >= 0 )
1226 lp = labelpositions[choosed_label];
1230 context.
diff_cost = local_inactive + labelpositions[choosed_label]->
getCost();
1231 context.
lp = labelpositions[choosed_label];
1241 if ( best_cost - cur_cost >
EPSILON )
1243 best_cost = cur_cost;
1244 memcpy( best_sol, sol,
sizeof(
int ) *( subSize ) );
1245 stop_it = it + itwImp;
1246 if ( stop_it > max_it )
1254 &candidateFactor, minCandidateListSize, growingFactor, probSize );
1257 std::cout <<
"cost : " << cur_cost << std::endl;
1260 std::cout <<
"best_cost: " << best_cost << std::endl << std::endl;
1265 memcpy( sol, best_sol,
sizeof(
int ) *( subSize ) );
1267 for ( i = 0; i < subSize; i++ )
1268 featWrap[sub[i]] = -1;
1270 for ( i = 0; i < probSize; i++ )
1271 delete candidateList[i];
1273 delete[] candidateList;
1274 delete[] candidateListUnsorted;
1279 return initial_cost - best_cost;
1307 std::cout <<
"chainCallback" << std::endl;
1308 std::cout <<
" lp from rtree: " << lp << std::endl;
1309 std::cout <<
" lpid from rtree: " << lp->
id << std::endl;
1310 std::cout <<
" lpco from rtree: " << lp->
cost << std::endl;
1311 std::cout <<
" lp from context: " << ctx->
lp << std::endl;
1312 std::cout <<
" lpid from context: " << ctx->
lp->
id << std::endl;
1313 std::cout <<
" lpco from context: " << ctx->
lp->
cost << std::endl;
1314 std::cout <<
" delta_tmp: " << ctx->
delta_tmp << std::endl;
1315 std::cout <<
" *delta_tmp: " << *ctx->
delta_tmp << std::endl;
1316 std::cout <<
" inactiveCost: " << ctx->
inactiveCost << std::endl;
1320 std::cout <<
"ejChCallBack: " << lp->
id <<
"<->" << ctx->
lp->
id << std::endl;
1325 std::cout <<
"ejChCallBack: " << lp->
id <<
"<->" << ctx->
lp->
id << std::endl;
1326 std::cout <<
" Conflictual..." << std::endl;
1341 std::cout <<
" feat: " << feat << std::endl;
1342 std::cout <<
" sol: " << ctx->
tmpsol[feat] <<
"/" << lp->
id << std::endl;
1343 std::cout <<
" border:" << ctx->
borderSize << std::endl;
1345 if ( feat >= 0 && ctx->
tmpsol[feat] == lp->
getId() )
1347 if ( sub && feat < ctx->borderSize )
1350 std::cout <<
" Cannot touch border (throw) !" << std::endl;
1361 if ( cur->item->feat == feat )
1364 std::cout <<
"Cycle into chain (throw) !" << std::endl;
1389 int borderSize = part->borderSize;
1390 int subSize = part->subSize;
1391 int *sub = part->sub;
1392 int *sol = part->sol;
1397 double delta_best = DBL_MAX;
1402 Chain *retainedChain = NULL;
1404 int max_degree = pal->ejChainDeg;
1408 LinkedList<ElemTrans*> *currentChain =
new LinkedList<ElemTrans*> (
ptrETCompare );
1409 LinkedList<int> *conflicts =
new LinkedList<int> (
intCompare );
1411 int *tmpsol =
new int[subSize];
1412 memcpy( tmpsol, sol,
sizeof(
int ) *subSize );
1418 ChainContext context;
1419 context.featWrap = featWrap;
1420 context.borderSize = borderSize;
1421 context.tmpsol = tmpsol;
1422 context.inactiveCost = inactiveCost;
1423 context.feat = NULL;
1424 context.currentChain = currentChain;
1425 context.conflicts = conflicts;
1426 context.delta_tmp = &delta_tmp;
1429 while ( seed != -1 )
1431 subseed = sub[
seed];
1432 seedNbLp = featNbLp[subseed];
1433 delta_min = DBL_MAX;
1435 std::cout <<
"New seed: " << seed <<
"/" << subseed << std::endl;
1441 if ( tmpsol[seed] == -1 )
1442 delta -= inactiveCost[subseed];
1447 for ( i = -1; i < seedNbLp; i++ )
1452 if ( !( tmpsol[seed] == -1 && i == -1 ) && i + featStartId[subseed] != tmpsol[seed] )
1456 lid = featStartId[subseed] + i;
1459 lp = labelpositions[lid];
1466 if ( conflicts->size() != 0 )
1467 std::cerr <<
"Conflicts not empty !!" << std::endl;
1470 candidates_subsol->Search( amin, amax,
chainCallback, (
void* ) &context );
1473 std::cout <<
"Conflicts:" << conflicts->size() << std::endl;
1476 if ( conflicts->size() == 0 )
1478 if ( !retainedChain || delta + labelpositions[lid]->getCost() < delta_best )
1481 if ( retainedChain )
1483 delete[] retainedChain->label;
1484 delete[] retainedChain->feat;
1488 retainedChain =
new Chain();
1491 delta_best = delta + labelpositions[lid]->
getCost();
1493 retainedChain->degree = currentChain->size() + 1;
1494 retainedChain->feat =
new int[retainedChain->degree];
1495 retainedChain->label =
new int[retainedChain->degree];
1496 Cell<ElemTrans*> *current = currentChain->getFirst();
1501 move = current->item;
1502 retainedChain->
feat[j] = move->feat;
1503 retainedChain->label[j] = move->new_label;
1504 current = current->next;
1507 retainedChain->feat[j] =
seed;
1508 retainedChain->label[j] = lid;
1509 retainedChain->delta = delta + labelpositions[retainedChain->label[j]]->
getCost();
1514 else if ( conflicts->size() == 1 )
1516 if ( delta_tmp < delta_min )
1518 delta_min = delta_tmp;
1519 retainedLabel = lid;
1520 next_seed = conflicts->pop_front();
1524 conflicts->pop_front();
1532 newChain->degree = currentChain->size() + 1 + conflicts->size();
1533 newChain->feat =
new int[newChain->degree];
1534 newChain->label =
new int[newChain->degree];
1535 Cell<ElemTrans*> *current = currentChain->getFirst();
1540 move = current->item;
1541 newChain->
feat[j] = move->feat;
1542 newChain->label[j] = move->new_label;
1543 current = current->next;
1547 newChain->feat[j] =
seed;
1548 newChain->label[j] = lid;
1549 newChain->delta = delta + labelpositions[newChain->label[j]]->
getCost();
1553 while ( conflicts->size() > 0 )
1555 int ftid = conflicts->pop_front();
1556 newChain->feat[j] = ftid;
1557 newChain->label[j] = -1;
1558 newChain->delta += inactiveCost[sub[ftid]];
1562 if ( newChain->delta < delta_best )
1564 if ( retainedChain )
1567 delta_best = newChain->delta;
1568 retainedChain = newChain;
1578 if ( !retainedChain || delta + inactiveCost[subseed] < delta_best )
1580 if ( retainedChain )
1582 delete[] retainedChain->label;
1583 delete[] retainedChain->feat;
1586 retainedChain =
new Chain();
1588 delta_best = delta + inactiveCost[subseed];
1590 retainedChain->degree = currentChain->size() + 1;
1591 retainedChain->feat =
new int[retainedChain->degree];
1592 retainedChain->label =
new int[retainedChain->degree];
1593 Cell<ElemTrans*> *current = currentChain->getFirst();
1598 move = current->item;
1599 retainedChain->
feat[j] = move->feat;
1600 retainedChain->label[j] = move->new_label;
1601 current = current->next;
1604 retainedChain->feat[j] =
seed;
1605 retainedChain->label[j] = -1;
1606 retainedChain->delta = delta + inactiveCost[subseed];
1614 std::cout <<
"catch int " << i << std::endl;
1618 while ( conflicts->size() > 0 )
1619 conflicts->pop_front();
1623 if ( next_seed == -1 )
1627 else if ( currentChain->size() > max_degree )
1630 std::cout <<
"Max degree reached !! (" << max_degree <<
")" << std::endl;
1638 et->old_label = tmpsol[
seed];
1639 et->new_label = retainedLabel;
1640 currentChain->push_back( et );
1642 if ( et->old_label != -1 )
1647 if ( et->new_label != -1 )
1652 tmpsol[
seed] = retainedLabel;
1653 delta += labelpositions[retainedLabel]->
getCost();
1658 while ( currentChain->size() > 0 )
1660 ElemTrans* et = currentChain->pop_front();
1662 if ( et->new_label != -1 )
1667 if ( et->old_label != -1 )
1674 delete currentChain;
1680 return retainedChain;
1684 inline Chain *Problem::chain(
int seed )
1694 double delta_best = DBL_MAX;
1699 Chain *retainedChain = NULL;
1701 int max_degree = pal->ejChainDeg;
1705 LinkedList<ElemTrans*> *currentChain =
new LinkedList<ElemTrans*> (
ptrETCompare );
1706 LinkedList<int> *conflicts =
new LinkedList<int> (
intCompare );
1708 int *tmpsol =
new int[nbft];
1709 memcpy( tmpsol, sol->s,
sizeof(
int ) *nbft );
1715 ChainContext context;
1716 context.featWrap = NULL;
1717 context.borderSize = 0;
1718 context.tmpsol = tmpsol;
1719 context.inactiveCost = inactiveCost;
1720 context.feat = NULL;
1721 context.currentChain = currentChain;
1722 context.conflicts = conflicts;
1723 context.delta_tmp = &delta_tmp;
1726 while ( seed != -1 )
1728 seedNbLp = featNbLp[
seed];
1729 delta_min = DBL_MAX;
1735 if ( tmpsol[seed] == -1 )
1736 delta -= inactiveCost[
seed];
1740 for ( i = -1; i < seedNbLp; i++ )
1745 if ( !( tmpsol[seed] == -1 && i == -1 ) && i + featStartId[seed] != tmpsol[seed] )
1749 lid = featStartId[
seed] + i;
1752 lp = labelpositions[lid];
1758 if ( conflicts->size() != 0 )
1759 std::cerr <<
"Conflicts not empty" << std::endl;
1761 candidates_sol->Search( amin, amax,
chainCallback, (
void* ) &context );
1764 if ( conflicts->size() == 0 )
1766 if ( !retainedChain || delta + labelpositions[lid]->getCost() < delta_best )
1768 if ( retainedChain )
1770 delete[] retainedChain->label;
1771 delete[] retainedChain->feat;
1775 retainedChain =
new Chain();
1778 delta_best = delta + labelpositions[lid]->
getCost();
1780 retainedChain->degree = currentChain->size() + 1;
1781 retainedChain->feat =
new int[retainedChain->degree];
1782 retainedChain->label =
new int[retainedChain->degree];
1783 Cell<ElemTrans*> *current = currentChain->getFirst();
1788 move = current->item;
1789 retainedChain->
feat[j] = move->feat;
1790 retainedChain->label[j] = move->new_label;
1791 current = current->next;
1794 retainedChain->feat[j] =
seed;
1795 retainedChain->label[j] = lid;
1796 retainedChain->delta = delta + labelpositions[lid]->
getCost();
1801 else if ( conflicts->size() == 1 )
1803 if ( delta_tmp < delta_min )
1805 delta_min = delta_tmp;
1806 retainedLabel = lid;
1807 next_seed = conflicts->pop_front();
1811 conflicts->pop_front();
1819 newChain->degree = currentChain->size() + 1 + conflicts->size();
1820 newChain->feat =
new int[newChain->degree];
1821 newChain->label =
new int[newChain->degree];
1822 Cell<ElemTrans*> *current = currentChain->getFirst();
1828 move = current->item;
1829 newChain->
feat[j] = move->feat;
1830 newChain->label[j] = move->new_label;
1831 current = current->next;
1836 newChain->feat[j] =
seed;
1837 newChain->label[j] = lid;
1838 newChain->delta = delta + labelpositions[newChain->label[j]]->
getCost();
1842 while ( conflicts->size() > 0 )
1844 int ftid = conflicts->pop_front();
1845 newChain->feat[j] = ftid;
1846 newChain->label[j] = -1;
1847 newChain->delta += inactiveCost[ftid];
1851 if ( newChain->delta < delta_best )
1853 if ( retainedChain )
1856 delta_best = newChain->delta;
1857 retainedChain = newChain;
1868 if ( !retainedChain || delta + inactiveCost[seed] < delta_best )
1870 if ( retainedChain )
1872 delete[] retainedChain->label;
1873 delete[] retainedChain->feat;
1876 retainedChain =
new Chain();
1878 delta_best = delta + inactiveCost[
seed];
1880 retainedChain->degree = currentChain->size() + 1;
1881 retainedChain->feat =
new int[retainedChain->degree];
1882 retainedChain->label =
new int[retainedChain->degree];
1883 Cell<ElemTrans*> *current = currentChain->getFirst();
1888 move = current->item;
1889 retainedChain->
feat[j] = move->feat;
1890 retainedChain->label[j] = move->new_label;
1891 current = current->next;
1894 retainedChain->feat[j] =
seed;
1895 retainedChain->label[j] = -1;
1896 retainedChain->delta = delta + inactiveCost[
seed];
1904 std::cout <<
"catch Cycle in chain" << std::endl;
1908 while ( conflicts->size() > 0 )
1909 conflicts->pop_front();
1913 if ( next_seed == -1 )
1917 else if ( currentChain->size() > max_degree )
1919 std::cout <<
"Max degree reached !! (" << max_degree <<
")" << std::endl;
1926 et->old_label = tmpsol[
seed];
1927 et->new_label = retainedLabel;
1928 currentChain->push_back( et );
1930 if ( et->old_label != -1 )
1935 if ( et->new_label != -1 )
1941 tmpsol[
seed] = retainedLabel;
1942 delta += labelpositions[retainedLabel]->
getCost();
1948 while ( currentChain->size() > 0 )
1950 ElemTrans* et = currentChain->pop_front();
1952 if ( et->new_label != -1 )
1957 if ( et->old_label != -1 )
1964 delete currentChain;
1970 return retainedChain;
1985 int *sub = part->
sub;
1986 int *sol = part->
sol;
1988 int *best_sol =
new int[subSize];
1990 for ( i = 0; i < subSize; i++ )
1992 featWrap[sub[i]] = i;
1993 best_sol[i] = sol[i];
1996 double initial_cost;
1997 double cur_cost = 0;
1998 double best_cost = 0;
2009 int *tabu_list =
new int[subSize];
2011 Chain *current_chain = NULL;
2020 int tenure = pal->tenure;
2022 for ( i = 0; i < subSize; i++ )
2028 initial_cost = cur_cost;
2029 best_cost = cur_cost;
2033 maxit = probSize * pal->tabuMaxIt;
2035 itwimp = probSize * pal->tabuMinIt;;
2040 for ( i = 0; i < borderSize; i++ )
2041 tabu_list[i] = maxit;
2043 for ( i = 0; i < probSize; i++ )
2044 tabu_list[i+borderSize] = -1;
2046 while ( it < stop_it )
2048 seed = ( it % probSize ) + borderSize;
2050 current_chain = chain( part, seed );
2051 if ( current_chain )
2056 if ( tabu_list[seed] < it || ( cur_cost + current_chain->
delta ) - best_cost < 0.0 )
2059 for ( i = 0; i < current_chain->
degree; i++ )
2061 fid = current_chain->
feat[i];
2062 lid = current_chain->
label[i];
2064 if ( sol[fid] >= 0 )
2070 if ( sol[fid] >= 0 )
2075 tabu_list[fid] = it + tenure;
2078 cur_cost += current_chain->
delta;
2080 std::cout <<
"cur->cost: " << cur_cost << std::endl;
2085 if ( best_cost - cur_cost >
EPSILON )
2087 best_cost = cur_cost;
2088 memcpy( best_sol, sol,
sizeof(
int ) *subSize );
2090 stop_it = ( it + itwimp > maxit ? maxit : it + itwimp );
2098 memcpy( sol, best_sol,
sizeof(
int ) *subSize );
2118 for ( i = 0; i < subSize; i++ )
2119 featWrap[sub[i]] = -1;
2125 return initial_cost - best_cost;
2143 int *sub = part->
sub;
2144 int *sol = part->
sol;
2146 int *best_sol =
new int[subSize];
2148 for ( i = 0; i < subSize; i++ )
2150 featWrap[sub[i]] = i;
2153 double initial_cost;
2154 double cur_cost = 0;
2155 double best_cost = 0;
2166 int *tabu_list =
new int[subSize];
2168 Chain *retainedChain = NULL;
2169 Chain *current_chain = NULL;
2178 int tenure = pal->tenure;
2185 LinkedList<int> *conflicts =
new LinkedList<int> (
intCompare );
2187 for ( i = 0; i < subSize; i++ )
2193 initial_cost = cur_cost;
2194 best_cost = cur_cost;
2198 maxit = probSize * pal->tabuMaxIt;
2200 itwimp = probSize * pal->tabuMinIt;
2204 for ( i = 0; i < borderSize; i++ )
2205 tabu_list[i] = maxit;
2208 for ( i = 0; i < probSize; i++ )
2210 tabu_list[i+borderSize] = -1;
2212 candidates[i] =
new Triple();
2213 candidates[i]->
feat_id = i + borderSize;
2214 candidatesUnsorted[i] = candidates[i];
2216 candidates[i]->
cost = ( sol[i+borderSize] == -1 ? inactiveCost[i+borderSize] : labelpositions[sol[i+borderSize]]->
getCost() );
2221 int candidateListSize;
2222 candidateListSize = int ( pal->candListSize * (
double ) probSize + 0.5 );
2224 if ( candidateListSize > probSize )
2225 candidateListSize = probSize;
2229 std::cout << std::endl <<
"Initial solution cost " << cur_cost << std::endl;
2231 std::cout <<
"NbOverlap: " << nbOv << std::endl;
2233 while ( it < stop_it )
2235 retainedChain = NULL;
2238 std::cout << std::endl << std::endl << candidateListSize << std::endl;
2240 for ( itC = 0; itC < candidateListSize; itC++ )
2242 seed = candidates[itC]->
feat_id;
2245 std::cout <<
"new candidates:" << std::endl;
2247 current_chain = chain( part, seed );
2250 std::cout <<
"get chain:" << current_chain << std::endl;
2252 if ( current_chain )
2255 if ( tabu_list[seed] < it || ( cur_cost + current_chain->
delta ) - best_cost < 0.0 )
2257 if ( !retainedChain )
2259 retainedChain = current_chain;
2261 std::cout <<
"New chain, delta = " << current_chain->
delta << std::endl;
2267 retainedChain = current_chain;
2269 std::cout <<
"New best chain, delta = " << current_chain->
delta << std::endl;
2275 std::cout <<
"chain rejected..." << std::endl;
2283 std::cout <<
"chain rejected, tabu and/or delta = " << current_chain->
delta << std::endl;
2291 std::cout <<
"no chain !!" << std::endl;
2297 if ( retainedChain )
2300 std::cout << it <<
" retained chain's degree: " << retainedChain->
degree;
2301 std::cout <<
" and delta: " << retainedChain->
delta << std::endl;
2304 for ( i = 0; i < retainedChain->
degree; i++ )
2306 fid = retainedChain->
feat[i];
2307 lid = retainedChain->
label[i];
2309 std::cout << fid <<
": " << sol[fid] <<
" -> " << lid <<
" Costs: " << inactiveCost[fid] <<
":" << ( sol[fid] != -1 ? labelpositions[sol[fid]]->
cost : -1 ) <<
":" << ( lid != -1 ? labelpositions[lid]->cost : -1 ) << std::endl;
2312 if ( sol[fid] >= 0 )
2320 tabu_list[fid] = it + tenure;
2322 std::cout <<
"fid: " << fid << std::endl;
2323 std::cout <<
"borderSize: " << borderSize << std::endl;
2324 std::cout <<
"lid: " << lid << std::endl;
2325 std::cout <<
"sub[fid]: " << sub[fid] << std::endl;
2326 std::cout <<
"inactivecosr[sub[fid]]: " << inactiveCost[sub[fid]] << std::endl;
2329 std::cout <<
"label[lid]: " << labelpositions[lid] << std::endl;
2330 std::cout <<
"label[lid]->cost: " << labelpositions[lid]->
cost << std::endl;
2333 candidatesUnsorted[fid-borderSize]->
cost = ( lid == -1 ? inactiveCost[sub[fid]] : labelpositions[lid]->
getCost() );
2338 std::cout << std::endl;
2343 cur_cost += retainedChain->
delta;
2352 if ( best_cost - cur_cost >
EPSILON )
2355 std::cout <<
"new_best" << std::endl;
2357 best_cost = cur_cost;
2358 memcpy( best_sol, sol,
sizeof(
int ) * subSize );
2360 stop_it = ( it + itwimp > maxit ? maxit : it + itwimp );
2369 std::cout << it <<
" no chain" << std::endl << std::endl;
2375 memcpy( sol, best_sol,
sizeof(
int ) *subSize );
2379 for ( i = 0; i < probSize; i++ )
2380 delete candidates[i];
2382 delete[] candidates;
2383 delete[] candidatesUnsorted;
2385 for ( i = 0; i < subSize; i++ )
2386 featWrap[sub[i]] = -1;
2392 return initial_cost - best_cost;
2397 LinkedList<LabelPosition*> *list = ( LinkedList<LabelPosition*>* ) ctx;
2398 list->push_back( lp );
2404 void Problem::check_solution()
2406 int *solution =
new int[nbft];
2416 LinkedList<LabelPosition*> *list =
new LinkedList<LabelPosition*> (
ptrLPosCompare );
2418 candidates_sol->Search( amin, amax,
checkCallback, (
void* ) list );
2420 std::cerr <<
"Check Solution" << std::endl;
2424 for ( i = 0; i < nbft; i++ )
2427 if ( sol->s[i] >= 0 )
2431 if ( list->size() != nbActive )
2433 std::cerr <<
"Error in solution !!!!" << std::endl;
2436 while ( list->size() > 0 )
2438 LabelPosition *lp = list->pop_front();
2439 int probFeatId = lp->getProblemFeatureId();
2440 if ( solution[probFeatId] >= 0 )
2442 std::cerr <<
"Doublon : " << probFeatId <<
" "
2443 << solution[probFeatId] <<
"<->"
2444 << lp->getId() << std::endl;
2447 solution[probFeatId] = lp->getId();
2451 for ( i = 0; i < nbft; i++ )
2453 if ( solution[i] != sol->s[i] )
2455 std::cerr <<
"Feat " << i <<
" : " << solution[i] <<
"<-->" << sol->s[i] << std::endl;
2474 int *wrap = ((
NokContext* ) context )->wrap;
2497 int *best_sol =
new int[nbft];
2499 double initial_cost;
2500 double cur_cost = 0;
2501 double best_cost = 0;
2512 int *tabu_list =
new int[nbft];
2514 Chain *current_chain = NULL;
2521 int tenure = pal->tenure;
2525 clock_t start_time = clock();
2526 clock_t init_sol_time;
2527 clock_t search_time;
2534 std::cout <<
" Compute initial solution: " << ( double )(( init_sol_time = clock() ) - start_time ) / (
double ) CLOCKS_PER_SEC;
2540 std::cerr <<
"\t" << sol->cost <<
"\t" << nbActive <<
"\t" << ( double ) nbActive / (
double ) nbft;
2541 std::cout << " (solution cost: " << sol->cost << ", nbDisplayed: " << nbActive << "(" <<
double( nbActive ) / nbft << "%)" << std::endl;
2544 cur_cost = sol->cost;
2546 initial_cost = cur_cost;
2548 best_cost = cur_cost;
2550 memcpy( best_sol, sol->s,
sizeof(
int ) *nbft );
2554 maxit = nbft * pal->tabuMaxIt;
2556 itwimp = nbft * pal->tabuMinIt;;
2560 for ( i = 0; i < nbft; i++ )
2563 while ( it < stop_it )
2565 seed = ( it % nbft );
2567 if (( current_chain = chain( seed ) ) )
2572 if ( tabu_list[seed] < it || ( cur_cost + current_chain->delta ) - best_cost < -
EPSILON )
2575 for ( i = 0; i < current_chain->degree; i++ )
2577 fid = current_chain->feat[i];
2578 lid = current_chain->label[i];
2580 if ( sol->s[fid] >= 0 )
2586 if ( sol->s[fid] >= 0 )
2591 tabu_list[fid] = it + tenure;
2594 cur_cost += current_chain->delta;
2597 std::cout <<
"cur->cost: " << cur_cost << std::endl;
2599 std::cout <<
"computed cost: " << sol->cost << std::endl << std::endl;
2604 if ( best_cost - cur_cost >
EPSILON )
2608 best_cost = cur_cost;
2609 memcpy( best_sol, sol->s,
sizeof(
int ) *nbft );
2611 stop_it = ( it + itwimp > maxit ? maxit : it + itwimp );
2619 memcpy( sol->s, best_sol,
sizeof(
int ) *nbft );
2621 candidates_sol->RemoveAll();
2622 for ( i = 0; i < nbft; i++ )
2623 if ( sol->s[i] != -1 )
2626 std::cout <<
"Cost : " << cur_cost << std::endl;
2631 std::cout <<
" Improved solution: " << ( double )(( search_time = clock() ) - start_time ) / (
double ) CLOCKS_PER_SEC << " (solution cost: " << sol->cost << ", nbDisplayed: " << nbActive << " (" << (
double ) nbActive / (
double ) nbft << "%)" << std::endl;
2633 std::cerr << "\tna\tchain" << "\tna\t" << it << "\tna\t" << ( init_sol_time - start_time ) / (
double ) CLOCKS_PER_SEC << "\t" << ( search_time - init_sol_time ) / (
double ) CLOCKS_PER_SEC << "\t" << ( search_time - start_time ) / (
double ) CLOCKS_PER_SEC << "\t" << sol->cost << "\t" << nbActive << "\t" << (
double ) nbActive / (
double ) nbft;
2652 bool *ok =
new bool[nbft];
2658 clock_t start_time = clock();
2659 clock_t init_sol_time;
2660 clock_t search_time;
2671 context.
wrap = NULL;
2673 Chain *retainedChain;
2677 for ( i = 0; i < nbft; i++ )
2688 std::cout <<
" Compute initial solution: " << ( double )(( init_sol_time = clock() ) - start_time ) / (
double ) CLOCKS_PER_SEC;
2695 std::cerr <<
"\t" << sol->cost <<
"\t" << nbActive <<
"\t" << ( double ) nbActive / (
double ) nbft;
2696 std::cout <<
" (solution cost: " << sol->cost <<
", nbDisplayed: " << nbActive <<
"(" << double( nbActive ) / nbft <<
"%)" << std::endl;
2705 for ( seed = ( iter + 1 ) % nbft;
2706 ok[
seed] && seed != iter;
2707 seed = ( seed + 1 ) % nbft )
2716 iter = ( iter + 1 ) % nbft;
2719 std::cout <<
"Seed for it " << popit <<
" is " << seed << std::endl;
2722 retainedChain = chain( seed );
2724 if ( retainedChain && retainedChain->
delta < -
EPSILON )
2727 std::cout <<
"chain's degree & delta : " << retainedChain->
degree <<
" " << retainedChain->
delta << std::endl;
2730 for ( i = 0; i < retainedChain->
degree; i++ )
2732 fid = retainedChain->
feat[i];
2733 lid = retainedChain->
label[i];
2735 std::cout <<
" " << i <<
" :" << fid <<
" " << lid << std::endl;
2736 std::cout <<
" sol->s[fid]: " << sol->s[fid] <<
" <=> " << lid << std::endl;
2737 if ( sol->s[fid] == -1 || lid == -1 )
2738 std::cout <<
"feat inactive :" << inactiveCost[fid] << std::endl;
2739 if ( sol->s[fid] >= 0 )
2740 std::cout <<
"old cost : " << labelpositions[sol->s[fid]]->
cost << std::endl;
2742 std::cout <<
"new cost : " << labelpositions[lid]->
cost << std::endl;
2745 if ( sol->s[fid] >= 0 )
2753 candidates->Search( amin, amax,
nokCallback, &context );
2758 if ( sol->s[fid] >= 0 )
2765 sol->cost += retainedChain->
delta;
2767 std::cout <<
"Expected cost: " << sol->cost << std::endl;
2769 std::cout <<
"chain iteration " << popit <<
": " << sol->cost <<
", " << retainedChain->
delta <<
", " << retainedChain->
degree << std::endl;
2783 std::cout <<
"Cur_cost: " << sol->cost << std::endl;
2790 std::cout <<
" Improved solution: " << ( double )(( search_time = clock() ) - start_time ) / (
double ) CLOCKS_PER_SEC <<
" (solution cost: " << sol->cost <<
", nbDisplayed: " << nbActive <<
" (" << ( double ) nbActive / (
double ) nbft <<
"%)" << std::endl;
2793 std::cerr <<
"\tna\tchain" <<
"\tna\t" << popit <<
"\tna\t" << ( init_sol_time - start_time ) / (
double ) CLOCKS_PER_SEC <<
"\t" << ( search_time - init_sol_time ) / (
double ) CLOCKS_PER_SEC <<
"\t" << ( search_time - start_time ) / (
double ) CLOCKS_PER_SEC <<
"\t" << sol->cost <<
"\t" << nbActive <<
"\t" << ( double ) nbActive / (
double ) nbft;
2809 int *sub = part->
sub;
2810 int *sol = part->
sol;
2812 int *best_sol =
new int[subSize];
2814 for ( i = 0; i < subSize; i++ )
2816 featWrap[sub[i]] = i;
2817 best_sol[i] = sol[i];
2820 double initial_cost;
2821 double cur_cost = 0;
2832 bool *ok =
new bool[subSize];
2834 Chain *retainedChain = NULL;
2842 context.feat = NULL;
2843 context.wrap = featWrap;
2847 int iter = 0, it = 0;
2849 for ( i = 0; i < subSize; i++ )
2852 nbOverlap += featOv;
2855 initial_cost = cur_cost;
2858 cout <<
"Popmusic_chain" << std::endl;
2859 std::cout <<
" initial cost" << initial_cost << std::endl;
2863 for ( i = 0; i < borderSize; i++ )
2866 for ( i = 0; i < probSize; i++ )
2867 ok[i+borderSize] =
false;
2871 for ( seed = ( iter + 1 ) % probSize;
2872 ok[seed + borderSize] && seed != iter;
2873 seed = ( seed + 1 ) % probSize );
2878 iter = ( iter + 1 ) % probSize;
2879 seed = seed + borderSize;
2881 retainedChain = chain( part, seed );
2884 std::cout <<
" seed: " << seed <<
"(" << seed - borderSize <<
" / " << probSize <<
")" << std::endl;
2885 std::cout <<
" chain(seed)";
2886 if ( retainedChain )
2888 std::cout <<
" delta: " << retainedChain->delta << std::endl;
2891 std::cout <<
": undef" << std::endl;
2894 if ( retainedChain && retainedChain->delta < -
EPSILON )
2897 std::cout <<
" chain accepted " << std::endl;
2899 for ( i = 0; i < retainedChain->degree; i++ )
2901 fid = retainedChain->feat[i];
2902 lid = retainedChain->label[i];
2904 if ( sol[fid] >= 0 )
2906 LabelPosition *old = labelpositions[sol[fid]];
2909 old->getBoundingBox( amin, amax );
2912 candidates->Search( amin, amax,
nokCallback, &context );
2917 if ( sol[fid] >= 0 )
2923 cur_cost += retainedChain->delta;
2925 std::cout <<
" cur->cost: " << cur_cost << std::endl;
2938 for ( i = 0; i < subSize; i++ )
2939 featWrap[sub[i]] = -1;
2944 std::cout <<
"Final cost : " << cur_cost <<
" (" << initial_cost - cur_cost <<
")" << std::endl;
2947 return initial_cost - cur_cost;
2961 std::list<LabelPosition*> *solList =
new std::list<LabelPosition*>();
2968 for ( i = 0; i < nbft; i++ )
2970 if ( sol->s[i] != -1 )
2972 solList->push_back( labelpositions[sol->s[i]] );
2974 else if ( returnInactive
2975 || labelpositions[featStartId[i]]->getFeaturePart()->getLayer()->getDisplayAll()
2976 || labelpositions[featStartId[i]]->getFeaturePart()->getAlwaysShow() )
2978 solList->push_back( labelpositions[featStartId[i]] );
2983 if ( returnInactive )
2997 stats->nbObjects = nbft;
2998 stats->nbLabelledObjects = 0;
3000 stats->nbLayers = nbLabelledLayers;
3001 stats->layersName =
new char*[stats->nbLayers];
3002 stats->layersNbObjects =
new int[stats->nbLayers];
3003 stats->layersNbLabelledObjects =
new int[stats->nbLayers];
3005 for ( i = 0; i < stats->nbLayers; i++ )
3007 stats->layersName[i] =
new char[strlen( labelledLayersName[i] ) + 1];
3008 strcpy( stats->layersName[i], labelledLayersName[i] );
3009 stats->layersNbObjects[i] = 0;
3010 stats->layersNbLabelledObjects[i] = 0;
3015 for ( i = 0; i < nbft; i++ )
3017 lyrName = labelpositions[featStartId[i]]->
getLayerName();
3019 for ( j = 0; j < stats->nbLayers; j++ )
3021 if ( strcmp( lyrName, stats->layersName[j] ) == 0 )
3029 stats->layersNbObjects[k]++;
3030 if ( sol->s[i] >= 0 )
3032 stats->layersNbLabelledObjects[k]++;
3033 stats->nbLabelledObjects++;
3038 std::cerr <<
"Error unknown layers while computing stats: " << lyrName << std::endl;
3072 std::ofstream solution(
"solution.raw" );
3073 solution <<
"GeomType ; nbPoints ; label length ; label height ; down-left X ; down-left Y ; rotation (rad) ; points list" << std::endl;
3074 for ( i = 0; i < nbft; i++ )
3077 if ( sol->s[i] >= 0 )
3079 lp = labelpositions[sol->s[i]];
3082 xrm = px2meters( lp->
feature->label_x, pal->dpi, scale );
3083 yrm = px2meters( lp->
feature->label_y, pal->dpi, scale );
3093 lp = labelpositions[featStartId[i]];
3100 if ( sol->s[i] >= 0 )
3102 solution << feature->type <<
";" << feature->nbPoints <<
";" << xrm <<
";" << yrm
3103 <<
";" << lp->
x[0] <<
";" << lp->
y[0] <<
";" << lp->
alpha <<
";";
3107 solution << feature->type <<
";" << feature->nbPoints <<
";0;0;0;0;0;";
3110 for ( j = 0; j < feature->nbPoints; j++ )
3112 solution << feature->x[j] <<
" " << feature->y[j] <<
" ";
3114 solution << std::endl;
3121 void Problem::solution_cost()
3125 std::cout <<
"Global solution evaluation" << std::endl;
3137 context.
nbOv = &nbOv;
3138 context.
cost = &sol->cost;
3145 for ( i = 0; i < nbft; i++ )
3147 if ( sol->s[i] == -1 )
3149 sol->
cost += inactiveCost[i];
3155 lp = labelpositions[sol->s[i]];
3170 if ( nbActive + nbHidden != nbft )
3172 std::cout <<
"Conflicts in solution: " << nbHidden / 2 << std::endl;
3174 std::cout <<
"nbActive and free: " << nbActive <<
" (" << double( nbActive ) / double( nbft ) <<
" %)" << std::endl;
3175 std::cout <<
"solution cost:" << sol->cost << std::endl;
3181 void Problem::drawLabels( std::ofstream &svgmap )
3185 svgmap <<
"<g inkscape:label=\"labels\"" << std::endl
3186 <<
"inkscape:groupmode=\"layer\"" << std::endl
3187 <<
"id=\"label_layer\">" << std::endl << std::endl;
3189 for ( i = 0; i < nbft; i++ )
3191 if ( sol->s[i] >= 0 )
3193 LabelPosition *lp = labelpositions[sol->s[i]];
3194 toSVGPath( 4, 3, lp->x, lp->y, pal->
getDpi(), scale,
convert2pt( bbox[0], scale, pal->
getDpi() ),
convert2pt( bbox[3], scale, pal->
getDpi() ),
"label", lp->feature->uid, svgmap );
3198 svgmap <<
"</g>" << std::endl;