随机生成关联操作

时间:2011-11-10 19:26:23

标签: algorithm math language-agnostic computer-science abstract-algebra

在抽象代数中,group的概念是相当基础的。要获得一个组,我们需要一组对象,以及一个带3 properties的二进制操作(如果计算闭包,则为4)。如果我们想要随机生成一个给定有限集的组,(即,随机生成一个table给出集合中每个可能的元素组合的结果),那么很容易入侵一个标识元素,并且在逆向中进行攻击,但是随机生成一个关联的操作似乎很难。

我的问题是是否有一些(有效的)方法来随机生成关联操作。我试过随机生成一个操作,然后扰乱非关联关系,使它们一次关联一个,但这似乎并没有真正收敛。有什么想法吗?

4 个答案:

答案 0 :(得分:3)

这仅取决于被认为是“随机”的内容。一种选择是,不是随机生成实际的组操作矩阵,而是从一组已知通过构造关联的组中随机选择一个关联组。

例如:

  • 具有加法模n的整数组{0 ... n-1}是关联组
  • 当p为素数时,乘法模n的整数组{1..p-1}是一个关联组
  • 如果G和H以及两个关联组,则组(G,H)与组操作(g,h)*(g',h')=(g * g',h * h')是关联的
  • 如果G是具有组操作的组*并且c是G中的常数,则定义为g @ g'=(g * c)* g'的操作@关联为(g @ g')@ g''= g * c * g'* c * g''= g @(g'@ g'')

因此,举例来说,为了生成一个大小为N的随机组,得到一个N的因子分解为素数N =(p1,...,pk)(相同的素数可以在该列表中出现多次),然后从它们构建随机乘积q1,...,qn,使得N = q1 * ... * qn,然后对于每个qi,选择一个加法或乘法整数组,添加随机常数,然后使用得到的产品组作为随机关联组。它不会生成具有相同概率的所有关联组,但它仍然是获得随机添加组的随机过程,并且可能比随机填充矩阵要好得多,特别是如果您需要更大的组。

答案 1 :(得分:3)

你可以尝试完成Knuth-Bendix。

实质上,这意味着您可以通过反复识别关联方程的两边来强制您的组关联。

因此,您的论坛会比您的初始尺寸小,但您可以再次添加一些元素并继续。

答案 2 :(得分:1)

二元运算的相关性被定义为三元组(a,b,c)为(a *(b * c))=((a * b)* c)。因此,当您随机定义a * b时,您可以随意选择一个不会导致违反关联性的* b分配;如果没有任何此类作业,请备份并在最后一步选择其他作业。所以......

  MakeRandomAssociative(table[1..N, 1..N], elements[1..N], n)
  0. if n = N + 1 return true
  1. a := elements[n mod N]
  2. b := elements[n // N]
  3. candidates = []
  4. for each c in elements do
  5.    table[n mod N,n // N] = c
  6.    if not violates_associativity(table) then candidates.add(c)
  7. if empty(candidates) return false
  8. else then
  9.    c := remove_random(candidates)
  A.    table[n mod N,n // N] = c
  B.    if MakeRandomAssociative(table, elements, n+1) then
  C.       return true
  D.    else goto 7

这是丑陋和暴力,但是(这里给出的实现可能是错误的)它应该在概念上找到一个在某种意义上应该是“随机”的关联运算符。

答案 3 :(得分:1)

以下是一些在给定集上生成所有二元函数的Prolog谓词:

gen_binop(A,BinOp):-
    cartesian(A,Cart),
    gen_func(Cart,A,BinOp).gen_func(Dom,Rng,Func) :-
    is_set(Dom),
    is_set(Rng),
    gen_func(Dom,Rng,[],Tmp),
    reverse(Tmp,Func).

cartesian(A,B,Cart):-
    findall([X,Y],(member(X,A),member(Y,B)),L),
    list_to_set(L,Cart),!.

gen_func([],_,Func,Func).
gen_func([H|T],Rng,Func1,Func) :-
    member(Y,Rng),
    Func2=[[H,Y]|Func1],
    gen_func(T,Rng,Func2,Func).

Finally, we test to see if any given binary operation is non-associative (and then negate that to find the associative ones):

non_assoc_binop(BinOp):-
    domain(BinOp,D),
    flatten(D,A),
    cartesian3(A,A,A,Cart),
    member([X,Y,Z],Cart),
    eval(BinOp,[X,Y],X1),
    eval(BinOp,[Y,Z],Y2),
    eval(BinOp,[X1,Z],U),
    eval(BinOp,[X,Y2],V),
    U\=V.

eval(F,X,Y) :-
    function(F),
    member([X,Y],F).

function(PL) :-
    pair_list(PL),
    forall(image(PL,_,ImgX),func_image(PL,ImgX)).

image(PL,X,ImgX) :-
    pair_list(PL),
    domain(PL,Dom),
    member(X,Dom),
    findall(Y,member([X,Y],PL),L),
    list_to_set(L,ImgX).

func_image(PL,ImgX) :-
    image(PL,_,ImgX),
    length(ImgX,1).

pair_list([]).
pair_list([[_,_]|T]) :-
    pair_list(T).