2015-09-22 116 views
0

這是一種奇怪的問題,並且可能不完全適用於堆棧溢出,但我無法在網上找到關於它的任何東西,所以這裏是......生成隨機數學函數

是否有(或什麼是最好的方式)來產生隨機數學函數?通過這個我並不是說我想要一個生成隨機數的函數(行RNG),而是我想動態地創建一些函數,它將一個或多個實際輸入從一個域映射到單個輸出,並使用一些mutate規則。

例如,在最簡單的情況下,我可以通過對x1和x2應用隨機運算符來生成f(x1,x2) -> Y這樣的函數。如F可能是:

f = x1 + x2 
or f = x1 - x2 
or f = x1 * x2 
etc... 

不過,我想能夠包括更復雜的公式,包括三角函數,冪函數,僞隨機常量,可能還有一些微積分的功能,等等......顯然,我不能只是串聯不同的塊以完全隨機的方式,因爲這些函數總是需要總是有效的語法。

這不適用於任何與密碼相關的任何事情,所以它不一定是完美的,但熵越高越好。如果有一個簡單的方法來跟蹤正在執行什麼操作並使它們發生變化,這也會很棒。

我不知道是否有人對此有任何見解,或者如果它甚至是有道理的,但是謝謝你的好意

+0

有太多的方法可以解決這個問題。答案只會變成一個人們喜歡的稻草民意調查。最好的事情是自己做一些關於這個話題的研究,找到兩三個,分析他們,確定他們是否爲你工作,然後試試他們。當你對你試圖做的事情有一個具體的問題時來找我們。 –

+0

這不是一個非常精確的問題。 「生成函數」是什麼意思?你的意思是隻顯示文本的功能?或者生成執行該函數的代碼?你知道你想限制你的生產的操作嗎(例如,它是否包含超越函數,或者只有4個操作+, - ,*,/)?一種方法是編寫一個分析樹生成器,然後將該分析樹翻譯爲一個表達式。分析樹生成器將應用樹中每個節點的隨機性。 – lurker

+0

構建這種類型的生成器時,您需要約束(特別是在深度上,或者生成可能永遠不會終止),否則您最終可能會遇到像下面這樣的術語(例如):gamma(sqrt(gamma(sqrt (sqrt(sin(x + sqrt((gamma(sqrt(x))))))))))))' –

回答

0

謝謝大家的幫助。我最終做的是沿着一個分析樹的行,遞歸地生成具有2,1或0個孩子的新節點(對於二元或一元運算符或常量)。您可以通過檢查Node.getDepth()來限制深度。以下是一些顯示此過程的JavaScript代碼。我不確定它將會如何有用,但它的工作原理與我設想的非常相似。

'use strict'; 
 

 
var print = console.log; 
 

 
function randint(a, b) { 
 
    return Math.floor((Math.random() * (b + 1 - a)) + a); 
 
} 
 

 
function Node(parentNode, numberOfVars, 
 
       mode, weight, method, numberOfChildren, varIndex, value) { 
 

 
    this.mode = mode ? mode : randint(0, 3); 
 

 
    this.parent = parentNode; 
 
    this.weight = weight ? weight : 1; 
 

 
    if (this.mode == 0) { //constant 
 
    this.value = value ? value : 1; 
 
    } else if (this.mode == 1) { //variable 
 
    this.varIndex = varIndex ? varIndex : randint(0, numberOfVars - 1); 
 
    } else if (this.mode == 2) { //binary 
 
    this.method = method ? method : Node.binary[randint(0, Node.binary.length - 1)]; 
 
    } else if (this.mode == 3) { //unary 
 
    this.method = method ? method : Node.unary[randint(0, Node.unary.length - 1)]; 
 
    } 
 

 
    if (numberOfChildren) { 
 
    this.children = new Array(numberOfChildren); 
 
    } else { 
 
    this.children = []; 
 

 
    if (this.mode == 2) { //binary 
 
     this.children = [new Node(this, numberOfVars), 
 
         new Node(this, numberOfVars) 
 
         ]; 
 
    } else if (this.mode == 3) { //unary 
 
     this.children = [new Node(this, numberOfVars)]; 
 
    } 
 
    } 
 

 
    //Methods 
 
    this.execute = function(top_level_variables) { 
 
    print("executing " + this.mode); 
 
    var inputs = []; 
 
    this.children.forEach(function(child, index) { 
 
     print("child index " + index); 
 
     inputs.push(child.execute(top_level_variables) * child.weight); 
 
    }); 
 
    print(" inputs = " + inputs); 
 

 
    if (this.mode == 0) { 
 
     print(" mode == 0"); 
 
     return this.constant(); 
 
    } 
 
    if (this.mode == 1) { 
 
     print(" mode == 1"); 
 
     return this.variable(top_level_variables); 
 
    } 
 
    if (this.mode == 2) { 
 
     print(" mode == 2"); 
 
     return this.method(inputs[0], inputs[1]); 
 
    } 
 
    if (this.mode == 3) { 
 
     print(" mode == 3"); 
 
     return this.method(inputs[0]); 
 
    } 
 
    }; 
 
    var getIndent = function(indent) { 
 
    var str = ""; 
 
    if (indent === 0) 
 
     return str; 
 

 
    for (var i = 0; i < indent; i++) { 
 
     str += " | "; 
 
    } 
 
    return str; 
 
    }; 
 
    this.getTree = function(indent) { 
 
    if (this.mode == 0) { 
 
     print(getIndent(indent) + "(" + this.value + ")"); 
 
    } else if (this.mode == 1) { 
 
     print(getIndent(indent) + "x[" + this.varIndex + "]"); 
 
    } else if (this.mode == 2) { 
 
     print(getIndent(indent) + this.method.name); 
 
     this.children[0].getTree(indent + 1); 
 
     this.children[1].getTree(indent + 1); 
 
    } else if (this.mode == 3) { 
 
     print(getIndent(indent) + this.method.name); 
 
     this.children[0].getTree(indent + 1); 
 
    } 
 
    }; 
 
    this.getStr = function() { 
 
    if (this.mode == 0) { 
 
     return this.value; 
 
    } else if (this.mode == 1) { 
 
     return "x[" + this.varIndex + "]"; 
 
    } else if (this.mode == 2) { 
 
     return this.method.name + "(" + this.children[0].getStr() + ", " + this.children[1].getStr() + ")"; 
 
    } else if (this.mode == 3) { 
 
     return this.method.name + "(" + this.children[0].getStr() + ")"; 
 
    } 
 
    }; 
 
} 
 

 
Node.binary = [ 
 
    function add(a, b) { 
 
    return a + b 
 
    }, 
 
    function multiply(a, b) { 
 
    return a * b 
 
    }, 
 
    function power(a, b) { 
 
    return Math.pow(a, b) 
 
    } 
 
]; 
 
Node.unary = [ 
 
    function sin(a) { 
 
    return Math.sin(a) 
 
    } 
 
]; 
 
Node.prototype.constant = function() { 
 
    return this.value 
 
}; 
 
Node.prototype.variable = function(variables) { 
 
    return variables[this.varIndex] 
 
}; 
 

 
//Test 
 
var a = new Node(null, 2, 2); 
 
a.getTree(0); 
 
print(a.getStr()) 
 
print(a.getDepth()); 
 
var b = a.execute([1, 3]); 
 
print(b);

2

我建議你嘗試生成隨機表達式樹;僞代碼(有點斯卡拉啓發)爲可能是這個樣子:

NVars = 2 
def generateTree(level) = { 
    if (level > 100) { generateVarref() } 
    else { 
    val choice = randomChoice(4) 
    switch (choice) { 
     case 0 => generateVarref() 
     case 1 => generateConstant() 
     case 2 => generateUnary(level + 1) 
     case 3 => generateBinary(level + 1) 
    } 
    } 
} 
def generateVarref() = { 
    val c = randomChoice(NVars) 
    VarRef(c) 
} 
def generateConstant() = { 
    Number(randomChoice(100)) 
} 
def generateUnary(level) = { 
    val c = randomChoice(6) 
    val subexpr = generateTree(level) 
    switch (c) { 
    case 0 => Negate(subexpr) 
    case 1 => Sin(subexpr) 
    // etc. More unary functions here 
    } 
} 
def generateBinary(level) = { 
    val c = randomChoice(4) 
    val sub1 = generateTree(level) 
    val sub2 = generateTree(level) 
    switch (c) { 
    case 0 => Plus(sub1, sub2) 
    case 1 => Minus(sub1, sub2) 
    case 2 => Times(sub1, sub2) 
    case 3 => Divide(sub1, sub2) 
    } 
} 

PlusVarref等是實現了一個方法,然後,讓你在給定的值計算表達式的表達式類型構造。

1

讓我們假設你的函數有2變量x1x2(如果這種假設過於嚴格只是適應我的回答n變量x1,...,xn。)

[開始]隨機生成多項式函數

這將需要

  • 建模多項式2變量(x1x2
  • 執行多項式的評價上(任何)特定變量的值
  • 通過取隨機度生成隨機多項式函數(u p來一定的最大值)和隨機係數(在給定的時間間隔內)

[撰寫]啓用功能組成

這將需要

  • 執行的功能的組合物,這樣,如果,比如f,gh是你模型中的函數(是否隨機生成),那麼f(g,h)也是你模型中的函數。

[富民]添加新的功能,家庭模型

在這裏,你必須要考慮(和實施)其他類型的功能,你已經有一個(多項式):合理,三角函數,對數,指數等。對於每一個新的類型,你將不得不對他們的模型,也,以實現它們生成隨機實例的方式(像你一樣的多項式多。)

[生成]創建隨機功能結合了以上所有

  • 選擇某些類型的隨機
  • 對於每一個類型,生成一個隨機的實例
  • 撰寫的所有類型爲最終結果。

[迭代]轉到[富民],並添加新的類型的函數

  • 同上。