簡體   English   中英

如何編寫蠻力算法?

[英]How to write a brute-force algorithm?

我目前正在尋找一種蠻力算法,但我找不到一個好的/簡單的算法。
所以我試着自己寫一個,但我失敗了。 我只是數學太差了或者別的什么。 :/
我不需要特定編程語言的算法,如果你有,我可以將它移植到我需要的語言。
我基本上在尋找像這樣簡單的東西:
(我嘗試寫一個蠻力函數)

function BruteForce(chars,minLen,maxLen)
    curCharArray = {}
    for i=1, maxLen do
      curCharArray[i] = 0
    end
    generatedString = ""
    for currentLength = minLen, maxLen, 1 do
        curCharArray[currentLength] = 1
        Pos=currentLength
        while Pos>0 do

            if string.len(generatedString) < 1 then 
                generatedString= string.sub(chars,curCharArray[Pos],curCharArray[Pos])
            else
                generatedString= string.sub(generatedString,1,Pos-1) .. string.sub(chars,curCharArray[Pos],curCharArray[Pos])
            end

                print(generatedString)

            curCharArray[Pos] = curCharArray[Pos]+1
            Pos = currentLength
            while curCharArray[Pos]==string.len(chars)+1 do
                curCharArray[Pos]=1
                Pos = Pos-1
            end
        end
    end
end

BruteForceAttack("abc",2,3)

It's written in Lua, you can run the code online here: http://www.lua.org/cgi-bin/demo The output is:

a
ab
ac

a
ab
ac
a
aa
ab
ac
b
ba
bb
bc
c
ca
cb
cc
cca
ccb
ccc
ca
caa
cab
cac
cb
cba
cbb
cbc
cc
cca
ccb
ccc
a
aa
aab
aac
aa
aaa
aab
aac
ab
aba
abb
abc
ac
aca
acb
acc
b
ba
bab
bac
ba
baa
bab
bac
bb
bba
bbb
bbc
bc
bca
bcb
bcc
c
ca
cab
cac
ca
caa
cab
cac
cb
cba
cbb
cbc
cc
cca
ccb
ccc

正如您所看到的,一些輸出是相同的,並且沒有考慮最小長度。 另外,順序不對。 我希望 output 是:

aa
ab
ac
ba
bb
bc
ca
cb
cc
aaa
aab
aac
aba
abb
abc
aca
acb
acc
baa
bab
bac
bba
bbb
bbc
bca
bcb
bcc
caa
cab
cac
cba
cbb
cbc
cca
ccb
ccc

不幸的是,我不了解LUA,但是我認為從以下JavaScript代碼段中可以很清楚地了解到這一點:

function generate(current, len, chars) 
{
    if (current.length == len)
        console.log(current);
    if (current.length < len)
        for (var i in chars) {
            generate(current + chars[i], len, chars) 
        }
}

function brute(chars, min, max)
{
    for (var l = min; l <= max; ++l)
        generate("", l, chars);
}

brute(['a', 'b', 'c'], 2, 3);

更新 :無遞歸的代碼段:

function generateNoRecursion(len, chars) 
{
    // Indices that indicate what char to use on corresponding place.
    var indices = [];
    for (var i = 0; i < len; ++i)
        indices.push(0);

    // While all indices in set of chars
    while (indices[0] < chars.length)
    {
        // Print current solution
        var str = "";
        for (var i = 0; i < indices.length; ++i)
            str += chars[indices[i]];
        console.log(str);
        // Go to next solution by incrementing last index and adjusting
        // if it is out of chars set.
        indices[len-1]++;
        for (var i = len-1; i > 0 && indices[i] == chars.length; --i)
        {
            indices[i] = 0;
            indices[i-1]++;
        }
    }
}

function brute(chars, min, max)
{
    for (var l = min; l <= max; ++l)
        generateNoRecursion(l, chars);
}

許多編程語言在某些標准庫中都具有這種功能。 例如,在Python中,您可以執行以下操作:

import itertools 

def print_perms(chars, minlen, maxlen): 
    for n in range(minlen, maxlen+1): 
        for perm in itertools.product(chars, repeat=n): 
            print(''.join(perm)) 

print_perms("abc", 2, 3)

非常感謝@Dmitry Poroh的好主意。 我在lua上實現了代碼:

symbols = {'A','B','C'}

lenght = {min = 2, max = 3}

function print_t(t)
    for _,v in pairs(t) do
    io.write(v)
    end
    print()
end

