1. 随机洗牌算法
https://blog.csdn.net/qq_26399665/article/details/79831490
Fisher-Yates Shuffle算法
最早提出这个洗牌方法的是 Ronald A. Fisher 和 Frank Yates,即 Fisher–Yates Shuffle,其基本思想就是从原始数组中随机取一个之前没取过的数字到新的数组中,具体如下:
1. 初始化原始数组和新数组,原始数组长度为n(已知);
2. 从还没处理的数组(假如还剩k个)中,随机产生一个[0, k)之间的数字p(假设数组从0开始);
3. 从剩下的k个数中把第p个数取出;
4. 重复步骤2和3直到数字全部取完;
5. 从步骤3取出的数字序列便是一个打乱了的数列。
下面证明其随机性,即每个元素被放置在新数组中的第i个位置是1/n(假设数组大小是n)。
证明:一个元素m被放入第i个位置的概率P = 前i-1个位置选择元素时没有选中m的概率 * 第i个位置选中m的概率,注意
这里,第i个位置是从后往前数的
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> a = {1,2,3,4,5,6,7,8};
// srand((unsigned)time(NULL));
int len = a.size();
for (int i = len - 1; i >= 0; i--)
{
swap(a[rand() % (i + 1)], a[i]);
}
for (int i = 0; i < len; i++) cout << a[i] << " ";
return 0;
}
2.银行家算法
https://www.cnblogs.com/chuxiuhong/p/6103928.html
算法流程
安全判定算法
1.初始化
Work = Available(动态记录当前剩余资源) Finish[i] = false(设定所有进程均未完成)
2.查找可执行进程Pi(未完成但目前剩余资源可满足其需要,这样的进程是能够完成的。
Finish[i] = false Need[i] <= Work 如果没有这样的进程Pi,则跳转到第4步
3.(若有则)Pi一定能完成,并归还其占用的资源,即:
Finish[i] = true Work = Work +Allocation[i] GOTO 第2步,继续查找
4.如果所有进程Pi都是能完成的,即Finish[i]=ture
则系统处于安全状态,否则系统处于不安全状态
示例#
举个实际例子,假设下面的初始状态:
process Allocation Need Available
A B C A B C A B C
P0 0 1 0 7 4 3 3 3 2
P1 2 0 0 1 2 2
P2 3 0 2 6 0 0
P3 2 1 1 0 1 1
P4 0 0 2 4 3 1
首先,进入算法第一步,初始化。
那么Work = Available = [3 3 2]
首先看P0:
P0的Need为[7 4 3],Available不能满足,于是跳过去
P1的Need为[1 2 2]可以满足,我们令Work = Allocation[P1] + Work
此时Work = [5 3 2]
再看P2,P2的Need为[6 0 0],那么现有资源不满足。跳过去。
看P3,那么看P3,Work可以满足。那么令Work = Allocation[P3] + Work,此时Work = [7 4 3]
再看P4,Work可以满足。令Work = Allocation[P4] + Work ,此时Work = [7 4 5]
到此第一轮循环完毕,由于找到了可用进程,那么进入第二轮循环。
看P0,Work此时可以满足。令Work = Allocation[P0] + Work ,此时Work = [7 5 5]
再看P2,此时Work可以满足P2。令Work = Allocation[P2] + Work , 此时Work = [10 5 7]
至此,算法运行完毕。找到安全序列<P1,P3,P4,P0,P2>,证明此时没有死锁危险。(安全序列未必唯一)
资源请求算法#
之前说完了怎么判定当前情况是否安全,下面就是说当有进程新申请资源的时候如何处理。
我们将第i个进程请求的资源数记为Requests[i]
算法流程:
1.如果Requests[i]<=Need[i],则转到第二步。否则,返回异常。这一步是控制进程申请的资源不得大于需要的资源
2.如果Requests[i]<=Available,则转到第三步,否则Pi等待资源。
3.如果满足前两步,那么做如下操作:
Available = Available -Requests[i]
Allocation = Allocation[i]+Requests[i]
Need[i]=Need[i]-Requests[i]
调用安全判定算法,检查是否安全
if(安全)
{
申请成功,资源分配
}
else
{
申请失败,资源撤回。第三步前几个操作进行逆操作
}