@@ -707,38 +707,40 @@ 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 ;
714713 const float t_factor
715714 = std::exp (std::log (min_t / init_temperature_) / max_num_step_);
716715
717- if (isValid ()) {
718- updateBestValidResult (cost);
719- }
716+ updateBestResult (cost);
720717
721718 while (step <= max_num_step_) {
722719 for (int i = 0 ; i < num_perturb_per_step_; i++) {
723720 saveState ();
724721 perturb ();
725722 cost = calNormCost ();
726723
727- const bool keep_result
728- = cost < pre_cost
729- || best_valid_result_. sequence_pair . pos_sequence . empty ();
730- if ( isValid () && keep_result) {
731- updateBestValidResult (cost) ;
724+ const bool is_valid = isValid ();
725+ const bool improved = cost < pre_cost || best_result_. empty ();
726+ if ((!is_best_result_valid_ || is_valid) && improved) {
727+ updateBestResult (cost);
728+ is_best_result_valid_ = is_valid ;
732729 }
733730
734- delta_cost = cost - pre_cost;
735- const float num = distribution_ (generator_);
736- const float prob
737- = (delta_cost > 0.0 ) ? std::exp ((-1 ) * delta_cost / temperature) : 1 ;
738- if (num < prob) {
731+ const float delta_cost = cost - pre_cost;
732+ if (delta_cost <= 0 ) {
733+ // always accept improvements
739734 pre_cost = cost;
740735 } else {
741- restoreState ();
736+ // probabilistically accept degradations for hill climbing
737+ const float num = distribution_ (generator_);
738+ const float prob = std::exp (-delta_cost / temperature);
739+ if (num < prob) {
740+ pre_cost = cost;
741+ } else {
742+ restoreState ();
743+ }
742744 }
743745 }
744746
@@ -754,40 +756,42 @@ void SimulatedAnnealingCore<T>::fastSA()
754756 graphics_->doNotSkip ();
755757 }
756758 calPenalty ();
759+ cost = calNormCost ();
757760
758- if (!best_valid_result_.sequence_pair .pos_sequence .empty ()
759- && (!isValid () || best_valid_result_.cost < calNormCost ())) {
760- useBestValidResult ();
761+ const bool is_valid = isValid ();
762+ const bool improved = cost < best_result_.cost || best_result_.empty ();
763+ if ((is_best_result_valid_ && !is_valid) || !improved) {
764+ useBestResult ();
761765 }
762766}
763767
764768template <class T >
765- void SimulatedAnnealingCore<T>::updateBestValidResult (const float cost)
769+ void SimulatedAnnealingCore<T>::updateBestResult (const float cost)
766770{
767- best_valid_result_ .sequence_pair .pos_sequence = pos_seq_;
768- best_valid_result_ .sequence_pair .neg_sequence = neg_seq_;
771+ best_result_ .sequence_pair .pos_sequence = pos_seq_;
772+ best_result_ .sequence_pair .neg_sequence = neg_seq_;
769773
770774 if constexpr (std::is_same_v<T, SoftMacro>) {
771775 for (const int macro_id : pos_seq_) {
772776 SoftMacro& macro = macros_[macro_id];
773- best_valid_result_ .macro_id_to_width [macro_id] = macro.getWidth ();
777+ best_result_ .macro_id_to_width [macro_id] = macro.getWidth ();
774778 }
775779 }
776780
777- best_valid_result_ .cost = cost;
781+ best_result_ .cost = cost;
778782}
779783
780784template <class T >
781- void SimulatedAnnealingCore<T>::useBestValidResult ()
785+ void SimulatedAnnealingCore<T>::useBestResult ()
782786{
783- pos_seq_ = best_valid_result_ .sequence_pair .pos_sequence ;
784- neg_seq_ = best_valid_result_ .sequence_pair .neg_sequence ;
787+ pos_seq_ = best_result_ .sequence_pair .pos_sequence ;
788+ neg_seq_ = best_result_ .sequence_pair .neg_sequence ;
785789
786790 if constexpr (std::is_same_v<T, SoftMacro>) {
787791 for (const int macro_id : pos_seq_) {
788792 SoftMacro& macro = macros_[macro_id];
789793 const float valid_result_width
790- = best_valid_result_ .macro_id_to_width .at (macro_id);
794+ = best_result_ .macro_id_to_width .at (macro_id);
791795
792796 if (macro.isMacroCluster ()) {
793797 const float valid_result_height = macro.getArea () / valid_result_width;
0 commit comments