function generate(current, len, chars)
    if #current == len then
    print_t(current)
    return
    end
    if #current < len then
    for c = 1, #chars do
    curr = {}
    for i = 1, #current do
        curr[i] = current[i]
    end
    curr[#curr+1] = chars[c]
    generate(curr, len, chars)
    end
    end
end

function brute(chars, min, max)
    for l = min, max do
    generate({}, l, chars)
    end
end

brute(symbols, lenght.min, lenght.max)

結果:

AA
AB
AC
BA
BB
BC
CA
CB
CC
AAA
AAB
AAC
ABA
ABB
ABC
ACA
ACB
ACC
BAA
BAB
BAC
BBA
BBB
BBC
BCA
BCB
BCC
CAA
CAB
CAC
CBA
CBB
CBC
CCA
CCB
CCC

我希望這段代碼對某人有用。

以下是我對 Java 和 Free Pascal 的 BruteForce 算法的實現。

Java

/**
 *
 * @author Nikos Siatras
 * https://github.com/nsiatras
 */
public class BruteForce
{

    private static final char[] fCharList =
    {
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
    };

    public static void main(String[] args)
    {
        for (int i = 1; i < 17; i++)
        {
            StartBruteForce(i);
        }
    }

    /**
     * This method is called every time a new word is generated
     *
     * @param word is the brute force generated word
     */
    private static void OnBruteForceWordGenerated(String word)
    {
        System.out.println(word);
    }

    /**
     * Start a new Brute Force
     *
     * @param length is the words length (how many characters a word can have)
     */
    private static void StartBruteForce(int length)
    {
        StringBuffer sb = new StringBuffer(length);
        char currentChar = fCharList[0];

        for (int i = 1; i <= length; i++)
        {
            sb.append(currentChar);
        }

        ChangeCharacters(0, sb, length);
    }

    private static StringBuffer ChangeCharacters(int pos, StringBuffer sb, int length)
    {
        for (int i = 0; i <= fCharList.length - 1; i++)
        {
            sb.setCharAt(pos, fCharList[i]);
            if (pos == length - 1)
            {
                // Write the Brute Force generated word.
                OnBruteForceWordGenerated(sb.toString());
            }
            else
            {
                ChangeCharacters(pos + 1, sb, length);
            }
        }

        return sb;
    }
}

自由帕斯卡

program Pascal_BruteForce;

(*
  Brute Force Algorithm for FreePascal

  Author: Nikos Siatras
  https://github.com/nsiatras
*)

uses
  SysUtils;

// Global Variables
var
  fCharactersStr: string;
  fCharList: TStringArray;
  fCharactersListLength: integer;

{*
  The OnBruteForceWordGenerated procedure is called everytime a new word
  is generated from the BruteForce algorithm
  For this example I choose only to write to word on the screen
*}
  procedure OnBruteForceWordGenerated(word: string);

  begin
    WriteLn(word);
  end;

(*
  Change characters to each other and generate BruteForce words :)
*)
  procedure ChangeCharacter(pos: integer; sb: array of string; wordLength: integer);
  var
    i, x: integer;
    generatedWord: string;
  begin

    for i := 0 to fCharactersListLength - 1 do
    begin

      sb[pos] := fCharList[i];

      if pos = wordLength - 1 then
      begin
        // Pass the BruteForce generated word to the OnBruteForceWordGenerated
        // procedure
        generatedWord := string.Join('', sb);
        OnBruteForceWordGenerated(generatedWord);
      end

      else
      begin
        ChangeCharacter(pos + 1, sb, wordLength);
      end;

    end;

  end;

(*
  Start Brute Force Generation
  @wordLength is the word's length (how many characters a word can have)
*)
  procedure StartBruteForce(wordLength: integer);
  var
    stringBuilder: array of string;
    currentChar: string;
    i: integer;
  begin

    SetLength(stringBuilder, wordLength);
    currentChar := fCharList[0];

    for i := 1 to wordLength do
    begin
      stringBuilder[i - 1] := currentChar;
    end;

    ChangeCharacter(0, stringBuilder, wordLength);

  end;


  // Main Program
var
  i: integer;

begin

  //Initialize fCharList array
  //For this example I will use all lowercase english alphabet characters.
  fCharactersStr := 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z';
  fCharList := fCharactersStr.split(',');

  //Find the length of the fCharList array
  fCharactersListLength := Length(fCharList);

  // Generate all words with total length from 1 to 16 characters
  // This will generate all words from 'a' to 'zzzzzzzzzzzzzzzz'
  for i := 1 to 16 do
  begin
    StartBruteForce(i);
  end;

end.

解決問題時,有不同的方法,例如:

  • 蠻力:嘗試所有可能的狀態組合,通過組合枚舉獲得解決方案。

  • 分而治之:當某個問題狀態在某個時刻很困難時,您可以將其分為兩個或多個相同的部分,分別進行求解,然后合並部分解決方案。

  • 動態規划:當問題在2個或多個維度上具有變體時,您將重建相同的問題直至輸入大小,在每次構建時,您都可以使用小於該大小的最佳解決方案來線性解決問題。

  • 貪婪:在每個狀態下,如果不是解決方案,請轉到最佳鄰居狀態,這基本上是對成本g(state)函數的優化(最大化\\最小化)。

  • 啟發式:在每個狀態下,您都具有h(state)函數,該函數的作用類似於一個8球,告訴您鄰居狀態與解狀態的接近程度。

  • ..等

例如:搜索問題。

-- Brute Force example, search array

local array = { "apple", "orange", "pear", "banana" }

for i = 1, #array do

  if array[i] == "banana" then

    -- item found

  end

end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM