1. 带余数的除法
设a,b∈Z,a≠0,那么,一定存在唯一的一对q,r∈Z,使得 b=qa+r, 0≤r<|a|
2. 同余
设0≠m∈Z,a,b∈Z,如果m|b-a,就称b同余于a,记做b≡a(mod m
由此可见,同余也就是带余数除法的另一种表示方式b-a=mr, 即b=mr+a
3. 同余类(剩余类)
设0≠m∈Z,Z中的全体元素可以按对模m是否同余分为若干个两两不相交的等价类,以ã或a mod m表示Z中所有同余于a模m的元素组成的等价类,它称为模m的同余类或剩余类
4. 完全剩余系
在模m的每一个剩余类中取定一个元素作为代表,这样得到的R(m)个数称为是模m的一个完全剩余系
5. 最小完全剩余系
模m的完全剩余系的一般形式是aj=j+qjm, j=0,1,2,...,m-1, 其中qj∈Z任意取定,当qj为0时,则可得到一个最小完全剩余系{0,1,2,...,m-1}
那么,完全剩余系有什么用呢?一个简单的应用,是用来实现洗牌,只要能得到一个乱序的完全剩余系,那么洗牌将变得很容易。要想得到一个乱序的剩余类,则可参考下面的定理:
对于任意的n∈Z,当x遍历模m的一个完全剩余系时,x+n也遍历模m的一个完全剩余系
用C#实现
ResidualTheorem
public class ResidualTheorem
{
protected List<int> residualSeries;
protected int extra;
protected int baseNum;
protected int lastBaseNum;
protected int lastExtra;
public ResidualTheorem(int len)
{
lastBaseNum = Assembly.GetCallingAssembly().GetHashCode();
extra = 1;
lastExtra = 1;
residualSeries = new List<int>();
for (int i = 0; i < len; i++)
{
residualSeries.Add(i);
}
}
public void Shuffle()
{
Random rdm = new Random();
baseNum = lastBaseNum + 1;
if (baseNum <= 0) baseNum = 1;
extra = lastExtra + 1;
if (extra <= 0) extra = 1;
int[] indexes = Randomized(residualSeries.Count);
lastExtra = extra;
List<int> tmp = new List<int>();
foreach (int index in indexes)
{
tmp.Add(residualSeries[index]);
}
residualSeries = tmp;
extra = rdm.Next(1, 1000);
}
private int[] Randomized(int count)
{
int[] indexes = new int[count];
for (int i = 0; i < count; i++)
{
indexes[i] = EquationVendor(i) % count;
}
return indexes;
}
private int EquationVendor(int index)
{
return (baseNum * index + extra);
}
public override string ToString()
{
if (residualSeries == null || residualSeries.Count == 0)
{
return base.ToString();
}
StringBuilder sb = new StringBuilder();
foreach (int item in residualSeries)
{
if (sb.Length > 0)
sb.Append("=>");
sb.Append(item);
}
return sb.ToString();
}
}