void SrvrMergeOverlappingWalls( uint32_t client_id, INDEX iWorld, PORTHOAREA rect ) { // for all walls - find a wall without a mate in the rect area... // then for all remaining walls - find another wall that is the // same line as this one.... GETWORLD(iWorld); int nwalls, n; PWALL *wallarray; wallarray = GetLinearWallArray( world->walls, &nwalls ); for( n = 0; n < nwalls; n++ ) { _POINT start, end; PWALL wall = wallarray[n]; if( wall->iWallInto == INVALID_INDEX ) { PFLATLAND_MYLINESEG line = GetLine( wall->iLine ); addscaled( start, line->r.o, line->r.n, line->dFrom ); addscaled( end, line->r.o, line->r.n, line->dTo ); if( PointInRect( start, rect ) && PointInRect( end, rect ) ) { int m; for( m = n+1; m < nwalls; m++ ) { PWALL wall2 = wallarray[m]; if( wall2->iWallInto == INVALID_INDEX ) { _POINT start2, end2; PFLATLAND_MYLINESEG line = GetLine( wall2->iLine ); addscaled( start2, line->r.o, line->r.n, line->dFrom ); addscaled( end2, line->r.o, line->r.n, line->dTo ); /* if( PointInRect( start2, rect ) && PointInRect( end2, rect ) ) { Log4( "starts: (%12.12g,%12.12g) vs (%12.12g,%12.12g)" ,start[0], start[1] ,start2[0], start2[1] ); Log4( "ends : (%12.12g,%12.12g) vs (%12.12g,%12.12g)" ,end[0], end[1] ,end2[0], end2[1] ); } */ if( ( Near( start2, start ) && Near( end2, end ) ) ||( Near( start2, end ) && Near( end2, start ) ) ) { SrvrMergeWalls( client_id, iWorld, GetWallIndex( wall ), GetWallIndex( wall2 ) ); break; } } } } } } Release( wallarray ); }
bool Connect4GameState::CheckWinDirections(int player, int x, int y) { for (int i = 0; i < 4; ++i) { if (Near(player, x, y, directions[i][0], directions[i][1]) + Near(player, x, y, -directions[i][0], -directions[i][1]) >= 3) { return true; } } return false; }
template <typename t> static rank_hint Near(t *what) { if (what->isLeaf()) { return Start(); } else { return Near(what->internal().rank); } }
void Attack() { if(Near(Pos, player->Pos)) { player->Score(-1); Erase = true; } }
void performTest(int channelsIn, int channelsOut, int code, double threshold = 1e-3) { for (int j = 0; j < test_loop_times; j++) { generateTestData(channelsIn, channelsOut); OCL_OFF(cv::cvtColor(src_roi, dst_roi, code, channelsOut)); OCL_ON(cv::cvtColor(usrc_roi, udst_roi, code, channelsOut)); Near(threshold); } }
OCL_TEST_P(CalcBackProject, Mat) { for (int j = 0; j < test_loop_times; j++) { random_roi(); OCL_OFF(cv::calcBackProject(images_roi, channels, hist_roi, dst_roi, ranges, scale)); OCL_ON(cv::calcBackProject(uimages_roi, channels, uhist_roi, udst_roi, ranges, scale)); Near(); } }
void UnitTest() { assert(Sign(+10) == +1); assert(Sign(-10) == -1); assert(Sign(0) == 0); int n[6] = { 0 }; for (int i = 0; i < 10000; i++) for (int j = 1; j < 6; j++) n[j] += (SimpleRNG::ins().Random(j) == 0); assert(Near(n[1], 10000, 0)); assert(Near(n[2], 5000, 250)); assert(Near(n[3], 3333, 250)); assert(Near(n[4], 2500, 250)); assert(Near(n[5], 2000, 250)); int c = 0; for (int i = 0; i < 10000; i++) c += SimpleRNG::ins().Bernoulli(0.5); assert(Near(c, 5000, 250)); assert(CheckFlag(5, 0)); assert(!CheckFlag(5, 1)); assert(CheckFlag(5, 2)); assert(!CheckFlag(5, 3)); int flag = 1; SetFlag(flag, 2); SetFlag(flag, 4); assert(flag == 21); }
void Update() { if(Near(Pos, player->Pos)) { Visual = ' '; Collision = false; } else { Visual = '='; Collision = true; } }
bool PathFind::Search(const Point& first,const Point& second) { if(A[first.X][first.Y]!=A[second.X][second.Y]) { return false; } bool isOK=Near(first,second); if(!isOK) { isOK=OneLine(first,second); } if(!isOK) { isOK=MoreLine(first,second); } return isOK; }
void Update() { Attack(); if(Near(Pos, player->Pos, 8)) { if(dir) { if(Pos.x < player->Pos.x) Pos.x++; else if(Pos.x > player->Pos.x) Pos.x--; } else { if(Pos.y < player->Pos.y) Pos.y++; else if(Pos.y > player->Pos.y) Pos.y--; } } dir = !dir; }
OCL_TEST_F(SphericalWarperTest, Mat) { for (int j = 0; j < test_loop_times; j++) { generateTestData(); Ptr<WarperCreator> creator = makePtr<SphericalWarper>(); Ptr<detail::RotationWarper> warper = creator->create(2.0); OCL_OFF(warper->buildMaps(src.size(), K, R, xmap, ymap)); OCL_ON(warper->buildMaps(usrc.size(), K, R, uxmap, uymap)); OCL_OFF(warper->warp(src, K, R, INTER_LINEAR, BORDER_REPLICATE, dst)); OCL_ON(warper->warp(usrc, K, R, INTER_LINEAR, BORDER_REPLICATE, udst)); Near(1e-4); } }
unsigned int KeyFrameSequenceLength( KeyLink * p, double transTolerance, double rotTolerance ) { CalVector translation = p->keyframe_->getTranslation(); CalQuaternion rotation = p->keyframe_->getRotation(); p = p->next_; unsigned int len = 1; while( p ) { CalVector const ppos = p->keyframe_->getTranslation(); CalQuaternion const pori = p->keyframe_->getRotation(); if( Near( translation, rotation, ppos, pori, transTolerance, rotTolerance ) ) { len++; p = p->next_; } else { break; } } return len; }
bool CalCoreTrack::keyframeEliminatable( CalCoreKeyframe * prev, CalCoreKeyframe * p, CalCoreKeyframe * next, double transTolerance, double rotTolerance ) { CalVector translation; CalQuaternion rotation; assert( prev && p && next ); float time = p->getTime(); float blendFactor; blendFactor = ( time - prev->getTime() ) / ( next->getTime() - prev->getTime() ); // blend between the two keyframes translation = prev->getTranslation(); translation.blend( blendFactor, next->getTranslation() ); rotation = prev->getRotation(); rotation.blend( blendFactor, next->getRotation() ); CalVector const ppos = p->getTranslation(); CalQuaternion const pori = p->getRotation(); return Near( translation, rotation, ppos, pori, transTolerance, rotTolerance ); }
double Dist(const Line& l, const Point3d& p, Point3d& pnear, double& t){ // returns the distance of a point from a line and the near point on the extended line and the parameter of the near point (0-length) in range pnear = Near(l, p, t ); return p.Dist(pnear); }
LKH::LKHAlg::Node * LKH::LKHAlg::Best5OptMove(Node * t1, Node * t2, GainType * G0, GainType * Gain) { Node *t3, *t4, *t5, *t6 = 0, *t7, *t8 = 0, *t9, *t10 = 0; Node *T3 = 0, *T4 = 0, *T5 = 0, *T6 = 0, *T7 = 0, *T8 = 0, *T9 = 0, *T10 = 0; Candidate *Nt2, *Nt4, *Nt6, *Nt8; GainType G1, G2, G3, G4, G5, G6, G7, G8, BestG8 = MINUS_INFINITY; int Case6 = 0, Case8 = 0, Case10 = 0, BestCase10 = 0, X4, X6, X8, X10, BTW275 = 0, BTW674 = 0, BTW571 = 0, BTW376 = 0, BTW574 = 0, BTW671 = 0, BTW471 = 0, BTW673 = 0, BTW573 = 0, BTW273 = 0; int Breadth2 = 0, Breadth4, Breadth6, Breadth8; if (t2 != SUC(t1)) Reversed ^= 1; /* * Determine (T3,T4,T5,T6,T7,T8,T9,T10) = (t3,t4,t5,t6,t7,t8,t9,t10) * such that * * G8 = *G0 - C(t2,T3) + C(T3,T4) * - C(T4,T5) + C(T5,T6) * - C(T6,T7) + C(T7,T8) * - C(T8,T9) + C(T9,T10) * * is maximum (= BestG8), and (T9,T10) has not previously been included. * If during this process a legal move with *Gain > 0 is found, then make * the move and exit Best5OptMove immediately. */ /* Choose (t2,t3) as a candidate edge emanating from t2 */ for (Nt2 = t2->CandidateSet; (t3 = Nt2->To); Nt2++) { if (t3 == t2->Pred || t3 == t2->Suc || ((G1 = *G0 - Nt2->Cost) <= 0 && GainCriterionUsed && ProblemType != HCP && ProblemType != HPP)) continue; if (++Breadth2 > MaxBreadth) break; /* Choose t4 as one of t3's two neighbors on the tour */ for (X4 = 1; X4 <= 2; X4++) { t4 = X4 == 1 ? PRED(t3) : SUC(t3); if (FixedOrCommon(t3, t4)) continue; G2 = G1 + (this->*C)(t3, t4); if (X4 == 1 && !Forbidden(t4, t1) && (!c || G2 - (this->*c)(t4, t1) > 0) && (*Gain = G2 - (this->*C)(t4, t1)) > 0) { Make2OptMove(t1, t2, t3, t4); return 0; } if (Backtracking && !Excludable(t3, t4)) continue; Breadth4 = 0; /* Choose (t4,t5) as a candidate edge emanating from t4 */ for (Nt4 = t4->CandidateSet; (t5 = Nt4->To); Nt4++) { if (t5 == t4->Pred || t5 == t4->Suc || ((G3 = G2 - Nt4->Cost) <= 0 && GainCriterionUsed && ProblemType != HCP && ProblemType != HPP)) continue; if (++Breadth4 > MaxBreadth) break; /* Choose t6 as one of t5's two neighbors on the tour */ for (X6 = 1; X6 <= 2; X6++) { if (X4 == 1) { if (X6 == 1) { Case6 = 1 + !BETWEEN(t2, t5, t4); t6 = Case6 == 1 ? SUC(t5) : PRED(t5); } else { t6 = t6 == t5->Pred ? t5->Suc : t5->Pred; if ((t5 == t1 && t6 == t2) || (t5 == t2 && t6 == t1)) continue; Case6 += 2; } } else if (BETWEEN(t2, t5, t3)) { Case6 = 4 + X6; t6 = X6 == 1 ? SUC(t5) : PRED(t5); if (t6 == t1) continue; } else { Case6 = 6 + X6; t6 = X6 == 1 ? PRED(t5) : SUC(t5); if (t6 == t2) continue; } if (FixedOrCommon(t5, t6)) continue; G4 = G3 + (this->*C)(t5, t6); if ((Case6 <= 2 || Case6 == 5 || Case6 == 6) && !Forbidden(t6, t1) && (!c || G4 - (this->*c)(t6, t1) > 0) && (*Gain = G4 - (this->*C)(t6, t1)) > 0) { Make3OptMove(t1, t2, t3, t4, t5, t6, Case6); return 0; } if (Backtracking && !Excludable(t5, t6)) continue; Breadth6 = 0; /* Choose (t6,t7) as a candidate edge emanating from t6 */ for (Nt6 = t6->CandidateSet; (t7 = Nt6->To); Nt6++) { if (t7 == t6->Pred || t7 == t6->Suc || (t6 == t2 && t7 == t3) || (t6 == t3 && t7 == t2) || ((G5 = G4 - Nt6->Cost) <= 0 && GainCriterionUsed && ProblemType != HCP && ProblemType != HPP)) continue; if (++Breadth6 > MaxBreadth) break; /* Choose t8 as one of t7's two neighbors on the tour */ for (X8 = 1; X8 <= 2; X8++) { if (X8 == 1) { Case8 = Case6; switch (Case6) { case 1: if ((BTW275 = BETWEEN(t2, t7, t5))) t8 = SUC(t7); else { t8 = PRED(t7); BTW674 = BETWEEN(t6, t7, t4); } break; case 2: if ((BTW376 = BETWEEN(t3, t7, t6))) t8 = SUC(t7); else { t8 = PRED(t7); BTW571 = BETWEEN(t5, t7, t1); } break; case 3: t8 = SUC(t7); BTW574 = BETWEEN(t5, t7, t4); break; case 4: if ((BTW671 = BETWEEN(t6, t7, t1))) t8 = PRED(t7); else t8 = BETWEEN(t2, t7, t4) ? SUC(t7) : PRED(t7); break; case 5: t8 = PRED(t7); BTW471 = BETWEEN(t4, t7, t1); if (!BTW471) BTW673 = BETWEEN(t6, t7, t3); break; case 6: if ((BTW471 = BETWEEN(t4, t7, t1))) t8 = PRED(t7); else { t8 = SUC(t7); BTW573 = BETWEEN(t5, t7, t3); } break; case 7: case 8: t8 = SUC(t7); BTW273 = BETWEEN(t2, t7, t3); break; } } else { t8 = t8 == t7->Pred ? t7->Suc : t7->Pred; Case8 += 8; } if ((t7 == t1 && t8 == t2) || (t7 == t2 && t8 == t1) || (t7 == t3 && t8 == t4) || (t7 == t4 && t8 == t3)) continue; if (FixedOrCommon(t7, t8)) continue; if (Case6 == 3 && !BTW574 && (X8 == 1) == BETWEEN(t3, t7, t1)) continue; if (Case6 == 4 && BTW671 && X8 == 2) break; if (Case6 == 7 && !BTW273 && (X8 == 1) == BETWEEN(t5, t7, t1)) continue; if (Case6 == 8 && !BTW273 && !BETWEEN(t4, t7, t5)) break; G6 = G5 + (this->*C)(t7, t8); if (t8 != t1 && (Case6 == 3 ? BTW574 : Case6 == 4 ? !BTW671 : Case6 == 7 ? BTW273 : Case6 != 8 && X8 == 1) && !Forbidden(t8, t1) && (!c || G6 - (this->*c)(t8, t1) > 0) && (*Gain = G6 - (this->*C)(t8, t1)) > 0) { Make4OptMove(t1, t2, t3, t4, t5, t6, t7, t8, Case8); return 0; } if (Backtracking && !Excludable(t7, t8)) continue; Breadth8 = 0; /* Choose (t8,t9) as a candidate edge emanating from t8 */ for (Nt8 = t8->CandidateSet; (t9 = Nt8->To); Nt8++) { if (t9 == t8->Pred || t9 == t8->Suc || t9 == t1 || (t8 == t2 && t9 == t3) || (t8 == t3 && t9 == t2) || (t8 == t4 && t9 == t5) || (t8 == t5 && t9 == t4) || ((G7 = G6 - Nt8->Cost) <= 0 && GainCriterionUsed && ProblemType != HCP && ProblemType != HPP)) continue; if (++Breadth8 > MaxBreadth) break; /* Choose t10 as one of t9's two neighbors on the tour */ for (X10 = 1; X10 <= 2; X10++) { if (X10 == 1) { t10 = 0; switch (Case8) { case 1: t10 = (BTW275 ? BETWEEN(t8, t9, t5) || BETWEEN(t3, t9, t1) : BTW674 ? BETWEEN(t7, t9, t1) : BETWEEN(t7, t9, t5)) ? PRED(t9) : SUC(t9); Case10 = 22; break; case 2: t10 = (BTW376 ? BETWEEN(t8, t9, t4) : BTW571 ? BETWEEN(t7, t9, t1) || BETWEEN(t3, t9, t6) : BETWEEN(t7, t9, t1)) ? PRED(t9) : SUC(t9); Case10 = 23; break; case 3: if (BTW574) { t10 = BETWEEN(t5, t9, t1) ? PRED(t9) : SUC(t9); Case10 = 24; break; } if (!BETWEEN(t5, t9, t4)) break; t10 = SUC(t9); Case10 = 1; break; case 4: if (BTW671) { if (!BETWEEN(t2, t9, t5)) break; t10 = SUC(t9); Case10 = 2; break; } t10 = BETWEEN(t6, t9, t4) ? PRED(t9) : SUC(t9); Case10 = 25; break; case 5: t10 = (BTW471 ? BETWEEN(t7, t9, t1) : BTW673 ? BETWEEN(t7, t9, t5) : BETWEEN(t4, t9, t1) || BETWEEN(t7, t9, t5)) ? PRED(t9) : SUC(t9); Case10 = 26; break; case 6: t10 = (BTW471 ? BETWEEN(t7, t9, t3) : BTW573 ? BETWEEN(t8, t9, t6) : BETWEEN(t4, t9, t1) || BETWEEN(t8, t9, t6)) ? PRED(t9) : SUC(t9); Case10 = 27; break; case 7: if (BTW273) { t10 = BETWEEN(t5, t9, t3) ? PRED(t9) : SUC(t9); Case10 = 28; break; } if (!BETWEEN(t2, t9, t3)) break; t10 = SUC(t9); Case10 = 3; break; case 8: if (BTW273) { if (!BETWEEN(t4, t9, t5)) break; Case10 = 4; } else { if (!BETWEEN(t2, t9, t3)) break; Case10 = 5; } t10 = SUC(t9); break; case 9: if (BTW275) { if (!BETWEEN(t7, t9, t4)) break; t10 = SUC(t9); Case10 = 6; break; } if (!BTW674) { if (!BETWEEN(t2, t9, t7)) break; t10 = SUC(t9); Case10 = 7; break; } if (!BETWEEN(t6, t9, t7)) break; t10 = SUC(t9); Case10 = 8; break; case 10: if (BTW376) { if (!BETWEEN(t7, t9, t6)) break; t10 = SUC(t9); Case10 = 9; break; } if (BTW571) { if (!BETWEEN(t2, t9, t7)) break; t10 = SUC(t9); Case10 = 10; break; } if (!BETWEEN(t3, t9, t6) && !BETWEEN(t2, t9, t7)) break; t10 = SUC(t9); Case10 = 11; break; case 11: if (BTW574) { t10 = BETWEEN(t3, t9, t1) ? PRED(t9) : SUC(t9); Case10 = 29; break; } if (!BETWEEN(t5, t9, t4)) break; t10 = SUC(t9); Case10 = 12; break; case 12: t10 = BETWEEN(t3, t9, t1) ? PRED(t9) : SUC(t9); Case10 = 30; break; case 13: if (BTW471) { if (!BETWEEN(t2, t9, t7)) break; t10 = SUC(t9); Case10 = 13; break; } if (BTW673) { if (!BETWEEN(t6, t9, t7)) break; t10 = SUC(t9); Case10 = 14; break; } if (!BETWEEN(t6, t9, t3) && !BETWEEN(t2, t9, t7)) break; t10 = SUC(t9); Case10 = 15; break; case 14: if (BTW471) { if (!BETWEEN(t2, t9, t7)) break; t10 = SUC(t9); Case10 = 16; break; } if (BTW573) { if (!BETWEEN(t7, t9, t3) && !BETWEEN(t2, t9, t6)) break; t10 = SUC(t9); Case10 = 17; break; } if (!BETWEEN(t7, t9, t6)) break; t10 = SUC(t9); Case10 = 18; break; case 15: if (BTW273) { t10 = BETWEEN(t5, t9, t1) ? PRED(t9) : SUC(t9); Case10 = 31; break; } if (!BETWEEN(t2, t9, t3)) break; t10 = SUC(t9); Case10 = 19; break; case 16: if (BTW273) { if (!BETWEEN(t4, t9, t5)) break; Case10 = 20; } else { if (!BETWEEN(t2, t9, t3)) break; Case10 = 21; } t10 = SUC(t9); break; } if (!t10) break; } else { if (Case10 >= 22) continue; Case10 += 31; t10 = t10 == t9->Pred ? t9->Suc : t9->Pred; } if (t10 == t1 || (t9 == t3 && t10 == t4) || (t9 == t4 && t10 == t3) || (t9 == t5 && t10 == t6) || (t9 == t6 && t10 == t5)) continue; if (FixedOrCommon(t9, t10)) continue; G8 = G7 + (this->*C)(t9, t10); if (!Forbidden(t10, t1) && (!c || G8 - (this->*c)(t10, t1) > 0) && (*Gain = G8 - (this->*C)(t10, t1)) > 0) { Make5OptMove(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, Case10); return 0; } if (GainCriterionUsed && G8 - Precision < t10->Cost) continue; if (!Backtracking || Swaps > 0) { if ((G8 > BestG8 || (G8 == BestG8 && !Near(t9, t10) && Near(T9, T10))) && Swaps < MaxSwaps && Excludable(t9, t10) && !InInputTour(t9, t10)) { /* Ignore the move if the gain does not vary */ if (RestrictedSearch && ProblemType != HCP && ProblemType != HPP && G2 - t4->Pi == G4 - t6->Pi && G4 - t6->Pi == G6 - t8->Pi && G6 - t8->Pi == G8 - t10->Pi && G3 + t5->Pi == G1 + t3->Pi && G5 + t7->Pi == G3 + t5->Pi && G7 + t9->Pi == G5 + t7->Pi) continue; T3 = t3; T4 = t4; T5 = t5; T6 = t6; T7 = t7; T8 = t8; T9 = t9; T10 = t10; BestCase10 = Case10; BestG8 = G8; } } else if (MaxSwaps > 0) { GainType G = G8; Node *t = t10; Make5OptMove(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, Case10); Exclude(t1, t2); Exclude(t3, t4); Exclude(t5, t6); Exclude(t7, t8); Exclude(t9, t10); while ((t = (this->*BestSubsequentMove)(t1, t, &G, Gain))); if (*Gain > 0) return 0; RestoreTour(); if (t2 != SUC(t1)) Reversed ^= 1; } } } } } } } } } *Gain = 0; if (T10) { /* Make the best 5-opt move */ Make5OptMove(t1, t2, T3, T4, T5, T6, T7, T8, T9, T10, BestCase10); Exclude(t1, t2); Exclude(T3, T4); Exclude(T5, T6); Exclude(T7, T8); Exclude(T9, T10); *G0 = BestG8; } return T10; }
void MergePatternsAntiPar(STRIDE_PATTERN **Pat, int NPat) { register int i, j; int DB, DW, MinDB1, MinDB2, MinDW1, MinDW2, Min, Lnk1A, Lnk1D; int I1A, I1D, I2A, I2D, J1A, J1D, J2A, J2D; char I1ACn, I1DCn, I2ACn, I2DCn, J1ACn, J1DCn, J2ACn, J2DCn; for( i=0; i<NPat; i++ ) { if( !Pat[i]->ExistPattern ) continue; MinDB1 = MinDB2 = MinDW1 = MinDW2 = 1000; Min = ERR; Lnk1D = Lnk1A = ERR; Alias(&I1D,&I1A,&I2D,&I2A,&I1DCn,&I1ACn,&I2DCn,&I2ACn,Pat[i]); for( j=0; j<NPat; j++ ) { if( i == j || !Pat[j]->ExistPattern ) continue; Alias(&J1D,&J1A,&J2D,&J2A,&J1DCn,&J1ACn,&J2DCn,&J2ACn,Pat[j]); if( Near(I1D,J1D,J1A,I1A,J2A,J2D,I2A,I2D,I1DCn,J1DCn,J1ACn,I1ACn,&DB,&DW) && ((DB < MinDB1 && DW <= MinDW1) || (DB <= MinDB1 && DW < MinDW1) ) && RightSide(J1A,J1D,I1A,I1D,I2A,I2D) ) JoinNeighbours(&Lnk1A,J2D,&Lnk1D,J2A,&Pat[i]->Nei1,Pat[j],&MinDB1,DB,&MinDW1,DW,&Min,j); if( Near(I1D,J1A,J1D,I1A,J2D,J2A,I2A,I2D,I1DCn,J1ACn,J1DCn,I1ACn,&DB,&DW) && ((DB < MinDB1 && DW <= MinDW1) || (DB <= MinDB1 && DW < MinDW1) ) && RightSide(J1D,J1A,I1A,I1D,I2A,I2D) ) JoinNeighbours(&Lnk1A,J2A,&Lnk1D,J2D,&Pat[i]->Nei1,Pat[j],&MinDB1,DB,&MinDW1,DW,&Min,j); if( Near(I1D,J2D,J2A,I1A,J1A,J1D,I2A,I2D,I1DCn,J2DCn,J2ACn,I1ACn,&DB,&DW) && ((DB < MinDB1 && DW <= MinDW1) || (DB <= MinDB1 && DW < MinDW1) ) && RightSide(J2A,J2D,I1A,I1D,I2A,I2D) ) JoinNeighbours(&Lnk1A,J1D,&Lnk1D,J1A,&Pat[i]->Nei1,Pat[j],&MinDB1,DB,&MinDW1,DW,&Min,j); if( Near(I1D,J2A,J2D,I1A,J1D,J1A,I2A,I2D,I1DCn,J2ACn,J2DCn,I1ACn,&DB,&DW) && ((DB < MinDB1 && DW <= MinDW1) || (DB <= MinDB1 && DW < MinDW1) ) && RightSide(J2D,J2A,I1A,I1D,I2A,I2D) ) JoinNeighbours(&Lnk1A,J1A,&Lnk1D,J1D,&Pat[i]->Nei1,Pat[j],&MinDB1,DB,&MinDW1,DW,&Min,j); if( Near(I1A,J1D,J1A,I1D,J2A,J2D,I2D,I2A,I1ACn,J1DCn,J1ACn,I1DCn,&DB,&DW) && ((DB < MinDB1 && DW <= MinDW1) || (DB <= MinDB1 && DW < MinDW1) ) && RightSide(J1A,J1D,I1A,I1D,I2A,I2D) ) JoinNeighbours(&Lnk1A,J2A,&Lnk1D,J2D,&Pat[i]->Nei1,Pat[j],&MinDB1,DB,&MinDW1,DW,&Min,j); if( Near(I1A,J1A,J1D,I1D,J2D,J2A,I2D,I2A,I1ACn,J1ACn,J1DCn,I1DCn,&DB,&DW) && ((DB < MinDB1 && DW <= MinDW1) || (DB <= MinDB1 && DW < MinDW1) ) && RightSide(J1A,J1D,I1A,I1D,I2A,I2D) ) JoinNeighbours(&Lnk1A,J2D,&Lnk1D,J2A,&Pat[i]->Nei1,Pat[j],&MinDB1,DB,&MinDW1,DW,&Min,j); if( Near(I1A,J2D,J2A,I1D,J1A,J1D,I2D,I2A,I1ACn,J2DCn,J2ACn,I1DCn,&DB,&DW) && ((DB < MinDB1 && DW <= MinDW1) || (DB <= MinDB1 && DW < MinDW1) ) && RightSide(J2D,J2A,I1A,I1D,I2A,I2D) ) JoinNeighbours(&Lnk1A,J1A,&Lnk1D,J1D,&Pat[i]->Nei1,Pat[j],&MinDB1,DB,&MinDW1,DW,&Min,j); if( Near(I1A,J2A,J2D,I1D,J1D,J1A,I2D,I2A,I1ACn,J2ACn,J2DCn,I1DCn,&DB,&DW) && ((DB < MinDB1 && DW <= MinDW1) || (DB <= MinDB1 && DW < MinDW1) ) && RightSide(J2A,J2D,I1A,I1D,I2A,I2D) ) JoinNeighbours(&Lnk1A,J1D,&Lnk1D,J2D,&Pat[i]->Nei1,Pat[j],&MinDB1,DB,&MinDW1,DW,&Min,j); } for( j=0; j<NPat; j++ ) { if( j == Min || j == i || !Pat[j]->ExistPattern ) continue; Alias(&J1D,&J1A,&J2D,&J2A,&J1DCn,&J1ACn,&J2DCn,&J2ACn,Pat[j]); if( Near(I2D,J1D,J1A,I2A,J2A,J2D,I1A,I1D,I2DCn,J1DCn,J1ACn,I2ACn,&DB,&DW) && (( DB < MinDB2 && DW <= MinDW2) || (DB <= MinDB2 && DW < MinDW2) ) && RightSide2(Lnk1A,Lnk1D,J2A,J2D,I1A,I1D,I2A,I2D) ) JoinNeighb(&Pat[i]->Nei2,Pat[j],&MinDB2,DB,&MinDW2,DW); if( Near(I2D,J1A,J1D,I2A,J2D,J2A,I1A,I1D,I2DCn,J1ACn,J1DCn,I2ACn,&DB,&DW) && (( DB < MinDB2 && DW <= MinDW2) || (DB <= MinDB2 && DW < MinDW2) ) && RightSide2(Lnk1A,Lnk1D,J2D,J2A,I1A,I1D,I2A,I2D) ) JoinNeighb(&Pat[i]->Nei2,Pat[j],&MinDB2,DB,&MinDW2,DW); if( Near(I2D,J2D,J2A,I2A,J1A,J1D,I1A,I1D,I2DCn,J2DCn,J2ACn,I2ACn,&DB,&DW) && (( DB < MinDB2 && DW <= MinDW2) || (DB <= MinDB2 && DW < MinDW2) ) && RightSide2(Lnk1A,Lnk1D,J1A,J1D,I1A,I1D,I2A,I2D) ) JoinNeighb(&Pat[i]->Nei2,Pat[j],&MinDB2,DB,&MinDW2,DW); if( Near(I2D,J2A,J2D,I2A,J1D,J1A,I1A,I1D,I2DCn,J2ACn,J2DCn,I2ACn,&DB,&DW) && (( DB < MinDB2 && DW <= MinDW2) || (DB <= MinDB2 && DW < MinDW2) ) && RightSide2(Lnk1A,Lnk1D,J1D,J1A,I1A,I1D,I2A,I2D) ) JoinNeighb(&Pat[i]->Nei2,Pat[j],&MinDB2,DB,&MinDW2,DW); if( Near(I2A,J1D,J1A,I2D,J2A,J2D,I1D,I1A,I2ACn,J1DCn,J1ACn,I2DCn,&DB,&DW) && (( DB < MinDB2 && DW <= MinDW2) || (DB <= MinDB2 && DW < MinDW2) ) && RightSide2(Lnk1A,Lnk1D,J2D,J2A,I1A,I1D,I2A,I2D) ) JoinNeighb(&Pat[i]->Nei2,Pat[j],&MinDB2,DB,&MinDW2,DW); if( Near(I2A,J1A,J1D,I2D,J2D,J2A,I1D,I1A,I2ACn,J1ACn,J1DCn,I2DCn,&DB,&DW) && (( DB < MinDB2 && DW <= MinDW2) || (DB <= MinDB2 && DW < MinDW2) ) && RightSide2(Lnk1A,Lnk1D,J2A,J2D,I1A,I1D,I2A,I2D) ) JoinNeighb(&Pat[i]->Nei2,Pat[j],&MinDB2,DB,&MinDW2,DW); if( Near(I2A,J2D,J2A,I2D,J1A,J1D,I1D,I1A,I2ACn,J2DCn,J2ACn,I2DCn,&DB,&DW) && (( DB < MinDB2 && DW <= MinDW2) || (DB <= MinDB2 && DW < MinDW2) ) && RightSide2(Lnk1A,Lnk1D,J1D,J1A,I1A,I1D,I2A,I2D) ) JoinNeighb(&Pat[i]->Nei2,Pat[j],&MinDB2,DB,&MinDW2,DW); if( Near(I2A,J2A,J2D,I2D,J1D,J1A,I1D,I1A,I2ACn,J2ACn,J2DCn,I2DCn,&DB,&DW) && (( DB < MinDB2 && DW <= MinDW2) || (DB <= MinDB2 && DW < MinDW2) ) && RightSide2(Lnk1A,Lnk1D,J1A,J1D,I1A,I1D,I2A,I2D) ) JoinNeighb(&Pat[i]->Nei2,Pat[j],&MinDB2,DB,&MinDW2,DW); } } }
bool PathFind::Near(TwoPoint& endPoint) { Point& first=endPoint.First(); Point& second=endPoint.Second(); return Near(first,second); }
static GainType BestKOptMoveRec(int k, GainType G0,LKH::LKHAlg *Alg) { LKH::LKHAlg::Candidate *Nt2; LKH::LKHAlg::Node *t1, *t2, *t3, *t4; GainType G1, G2, G3, Gain; int X4, i; int Breadth2 = 0; t1 = (*t.get())[1]; t2 = (*t.get())[i = 2 * k - 2]; (*incl.get())[(*incl.get())[i] = i + 1] = i; (*incl.get())[(*incl.get())[1] = i + 2] = 1; /* Choose (t2,t3) as a candidate edge emanating from t2 */ for (Nt2 = t2->CandidateSet; (t3 = Nt2->To); Nt2++) { if (t3 == t2->Pred || t3 == t2->Suc || ((G1 = G0 - Nt2->Cost) <= 0 && Alg->GainCriterionUsed && Alg->ProblemType != LKH::HCP && Alg->ProblemType != LKH::HPP) || Added(t2, t3)) continue; if (++Breadth2 > Alg->MaxBreadth) break; MarkAdded(t2, t3); (*t.get())[2 * k - 1] = t3; (*G.get())[2 * k - 2] = G1 + t3->Pi; /* Choose t4 as one of t3's two neighbors on the tour */ for (X4 = 1; X4 <= 2; X4++) { t4 = X4 == 1 ? (Alg->Reversed == (t3)->Parent->Reversed ? (t3)->Pred : (t3)->Suc) : (Alg->Reversed == (t3)->Parent->Reversed ? (t3)->Suc : (t3)->Pred); if ((Fixed(t3, t4) || Alg->IsCommonEdge(t3, t4)) || Deleted(t3, t4)) continue; (*t.get())[2 * k] = t4; G2 = G1 + (Alg->*(Alg->C))(t3, t4); G3 = MINUS_INFINITY; if (t4 != t1 && !Alg->Forbidden(t4, t1) && !Added(t4, t1) && (!Alg->c || G2 - (Alg->*(Alg->c))(t4, t1) > 0) && (G3 = G2 - (Alg->*(Alg->C))(t4, t1)) > 0 && FeasibleKOptMove(k)) { UnmarkAdded(t2, t3); Alg->MakeKOptMove(k); return G3; } if (Alg->Backtracking && !Alg->Excludable(t3, t4)) continue; MarkDeleted(t3, t4); (*G.get())[2 * k - 1] = G2 - t4->Pi; if (k < *K) { if ((Gain = BestKOptMoveRec(k + 1, G2,Alg)) > 0) { UnmarkAdded(t2, t3); UnmarkDeleted(t3, t4); return Gain; } (*incl.get())[(*incl.get())[1] = 2 * k] = 1; } if (t4 != t1 && !Alg->Forbidden(t4, t1) && k + 1 < Alg->NonsequentialMoveType && Alg->PatchingC >= 2 && Alg->PatchingA >= 1 && (Alg->Swaps == 0 || Alg->SubsequentPatching)) { if (G3 == MINUS_INFINITY) G3 = G2 - (Alg->*(Alg->C))(t4, t1); if ((Alg->PatchingCRestricted ? G3 > 0 && Alg->IsCandidate(t4, t1) : Alg->PatchingCExtended ? G3 > 0 || Alg->IsCandidate(t4, t1) : G3 > 0) && (Gain = Alg->PatchCycles(k, G3)) > 0) { UnmarkAdded(t2, t3); UnmarkDeleted(t3, t4); return Gain; } } UnmarkDeleted(t3, t4); if (k == *K && t4 != t1 && t3 != t1 && G3 <= 0 && !Added(t4, t1) && (!Alg->GainCriterionUsed || G2 - Alg->Precision >= t4->Cost)) { if (!Alg->Backtracking || Alg->Swaps > 0) { if ((G2 > *BestG2 || (G2 == *BestG2 && !Near(t3, t4) && Near((*T.get())[2 * *K - 1], (*T.get())[2 * *K]))) && Alg->Swaps < Alg->MaxSwaps && Alg->Excludable(t3, t4) && !InInputTour(t3, t4)) { if (Alg->RestrictedSearch && *K > 2 && Alg->ProblemType != LKH::HCP && Alg->ProblemType != LKH::HPP) { /* Ignore the move if the gain does not vary */ (*G.get())[0] = (*G.get())[2 * *K - 2]; (*G.get())[1] = (*G.get())[2 * *K - 1]; for (i = 2 * *K - 3; i >= 2; i--) if ((*G.get())[i] != (*G.get())[i % 2]) break; if (i < 2) continue; } if (FeasibleKOptMove(*K)) { *BestG2 = G2; memcpy(T.get() + 1, t.get() + 1, 2 * *K * sizeof(LKH::LKHAlg::Node *)); } } } else if (Alg->MaxSwaps > 0 && FeasibleKOptMove(*K)) { LKH::LKHAlg::Node *SUCt1 = (Alg->Reversed == (t1)->Parent->Reversed ? (t1)->Suc : (t1)->Pred); Alg->MakeKOptMove(*K); for (i = 1; i < 2 * k; i += 2) { Alg->Exclude((*t.get())[i], (*t.get())[i + 1]); UnmarkDeleted((*t.get())[i], (*t.get())[i + 1]); } for (i = 2; i < 2 * k; i += 2) UnmarkAdded((*t.get())[i], (*t.get())[i + 1]); memcpy(tSaved.get() + 1, t.get() + 1, 2 * k * sizeof(LKH::LKHAlg::Node *)); while ((t4 = (Alg->*(Alg->BestSubsequentMove))(t1, t4, &G2, &Gain))); if (Gain > 0) { UnmarkAdded(t2, t3); return Gain; } Alg->RestoreTour(); *K = k; memcpy(t.get() + 1, tSaved.get() + 1, 2 * *K * sizeof(LKH::LKHAlg::Node *)); for (i = 1; i < 2 * *K - 2; i += 2) MarkDeleted((*t.get())[i], (*t.get())[i + 1]); for (i = 2; i < 2 * *K; i += 2) MarkAdded((*t.get())[i], (*t.get())[i + 1]); for (i = 2; i < 2 * *K; i += 2) (*incl.get())[(*incl.get())[i] = i + 1] = i; (*incl.get())[(*incl.get())[1] = 2 * *K] = 1; if (SUCt1 != (Alg->Reversed == (t1)->Parent->Reversed ? (t1)->Suc : (t1)->Pred)) Alg->Reversed ^= 1; (*T.get())[2 * *K] = 0; } } } UnmarkAdded(t2, t3); if (t3 == t1) continue; /* Try to delete an added edge, (_,t3) or (t3,_) */ for (i = 2 * k - 4; i >= 2; i--) { if (t3 == (*t.get())[i]) { t4 = (*t.get())[i ^ 1]; if (t4 == t1 || Alg->Forbidden(t4, t1) || (Fixed(t3, t4) || Alg->IsCommonEdge(t3, t4)) || Added(t4, t1)) continue; G2 = G1 + (Alg->*(Alg->C))(t3, t4); if ((!Alg->c || G2 - (Alg->*(Alg->c))(t4, t1) > 0) && (Gain = G2 - (Alg->*(Alg->C))(t4, t1)) > 0) { (*incl.get())[(*incl.get())[i ^ 1] = 1] = i ^ 1; (*incl.get())[(*incl.get())[i] = 2 * k - 2] = i; if (FeasibleKOptMove(k - 1)) { Alg->MakeKOptMove(k - 1); return Gain; } (*incl.get())[(*incl.get())[i ^ 1] = i] = i ^ 1; } } } (*incl.get())[1] = 2 * k; (*incl.get())[2 * k - 2] = 2 * k - 1; } return 0; }
Node *Best2OptMove(Node * t1, Node * t2, GainType * G0, GainType * Gain) { Node *t3, *t4, *T3 = 0, *T4 = 0; Candidate *Nt2; GainType G1, G2, BestG2 = MINUS_INFINITY; int Breadth2 = 0; if (SUC(t1) != t2) Reversed ^= 1; /* * Determine (T3,T4) = (t3,t4) * such that * * G4 = *G0 - C(t2,T3) + C(T3,T4) * * is maximum (= BestG2), and (T3,T4) has not previously been included. * If during this process a legal move with *Gain > 0 is found, then make * the move and exit Best2OptMove immediately */ /* Choose (t2,t3) as a candidate edge emanating from t2 */ for (Nt2 = t2->CandidateSet; (t3 = Nt2->To); Nt2++) { if (t3 == t2->Pred || t3 == t2->Suc || ((G1 = *G0 - Nt2->Cost) <= 0 && GainCriterionUsed && ProblemType != HCP && ProblemType != HPP)) continue; /* Choose t4 (only one choice gives a closed tour) */ t4 = PRED(t3); if (FixedOrCommon(t3, t4)) continue; G2 = G1 + C(t3, t4); if (!Forbidden(t4, t1) && (!c || G2 - c(t4, t1) > 0) && (*Gain = G2 - C(t4, t1)) > 0) { Swap1(t1, t2, t3); *G0 = G2; return 0; } if (++Breadth2 > MaxBreadth) break; if (GainCriterionUsed && G2 - Precision < t4->Cost) continue; if (!Backtracking || Swaps > 0) { if (G2 > BestG2 && Swaps < MaxSwaps && Excludable(t3, t4) && (!InInputTour(t3, t4) || !Near(t3, t4))) { T3 = t3; T4 = t4; BestG2 = G2; } } else if (MaxSwaps > 0) { GainType G = G2; Node *t = t4; Make2OptMove(t1, t2, t3, t4); Exclude(t1, t2); Exclude(t3, t4); while ((t = BestSubsequentMove(t1, t, &G, Gain))); if (*Gain > 0) return 0; RestoreTour(); if (t2 != SUC(t1)) Reversed ^= 1; } } *Gain = 0; if (T4) { /* Make the best 2-opt move */ Swap1(t1, t2, T3); Exclude(t1, t2); Exclude(T3, T4); *G0 = BestG2; } return T4; }
GainType LinKernighan() { Node *t1, *t2, *SUCt1; GainType Gain, G0, Cost; int X2, i, it = 0; Candidate *Nt1; Segment *S; SSegment *SS; double EntryTime = GetTime(); Reversed = 0; S = FirstSegment; i = 0; do { S->Size = 0; S->Rank = ++i; S->Reversed = 0; S->First = S->Last = 0; } while ((S = S->Suc) != FirstSegment); SS = FirstSSegment; i = 0; do { SS->Size = 0; SS->Rank = ++i; SS->Reversed = 0; SS->First = SS->Last = 0; } while ((SS = SS->Suc) != FirstSSegment); FirstActive = LastActive = 0; Swaps = 0; /* Compute the cost of the initial tour, Cost. Compute the corresponding hash value, Hash. Initialize the segment list. Make all nodes "active" (so that they can be used as t1). */ Cost = 0; Hash = 0; i = 0; t1 = FirstNode; do { t2 = t1->OldSuc = t1->Suc; t1->OldPred = t1->Pred; t1->Rank = ++i; Cost += (t1->SucCost = t2->PredCost = C(t1, t2)) - t1->Pi - t2->Pi; Hash ^= Rand[t1->Id] * Rand[t2->Id]; t1->Cost = INT_MAX; for (Nt1 = t1->CandidateSet; (t2 = Nt1->To); Nt1++) if (t2 != t1->Pred && t2 != t1->Suc && Nt1->Cost < t1->Cost) t1->Cost = Nt1->Cost; t1->Parent = S; S->Size++; if (S->Size == 1) S->First = t1; S->Last = t1; if (SS->Size == 0) SS->First = S; S->Parent = SS; SS->Last = S; if (S->Size == GroupSize) { S = S->Suc; SS->Size++; if (SS->Size == SGroupSize) SS = SS->Suc; } t1->OldPredExcluded = t1->OldSucExcluded = 0; t1->Next = 0; if (KickType == 0 || Kicks == 0 || !InBestTour(t1, t1->Pred) || !InBestTour(t1, t1->Suc)) Activate(t1); } while ((t1 = t1->Suc) != FirstNode); if (S->Size < GroupSize) SS->Size++; Cost /= Precision; if (TraceLevel >= 3 || (TraceLevel == 2 && Cost < BetterCost)) { printff("Cost = " GainFormat, Cost); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.4f%%", 100.0 * (Cost - Optimum) / Optimum); printff(", Time = %0.1f sec. %s\n", fabs(GetTime() - EntryTime), Cost < Optimum ? "<" : Cost == Optimum ? "=" : ""); } PredSucCostAvailable = 1; /* Loop as long as improvements are found */ do { /* Choose t1 as the first "active" node */ while ((t1 = RemoveFirstActive())) { /* t1 is now "passive" */ SUCt1 = SUC(t1); if ((TraceLevel >= 3 || (TraceLevel == 2 && Trial == 1)) && ++it % (Dimension >= 100000 ? 10000 : Dimension >= 10000 ? 1000 : 100) == 0) printff("#%d: Time = %0.1f sec.\n", it, fabs(GetTime() - EntryTime)); /* Choose t2 as one of t1's two neighbors on the tour */ for (X2 = 1; X2 <= 2; X2++) { t2 = X2 == 1 ? PRED(t1) : SUCt1; if (FixedOrCommon(t1, t2) || (RestrictedSearch && Near(t1, t2) && (Trial == 1 || (Trial > BackboneTrials && (KickType == 0 || Kicks == 0))))) continue; G0 = C(t1, t2); /* Try to find a tour-improving chain of moves */ do t2 = Swaps == 0 ? BestMove(t1, t2, &G0, &Gain) : BestSubsequentMove(t1, t2, &G0, &Gain); while (t2); if (Gain > 0) { /* An improvement has been found */ assert(Gain % Precision == 0); Cost -= Gain / Precision; if (TraceLevel >= 3 || (TraceLevel == 2 && Cost < BetterCost)) { printff("Cost = " GainFormat, Cost); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.4f%%", 100.0 * (Cost - Optimum) / Optimum); printff(", Time = %0.1f sec. %s\n", fabs(GetTime() - EntryTime), Cost < Optimum ? "<" : Cost == Optimum ? "=" : ""); } StoreTour(); if (HashSearch(HTable, Hash, Cost)) goto End_LinKernighan; /* Make t1 "active" again */ Activate(t1); break; } RestoreTour(); } } if (HashSearch(HTable, Hash, Cost)) goto End_LinKernighan; HashInsert(HTable, Hash, Cost); /* Try to find improvements using non-sequential 4/5-opt moves */ Gain = 0; if (Gain23Used && (Gain = Gain23()) > 0) { /* An improvement has been found */ assert(Gain % Precision == 0); Cost -= Gain / Precision; StoreTour(); if (TraceLevel >= 3 || (TraceLevel == 2 && Cost < BetterCost)) { printff("Cost = " GainFormat, Cost); if (Optimum != MINUS_INFINITY && Optimum != 0) printff(", Gap = %0.4f%%", 100.0 * (Cost - Optimum) / Optimum); printff(", Time = %0.1f sec. + %s\n", fabs(GetTime() - EntryTime), Cost < Optimum ? "<" : Cost == Optimum ? "=" : ""); } if (HashSearch(HTable, Hash, Cost)) goto End_LinKernighan; } } while (Gain > 0); End_LinKernighan: PredSucCostAvailable = 0; NormalizeNodeList(); NormalizeSegmentList(); return Cost; }
LKH::LKHAlg::Node * LKH::LKHAlg::Best4OptMove(Node * t1, Node * t2, GainType * G0, GainType * Gain) { Node *t3, *t4, *t5, *t6 = 0, *t7, *t8 = 0, *T3 = 0, *T4 = 0, *T5 = 0, *T6 = 0, *T7 = 0, *T8 = 0; Candidate *Nt2, *Nt4, *Nt6; GainType G1, G2, G3, G4, G5, G6, BestG6 = MINUS_INFINITY; int Case6 = 0, Case8 = 0, BestCase8 = 0, X4, X6, X8; int Breadth2 = 0, Breadth4, Breadth6; *Gain = 0; if (SUC(t1) != t2) Reversed ^= 1; /* * Determine (T3,T4,T5,T6,T7,T8) = (t3,t4,t5,t6,t7,t8) * such that * * G8 = *G0 - C(t2,T3) + C(T3,T4) * - C(T4,T5) + C(T5,T6) * - C(T6,T7) + C(T7,T8) * * is maximum (= BestG6), and (T7,T8) has not previously been included. * If during this process a legal move with *Gain > 0 is found, then make * the move and exit Best4OptMove immediately. */ /* Choose (t2,t3) as a candidate edge emanating from t2 */ for (Nt2 = t2->CandidateSet; (t3 = Nt2->To); Nt2++) { if (t3 == t2->Pred || t3 == t2->Suc || ((G1 = *G0 - Nt2->Cost) <= 0 && GainCriterionUsed && ProblemType != HCP && ProblemType != HPP)) continue; if (++Breadth2 > MaxBreadth) break; /* Choose t4 as one of t3's two neighbors on the tour */ for (X4 = 1; X4 <= 2; X4++) { t4 = X4 == 1 ? PRED(t3) : SUC(t3); if (FixedOrCommon(t3, t4)) continue; G2 = G1 + (this->*C)(t3, t4); if (X4 == 1 && !Forbidden(t4, t1) && (!c || G2 - (this->*c)(t4, t1) > 0) && (*Gain = G2 - (this->*C)(t4, t1)) > 0) { Swap1(t1, t2, t3); return 0; } if (Backtracking && !Excludable(t3, t4)) continue; Breadth4 = 0; /* Choose (t4,t5) as a candidate edge emanating from t4 */ for (Nt4 = t4->CandidateSet; (t5 = Nt4->To); Nt4++) { if (t5 == t4->Pred || t5 == t4->Suc || ((G3 = G2 - Nt4->Cost) <= 0 && GainCriterionUsed && ProblemType != HCP && ProblemType != HPP)) continue; if (++Breadth4 > MaxBreadth) break; /* Choose t6 as one of t5's two neighbors on the tour */ for (X6 = 1; X6 <= 2; X6++) { if (X4 == 1) { if (X6 == 1) { Case6 = 1 + !BETWEEN(t2, t5, t4); t6 = Case6 == 1 ? SUC(t5) : PRED(t5); } else { t6 = t6 == t5->Pred ? t5->Suc : t5->Pred; if ((t5 == t1 && t6 == t2) || (t5 == t2 && t6 == t1)) continue; Case6 += 2; } } else if (BETWEEN(t2, t5, t3)) { Case6 = 4 + X6; t6 = X6 == 1 ? SUC(t5) : PRED(t5); if (t6 == t1) continue; } else { if (X6 == 2) break; Case6 = 7; t6 = PRED(t5); if (t6 == t2) continue; } if (FixedOrCommon(t5, t6)) continue; G4 = G3 + (this->*C)(t5, t6); if ((Case6 <= 2 || Case6 == 5 || Case6 == 6) && !Forbidden(t6, t1) && (!c || G4 - (this->*c)(t6, t1) > 0) && (*Gain = G4 - (this->*C)(t6, t1)) > 0) { Make3OptMove(t1, t2, t3, t4, t5, t6, Case6); return 0; } if (Backtracking && !Excludable(t5, t6)) continue; Breadth6 = 0; /* Choose (t6,t7) as a candidate edge emanating from t6 */ for (Nt6 = t6->CandidateSet; (t7 = Nt6->To); Nt6++) { if (t7 == t6->Pred || t7 == t6->Suc || (t6 == t2 && t7 == t3) || (t6 == t3 && t7 == t2) || ((G5 = G4 - Nt6->Cost) <= 0 && GainCriterionUsed && ProblemType != HCP && ProblemType != HPP)) continue; if (++Breadth6 > MaxBreadth) break; /* Choose t8 as one of t7's two neighbors on the tour */ for (X8 = 1; X8 <= 2; X8++) { if (X8 == 1) { Case8 = Case6; t8 = 0; switch (Case6) { case 1: t8 = BETWEEN(t2, t7, t5) ? SUC(t7) : PRED(t7); break; case 2: t8 = BETWEEN(t3, t7, t6) ? SUC(t7) : PRED(t7); break; case 3: if (BETWEEN(t5, t7, t4)) t8 = SUC(t7); break; case 4: if (BETWEEN(t2, t7, t5)) t8 = BETWEEN(t2, t7, t4) ? SUC(t7) : PRED(t7); break; case 5: t8 = PRED(t7); break; case 6: t8 = BETWEEN(t2, t7, t3) ? SUC(t7) : PRED(t7); break; case 7: if (BETWEEN(t2, t7, t3)) t8 = SUC(t7); break; } if (t8 == 0) break; } else { if (Case6 != 3 && Case6 != 4 && Case6 != 7) break; t8 = t8 == t7->Pred ? t7->Suc : t7->Pred; Case8 += 8; } if (t8 == t1 || (t7 == t3 && t8 == t4) || (t7 == t4 && t8 == t3)) continue; if (FixedOrCommon(t7, t8)) continue; G6 = G5 + (this->*C)(t7, t8); if (t8 != t1 && !Forbidden(t8, t1) && (!c || G6 - (this->*c)(t8, t1) > 0) && (*Gain = G6 - (this->*C)(t8, t1)) > 0) { Make4OptMove(t1, t2, t3, t4, t5, t6, t7, t8, Case8); return 0; } if (GainCriterionUsed && G6 - Precision < t8->Cost) continue; if (!Backtracking || Swaps > 0) { if ((G6 > BestG6 || (G6 == BestG6 && !Near(t7, t8) && Near(T7, T8))) && Swaps < MaxSwaps && Excludable(t7, t8) && !InInputTour(t7, t8)) { /* Ignore the move if the gain does not vary */ if (RestrictedSearch && ProblemType != HCP && ProblemType != HPP && G2 - t4->Pi == G4 - t6->Pi && G4 - t6->Pi == G6 - t8->Pi && G3 + t5->Pi == G1 + t3->Pi && G5 + t7->Pi == G3 + t5->Pi) continue; T3 = t3; T4 = t4; T5 = t5; T6 = t6; T7 = t7; T8 = t8; BestCase8 = Case8; BestG6 = G6; } } else if (MaxSwaps > 0) { GainType G = G6; Node *t = t8; Make4OptMove(t1, t2, t3, t4, t5, t6, t7, t8, Case8); Exclude(t1, t2); Exclude(t3, t4); Exclude(t5, t6); Exclude(t7, t8); while ((t = (this->*BestSubsequentMove)(t1, t, &G, Gain))); if (*Gain > 0) return 0; RestoreTour(); if (t2 != SUC(t1)) Reversed ^= 1; } } } } } } } *Gain = 0; if (T8) { /* Make the best 4-opt move */ Make4OptMove(t1, t2, T3, T4, T5, T6, T7, T8, BestCase8); Exclude(t1, t2), Exclude(T3, T4); Exclude(T5, T6); Exclude(T7, T8); *G0 = BestG6; } return T8; }
int main() { Average data(0.0); assert(data.size() == 1); assert(data.max_size() == 6); assert(data.getHistoricValue(0) == 0.0); assert(data.getAverage() == 0.0); data.setValue(1.1); assert(data.size() == 2); assert(data.getValue() == 1.1); assert(data.getHistoricValue(0) == 1.1); assert(data.getHistoricValue(1) == 0.0); assert(data.getAverage() == Near(1.1/2)); data.setValue(2.2); assert(data.size() == 3); assert(data.getValue() == 2.2); assert(data.getHistoricValue(0) == 2.2); assert(data.getHistoricValue(1) == 1.1); assert(data.getHistoricValue(2) == 0.0); assert(data.getAverage() == Near(3.3/3)); data.setValue(3.3); assert(data.size() == 4); assert(data.getValue() == 3.3); assert(data.getHistoricValue(0) == 3.3); assert(data.getHistoricValue(1) == 2.2); assert(data.getHistoricValue(2) == 1.1); assert(data.getHistoricValue(3) == 0.0); assert(data.getAverage() == Near(6.6/4)); data.setValue(4.4); assert(data.size() == 5); assert(data.getValue() == 4.4); assert(data.getHistoricValue(0) == 4.4); assert(data.getHistoricValue(1) == 3.3); assert(data.getHistoricValue(2) == 2.2); assert(data.getHistoricValue(3) == 1.1); assert(data.getHistoricValue(4) == 0.0); assert(data.getAverage() == Near(11.0/5)); data.setValue(5.5); assert(data.size() == 6); assert(data.getValue() == 5.5); assert(data.getHistoricValue(0) == 5.5); assert(data.getHistoricValue(1) == 4.4); assert(data.getHistoricValue(2) == 3.3); assert(data.getHistoricValue(3) == 2.2); assert(data.getHistoricValue(4) == 1.1); assert(data.getHistoricValue(5) == 0.0); assert(data.getAverage() == Near(16.5/6)); data.setValue(6.6); assert(data.size() == 6); assert(data.getValue() == 6.6); assert(data.getHistoricValue(0) == 6.6); assert(data.getHistoricValue(1) == 5.5); assert(data.getHistoricValue(2) == 4.4); assert(data.getHistoricValue(3) == 3.3); assert(data.getHistoricValue(4) == 2.2); assert(data.getHistoricValue(5) == 1.1); #ifdef STATISTIC_OF_HISTORY_ONLY assert(data.getAverage() == Near(23.1/6)); #else assert(data.getAverage() == Near(23.1/7)); #endif data.setValue(7.7); assert(data.size() == 6); assert(data.getValue() == 7.7); assert(data.getHistoricValue(0) == 7.7); assert(data.getHistoricValue(1) == 6.6); assert(data.getHistoricValue(2) == 5.5); assert(data.getHistoricValue(3) == 4.4); assert(data.getHistoricValue(4) == 3.3); assert(data.getHistoricValue(5) == 2.2); #ifdef STATISTIC_OF_HISTORY_ONLY assert(data.getAverage() == Near(29.7/6)); #else assert(data.getAverage() == Near(30.8/8)); #endif data.clearHistory(); assert(data.size() == 1); assert(data.getValue() == 7.7); assert(data.getHistoricValue(0) == 7.7); #ifdef STATISTIC_OF_HISTORY_ONLY assert(data.getAverage() == Near(7.7/1)); #else assert(data.getAverage() == 30.8/8); #endif std::cout << "ALL TESTS PASSED" << std::endl; }
int main() { Statistic data(0.0); assert(data.historySize() == 1); assert(data.maxHistory() == 6); assert(data.getHistoricValue(0) == 0.0); assert(data.getAverage() == 0.0); assert(data.getMinimum() == 0.0); assert(data.getMaximum() == 0.0); data.setValue(1.1); assert(data.historySize() == 2); assert(data.getValue() == 1.1); assert(data.getHistoricValue(0) == 1.1); assert(data.getHistoricValue(1) == 0.0); assert(data.getAverage() == Near(1.1/2)); assert(data.getMinimum() == 0.0); assert(data.getMaximum() == 1.1); data.setValue(2.2); assert(data.historySize() == 3); assert(data.getValue() == 2.2); assert(data.getHistoricValue(0) == 2.2); assert(data.getHistoricValue(1) == 1.1); assert(data.getHistoricValue(2) == 0.0); assert(data.getAverage() == Near(3.3/3)); assert(data.getMinimum() == 0.0); assert(data.getMaximum() == 2.2); data.setValue(3.3); assert(data.historySize() == 4); assert(data.getValue() == 3.3); assert(data.getHistoricValue(0) == 3.3); assert(data.getHistoricValue(1) == 2.2); assert(data.getHistoricValue(2) == 1.1); assert(data.getHistoricValue(3) == 0.0); assert(data.getAverage() == Near(6.6/4)); assert(data.getMinimum() == 0.0); assert(data.getMaximum() == 3.3); data.setValue(4.4); assert(data.historySize() == 5); assert(data.getValue() == 4.4); assert(data.getHistoricValue(0) == 4.4); assert(data.getHistoricValue(1) == 3.3); assert(data.getHistoricValue(2) == 2.2); assert(data.getHistoricValue(3) == 1.1); assert(data.getHistoricValue(4) == 0.0); assert(data.getAverage() == Near(11.0/5)); assert(data.getMinimum() == 0.0); assert(data.getMaximum() == 4.4); data.setValue(5.5); assert(data.historySize() == 6); assert(data.getValue() == 5.5); assert(data.getHistoricValue(0) == 5.5); assert(data.getHistoricValue(1) == 4.4); assert(data.getHistoricValue(2) == 3.3); assert(data.getHistoricValue(3) == 2.2); assert(data.getHistoricValue(4) == 1.1); assert(data.getHistoricValue(5) == 0.0); assert(data.getAverage() == Near(16.5/6)); assert(data.getMinimum() == 0.0); assert(data.getMaximum() == 5.5); data.setValue(6.6); assert(data.historySize() == 6); assert(data.getValue() == 6.6); assert(data.getHistoricValue(0) == 6.6); assert(data.getHistoricValue(1) == 5.5); assert(data.getHistoricValue(2) == 4.4); assert(data.getHistoricValue(3) == 3.3); assert(data.getHistoricValue(4) == 2.2); assert(data.getHistoricValue(5) == 1.1); assert(data.getAverage() == Near(23.1/6)); assert(data.getMinimum() == 1.1); assert(data.getMaximum() == 6.6); data.setValue(-.7); assert(data.historySize() == 6); assert(data.getValue() == -.7); assert(data.getHistoricValue(0) == -.7); assert(data.getHistoricValue(1) == 6.6); assert(data.getHistoricValue(2) == 5.5); assert(data.getHistoricValue(3) == 4.4); assert(data.getHistoricValue(4) == 3.3); assert(data.getHistoricValue(5) == 2.2); assert(data.getAverage() == Near(21.3/6)); assert(data.getMinimum() == -.7); assert(data.getMaximum() == 6.6); data.clearHistory(); assert(data.historySize() == 1); assert(data.getValue() == -.7); assert(data.getHistoricValue(0) == -.7); assert(data.getAverage() == Near(-.7/1)); assert(data.getMinimum() == -.7); assert(data.getMaximum() == -.7); std::cout << "ALL TESTS PASSED" << std::endl; }
bool Near(Position one, Position two, int distance = 1) { return (Near(one.x, two.x, distance) && Near(one.y, two.y, distance)); }
Node *Best3OptMove(Node * t1, Node * t2, GainType * G0, GainType * Gain) { Node *t3, *t4, *t5, *t6, *T3 = 0, *T4 = 0, *T5 = 0, *T6 = 0; Candidate *Nt2, *Nt4; GainType G1, G2, G3, G4, BestG4 = MINUS_INFINITY; int Case6, BestCase6 = 0, X4, X6; int Breadth2 = 0, Breadth4; if (SUC(t1) != t2) Reversed ^= 1; /* * Determine (T3,T4,T5,T6) = (t3,t4,t5,t6) * such that * * G4 = *G0 - C(t2,T3) + C(T3,T4) * - C(T4,T5) + C(T5,T6) * * is maximum (= BestG4), and (T5,T6) has not previously been included. * If during this process a legal move with *Gain > 0 is found, then make * the move and exit Best3OptMove immediately. */ /* Choose (t2,t3) as a candidate edge emanating from t2 */ for (Nt2 = t2->CandidateSet; (t3 = Nt2->To); Nt2++) { if (t3 == t2->Pred || t3 == t2->Suc || ((G1 = *G0 - Nt2->Cost) <= 0 && GainCriterionUsed && ProblemType != HCP && ProblemType != HPP)) continue; if (++Breadth2 > MaxBreadth) break; /* Choose t4 as one of t3's two neighbors on the tour */ for (X4 = 1; X4 <= 2; X4++) { t4 = X4 == 1 ? PRED(t3) : SUC(t3); if (FixedOrCommon(t3, t4)) continue; G2 = G1 + C(t3, t4); if (X4 == 1 && !Forbidden(t4, t1) && (!c || G2 - c(t4, t1) > 0) && (*Gain = G2 - C(t4, t1)) > 0) { Swap1(t1, t2, t3); return 0; } if (Backtracking && !Excludable(t3, t4)) continue; Breadth4 = 0; /* Choose (t4,t5) as a candidate edge emanating from t4 */ for (Nt4 = t4->CandidateSet; (t5 = Nt4->To); Nt4++) { if (t5 == t4->Pred || t5 == t4->Suc || ((G3 = G2 - Nt4->Cost) <= 0 && GainCriterionUsed) || (X4 == 2 && !BETWEEN(t2, t5, t3))) continue; if (++Breadth4 > MaxBreadth) break; /* Choose t6 as one of t5's two neighbors on the tour */ for (X6 = 1; X6 <= X4; X6++) { if (X4 == 1) { Case6 = 1 + !BETWEEN(t2, t5, t4); t6 = Case6 == 1 ? SUC(t5) : PRED(t5); } else { Case6 = 4 + X6; t6 = X6 == 1 ? SUC(t5) : PRED(t5); if (t6 == t1) continue; } if (FixedOrCommon(t5, t6)) continue; G4 = G3 + C(t5, t6); if (!Forbidden(t6, t1) && (!c || G4 - c(t6, t1) > 0) && (*Gain = G4 - C(t6, t1)) > 0) { Make3OptMove(t1, t2, t3, t4, t5, t6, Case6); return 0; } if (GainCriterionUsed && G4 - Precision < t6->Cost) continue; if (!Backtracking || Swaps > 0) { if (G4 > BestG4 && Swaps < MaxSwaps && Excludable(t5, t6) && (!InInputTour(t5, t6) || !Near(t5, t6))) { /* Ignore the move if the gain does not vary */ if (RestrictedSearch && ProblemType != HCP && ProblemType != HPP && G2 - t4->Pi == G4 - t6->Pi && G3 + t5->Pi == G1 + t3->Pi) continue; T3 = t3; T4 = t4; T5 = t5; T6 = t6; BestCase6 = Case6; BestG4 = G4; } } else if (MaxSwaps > 0) { GainType G = G4; Node *t = t6; Make3OptMove(t1, t2, t3, t4, t5, t6, Case6); Exclude(t1, t2); Exclude(t3, t4); Exclude(t5, t6); while ((t = BestSubsequentMove(t1, t, &G, Gain))); if (*Gain > 0) return 0; RestoreTour(); if (t2 != SUC(t1)) Reversed ^= 1; } } } } } *Gain = 0; if (T6) { /* Make the best 3-opt move */ Make3OptMove(t1, t2, T3, T4, T5, T6, BestCase6); Exclude(t1, t2); Exclude(T3, T4); Exclude(T5, T6); *G0 = BestG4; } return T6; }