随机化乱搞
随机化
rand(c++98)
在 Linux 下 范围 \([0,2^{31})\)
在 Windows 下 范围 \([0,2^{15})\) 更大范围建议 functoin getrand()=rand()<<15|rand();
例题 luogu#P1429 平面最近点对(加强版)
random_shuffle(c++14以前)
在库 #include<algorithm> 中
假设有 a[]
用法 random_shuflle(a+a.begin(),a+a.end(),_rand());
复杂度 \(O(n)\)
例题 luogu#P2210 Haywire (包括了下面)
Sherwood(舍伍德算法)
通过随机化 消除最坏的结果(消除于实例的关系) 使期望时间复杂度趋于平均值
一定可以跑出正确结果 并可以优化复杂度
\(f(x)\) 是解决某个实例的所需时间,\(X_n\) 为实例的集合
有 \(\overline{f(x)}=\dfrac{\sum\limits_{x \in X_n} f(x)}{n}\)
期望 对于 \(\forall x \in X_n\) 有 \(f(x) \to \overline{f(x)}\)
例题 luogu#P2210 Haywire
Las Vegas(拉斯维加斯算法)
随机选择 总能给出正确的结果 但是 也有可能找不到解 优化事件复杂度 好像和上面的差不多
随着运行时间的增加 越有机会找到正解
例题 快速排序
Monte Carlo(蒙特卡罗算法)
一种结合概率统计的算法 非确定性算法
随着运行时间增加 给出正解的概率更高(越近似正解)
正确性 大数定理 样本数量越多,其平均就越趋近于真实值.
例题 求圆周率
模拟退火
其实就是一种蒙特卡罗算法
正确性玄学 大几率跑出正解
多峰函数求极值
定义当前温度 \(T\) ,新状态与已知状态之间的差 \(\Delta E(\Delta E \ge 0)\) 则发生状态转移(更改最优解(接受当前状态))的概率为
开始时 \(T=T_0\) 有降温系数 \(d\) 终止温度 \(T_k\)
一般的 有 \(d \to 1\) \(T_k \to 0\)
每次转移 让 \(T=T\times d\) 直到 \(T<T_k\)
//很抽象的板子
void SA()
{
double t=_originalT();
_data _state();
while(t>_endT())
{
_date _newState();
double now=solve(_newState());
double delta=now-ans;
if(_canAccept(now)) _accept(_newState());
else if(exp(-delta/t)*RAND_MAX>rand()) _accept(_newState());
t=t*_delta();
}
}
可以参考的思路
- 随机交换序列的两个点
- 随机生成一个向量使答案移动一个位置
- 随机生成一个解判断
- 直接当作贪心
例题 luogu#P1337 [JSOI2004]平衡点/吊打XXX
例题 luogu#P2503 [HAOI2006] 均分数据
例题 luogu#P3959 宝藏
例题 luogu#P2538 [SCOI2008]城堡
卡时
卡时 while((double)_startTime()<=LIMIT_TIME) SA();

浙公网安备 33010602011771号