首页 > 其他分享 >模拟退火(退役前怒学骗分)

模拟退火(退役前怒学骗分)

时间:2022-11-25 21:00:56浏览次数:72  
标签:inline return 学骗 int ch 模拟退火 前怒 operator modint

代码是 \([这题](https://www.luogu.com.cn/problem/P3878)\)的。
模拟一个退火的过程,最开始温度为 \(100\) 不断降低,常数可以自己设计这里为 \(99\)。
每次随机一个转移,如果这个转移更优,就直接做,反之做的概率为 \(e^{\Delta f / T}\),\(T\) 为温度, \(e\) 为自然常数, \(\Delta f\) 表示前后函数差值。

#include<bits/stdc++.h>
#define RG register
#define LL long long
#define U(x, y, z) for(RG int x = y; x <= z; ++x)
#define D(x, y, z) for(RG int x = y; x >= z; --x)
#define update(x, y) (x = x + y >= mod ? x + y - mod : x + y)
using namespace std;
const int mod = 998244353;
namespace FastIO {
#define il inline
const int iL = 1 << 25;
char ibuf[iL], *iS = ibuf + iL, *iT = ibuf + iL;
#define GC() (iS == iT) ? \
  (iT = (iS = ibuf) + fread(ibuf, 1, iL, stdin), (iS == iT) ? EOF : *iS++) : *iS++
void read(){}
template<typename _Tp, typename... _Tps>
void read(_Tp &x, _Tps &...Ar) {
    x = 0; char ch = GC(); bool flg = 0;
    for (; !isdigit(ch); ch = GC()) flg |= (ch == '-');
    for (; isdigit(ch); ch = GC()) x = (x << 1) + (x << 3) + (ch ^ 48);
    if (flg) x = -x;
    read(Ar...);    
}
char Out[iL], *iter = Out;
#define Flush() fwrite(Out, 1, iter - Out, stdout); iter = Out
template <class T>il void write(T x, char LastChar = '\n') {
    int c[35], len = 0;
    if (x < 0) {*iter++ = '-'; x = -x;}
    do {c[++len] = x % 10; x /= 10;} while (x);
    while (len) *iter++ = c[len--] + '0';
    *iter++ = LastChar; Flush();
}
template <typename T> inline void writeln(T n){write(n, '\n');}
template <typename T> inline void writesp(T n){write(n, ' ');}
inline char Getchar(){ char ch; for (ch = GC(); !isalpha(ch); ch = GC()); return ch;}
inline void readstr(string &s) { s = ""; static char c = GC(); while (isspace(c)) c = GC(); while (!isspace(c)) s = s + c, c = GC();}
}
using namespace FastIO;
struct modint{
    int x;
    modint(int o=0){x=o;}
    modint &operator = (int o){return x=o,*this;}
    modint &operator +=(modint o){return x=x+o.x>=mod?x+o.x-mod:x+o.x,*this;}
    modint &operator -=(modint o){return x=x-o.x<0?x-o.x+mod:x-o.x,*this;}
    modint &operator *=(modint o){return x=1ll*x*o.x%mod,*this;}
    modint &operator ^=(int b){
        if(b<0)return x=0,*this;
        b%=mod-1;
        modint a=*this,c=1;
        for(;b;b>>=1,a*=a)if(b&1)c*=a;
        return x=c.x,*this;
    }
    modint &operator /=(modint o){return *this *=o^=mod-2;}
    modint &operator +=(int o){return x=x+o>=mod?x+o-mod:x+o,*this;}
    modint &operator -=(int o){return x=x-o<0?x-o+mod:x-o,*this;}
    modint &operator *=(int o){return x=1ll*x*o%mod,*this;}
    modint &operator /=(int o){return *this *= ((modint(o))^=mod-2);}
    template<class I>friend modint operator +(modint a,I b){return a+=b;}
    template<class I>friend modint operator -(modint a,I b){return a-=b;}
    template<class I>friend modint operator *(modint a,I b){return a*=b;}
    template<class I>friend modint operator /(modint a,I b){return a/=b;}
    friend modint operator ^(modint a,int b){return a^=b;}
    friend bool operator ==(modint a,int b){return a.x==b;}
    friend bool operator !=(modint a,int b){return a.x!=b;}
    bool operator ! () {return !x;}
    modint operator - () {return x?mod-x:0;}
};
template <typename T> inline void chkmin(T &x, T y){x = x < y ? x : y;}
template <typename T> inline void chkmax(T &x, T y){x = x > y ? x : y;}
template <typename T> inline T Min(T x, T y){return x < y ? x : y;}
template <typename T> inline T Max(T x, T y){return x > y ? x : y;}
inline void FO(string s){freopen((s + ".in").c_str(), "r", stdin); freopen((s + ".out").c_str(), "w", stdout);}

#define db double
const int N = 55, inf = 1e9;
const db D = 0.99, eps = 1e-8;
int n, m, k, ans = inf, res, tot, now, T;
int v[N];

mt19937 rnd(19260817);

inline void init() {
	ans = inf;
	read(n);
	U(i, 1, n) read(v[i]);
}

inline int calc() {
	int s1 = 0, s2 = 0;
	U(i, 1, n / 2) s1 += v[i];
	U(i, n / 2 + 1, n) s2 += v[i];
	return abs(s1 - s2);
}

inline void solve() {
	db T = 100;
	int p1, p2;
	now = calc();
	while (T > eps) {
		p1 = rnd() % n + 1, p2 = rnd() % n + 1;
		if (p1 == p2) continue ;
		swap(v[p1], v[p2]);
		res = calc();
		chkmin(ans, res);
		if (exp(((db) now - res) / (T)) < (db) (rnd() % (inf + 1)) / inf) swap(v[p1], v[p2]);
		else now = res;
		T *= D;
	}
}

int main(){
	//FO("");
	int T;
	read(T);
	while (T--) {
		init();
		if (n == 1) {
			writeln(v[1]);
			continue ;
		}
		U(i, 1, 50) {
			random_shuffle(v + 1, v + n + 1);
			solve();
		}
		writeln(ans);
	}
	return 0;
}

标签:inline,return,学骗,int,ch,模拟退火,前怒,operator,modint
From: https://www.cnblogs.com/SouthernWay/p/16926329.html

相关文章

  • 【模板】模拟退火 Simulated Annealing
    postedon2021-05-0418:16:24|under学术|source模拟退火适用于:你不会正解能写出估价函数,而且最优解的估价最大/小估价函数不单调,不能二分人品好由于是个带......
  • 模拟退火
    模拟退火(SimulateAnneal)是一种通用概率演算法,在大的搜索空间内寻找最优解,若新的状态优于当前状态,则将新的状态作为最优解,否则以一定概率接受新的状态。模拟退火有三个因......
  • 基于粒子群优化和模拟退火算法增强传统聚类研究(Matlab代码实现)
    ......
  • 模拟退火
    模拟退火很多时候我们会被要求求一些函数的最值问题,但是又因为值域很大,是连续的乃至无穷的,那么搜索是搜不出来的,对于这种问题,一般来说爬山算法是很可以的,比如下边的图......
  • 模拟退火学习笔记
    1.简介模拟退火算法来源于固体退火原理,是一种基于概率的算法,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在......
  • 模拟退火学习笔记
    虽然说考前不应该碰这些随机化算法,容易影响思考,但是还是写一写吧,对于一些问题还是很好用的。概念什么是模拟退火。一句话解释,我们从一个旧状态随机出一个新状态,要从旧状......
  • 分治理 + 模拟退火(因为博客归档有问题,这两个就放一起了,以后有机会搬一下)
    分治本篇重点讲三个东西,线段树分治,点分治,以及CDQ分治。TOP1线段树分治这个算法主要是针对于一些对在线算法很不友好的题,其模型大概是维护一张图,其中的边在某个固定......
  • 学习常用模型及算法1.模拟退火算法
    title:学习常用模型及算法1.模拟退火算法excerpt:学习数学建模常用模型及算法tags:[数学建模,matlab]categories:[学习,数学建模]index_img:https://picture-......
  • 爬山算法&&模拟退火
    constdoubledown=0.996;//降温系数constdoubleeps=1e-15;//终止温度doubleansx,ansy,answ,T;structpoint{intx,y,w;}a[Z];inlinedoubledis(doub......
  • 模拟退火(SA)算法求解容量受限的车辆路径(CVRP)问题MATLAB代码
    SA求解CVRP问题的目标函数是车辆行驶总距离最小,输入数据是solomon算例中的rc208,因为求解的是CVRP问题,所以将rc208中的后三列全部删除,剩余4列,每一列含义如下:[序号X坐标Y坐......