百度百科解釋:
回溯算法實際上一個類似枚舉的搜索嘗試過程,主要是在搜索嘗試過程中尋找問題的解,當發現已不滿足求解條件時,就“回溯”返回,嘗試別的路徑。回溯法是一種選優搜索法,按選優條件向前搜索,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術爲回溯法,而滿足回溯條件的某個狀態的點稱爲“回溯點”。許多複雜的,規模較大的問題都可以使用回溯法,有“通用解題方法”的美稱。
現在來實際操練幾題
假如我們有1,2,3,4允許數字重複有多少種排列組合,這個題我們用程序實現。
直接來代碼:
$result = array();
function pailie($arr, $res = array())
{
global $result;
static $arr_count;
if(empty($arr_count))
{
$arr_count = count($arr);
}
if(count($res) == $arr_count)
{
$result[] = $res;
return;
}
foreach($arr as $key => $num)
{
$res[] = $num;
pailie($arr, $res);
array_pop($res);
}
}
$arr = array(1, 2, 3, 4);
pailie($arr);
echo count($result) . '<br>';
foreach($result as $r)
{
echo implode(',', $r);
echo '<br>';
}
假如我把上一題改成數字不能重複的排列組合,我們只需要稍微改改函數:
function pailie($arr, $res = array())
{
global $result;
static $arr_count;
if(empty($arr_count))
{
$arr_count = count($arr);
}
if(count($res) == $arr_count)
{
$result[] = $res;
return;
}
foreach($arr as $key => $num)
{
$res[] = $num;
//回溯的時候刪掉當前這個數字
$tm_arr = $arr;
unset($tm_arr[$key]);
pailie($tm_arr, $res);
array_pop($res);
}
}
再來一題:
有一個N階的樓梯,一步可以上一階或兩階。設計一個函數,傳入任意正整數N,列出所有可能的走法。例如臺階數爲4走法如下:
1,1,1,1
1,2,1
1,1,2
2,1,1
2,2
如果這個人腿比較長,一次有可能跨好幾階例如傳入階梯數組{3,5,7}的那麼該函數如何設計呢?
個人用回溯算法解題代碼如下:
$result = array();
function zoulu($n, $exist = array(), $res = array())
{
global $result;
if(!empty($res))
{
$sum = array_sum($res);
if($sum > $n)
return false;
else if($sum == $n)
{
$result[] = $res;
}
}
foreach($exist as $e_one)
{
$res[] = $e_one;
zoulu($n, $exist, $res);
array_pop($res);
}
}
$exist = array(4, 7);
zoulu(30, $exist);
echo count($result) . '<br>';
foreach($result as $r)
{
echo implode(',', $r);
echo '<br>';
}