@@ -707,7 +707,6 @@ void SimulatedAnnealingCore<T>::fastSA()
707707{
708708 float cost = calNormCost ();
709709 float pre_cost = cost;
710- float delta_cost = 0.0 ;
711710 int step = 1 ;
712711 float temperature = init_temperature_;
713712 const float min_t = 1e-10 ;
@@ -718,31 +717,34 @@ void SimulatedAnnealingCore<T>::fastSA()
718717 // as it is too expensive
719718 notch_weight_ = 0.0 ;
720719
721- if (isValid ()) {
722- updateBestValidResult (cost);
723- }
720+ updateBestResult (cost);
724721
725722 while (step <= max_num_step_) {
726723 for (int i = 0 ; i < num_perturb_per_step_; i++) {
727724 saveState ();
728725 perturb ();
729726 cost = calNormCost ();
730727
731- const bool keep_result
732- = cost < pre_cost
733- || best_valid_result_. sequence_pair . pos_sequence . empty ();
734- if ( isValid () && keep_result) {
735- updateBestValidResult (cost) ;
728+ const bool is_valid = isValid ();
729+ const bool improved = cost < pre_cost || best_result_. empty ();
730+ if ((!is_best_result_valid_ || is_valid) && improved) {
731+ updateBestResult (cost);
732+ is_best_result_valid_ = is_valid ;
736733 }
737734
738- delta_cost = cost - pre_cost;
739- const float num = distribution_ (generator_);
740- const float prob
741- = (delta_cost > 0.0 ) ? std::exp ((-1 ) * delta_cost / temperature) : 1 ;
742- if (num < prob) {
735+ const float delta_cost = cost - pre_cost;
736+ if (delta_cost <= 0 ) {
737+ // always accept improvements
743738 pre_cost = cost;
744739 } else {
745- restoreState ();
740+ // probabilistically accept degradations for hill climbing
741+ const float num = distribution_ (generator_);
742+ const float prob = std::exp (-delta_cost / temperature);
743+ if (num < prob) {
744+ pre_cost = cost;
745+ } else {
746+ restoreState ();
747+ }
746748 }
747749 }
748750
@@ -765,40 +767,42 @@ void SimulatedAnnealingCore<T>::fastSA()
765767 graphics_->doNotSkip ();
766768 }
767769 calPenalty ();
770+ cost = calNormCost ();
768771
769- if (!best_valid_result_.sequence_pair .pos_sequence .empty ()
770- && (!isValid () || best_valid_result_.cost < calNormCost ())) {
771- useBestValidResult ();
772+ const bool is_valid = isValid ();
773+ const bool improved = cost < best_result_.cost || best_result_.empty ();
774+ if ((is_best_result_valid_ && !is_valid) || !improved) {
775+ useBestResult ();
772776 }
773777}
774778
775779template <class T >
776- void SimulatedAnnealingCore<T>::updateBestValidResult (const float cost)
780+ void SimulatedAnnealingCore<T>::updateBestResult (const float cost)
777781{
778- best_valid_result_ .sequence_pair .pos_sequence = pos_seq_;
779- best_valid_result_ .sequence_pair .neg_sequence = neg_seq_;
782+ best_result_ .sequence_pair .pos_sequence = pos_seq_;
783+ best_result_ .sequence_pair .neg_sequence = neg_seq_;
780784
781785 if constexpr (std::is_same_v<T, SoftMacro>) {
782786 for (const int macro_id : pos_seq_) {
783787 SoftMacro& macro = macros_[macro_id];
784- best_valid_result_ .macro_id_to_width [macro_id] = macro.getWidth ();
788+ best_result_ .macro_id_to_width [macro_id] = macro.getWidth ();
785789 }
786790 }
787791
788- best_valid_result_ .cost = cost;
792+ best_result_ .cost = cost;
789793}
790794
791795template <class T >
792- void SimulatedAnnealingCore<T>::useBestValidResult ()
796+ void SimulatedAnnealingCore<T>::useBestResult ()
793797{
794- pos_seq_ = best_valid_result_ .sequence_pair .pos_sequence ;
795- neg_seq_ = best_valid_result_ .sequence_pair .neg_sequence ;
798+ pos_seq_ = best_result_ .sequence_pair .pos_sequence ;
799+ neg_seq_ = best_result_ .sequence_pair .neg_sequence ;
796800
797801 if constexpr (std::is_same_v<T, SoftMacro>) {
798802 for (const int macro_id : pos_seq_) {
799803 SoftMacro& macro = macros_[macro_id];
800804 const float valid_result_width
801- = best_valid_result_ .macro_id_to_width .at (macro_id);
805+ = best_result_ .macro_id_to_width .at (macro_id);
802806
803807 if (macro.isMacroCluster ()) {
804808 const float valid_result_height = macro.getArea () / valid_result_width;
0 commit comments