當前位置:首頁 » 編程語言 » java回溯

java回溯

發布時間: 2022-06-28 19:29:30

『壹』 java或者C/C++怎麼用回溯法解決最小長度電路板排列問題

以java為例,希望能夠幫到你。

電路板排列問題

問題描述

將n塊電路板以最佳排列方式插入帶有n個插槽的機箱中。n塊電路板的不同排列方式對應於不同的電路板插入方案。設B={1, 2, …, n}是n塊電路板的集合,L={N1, N2, …, Nm}是連接這n塊電路板中若干電路板的m個連接塊。Ni是B的一個子集,且Ni中的電路板用同一條導線連接在一起。設x表示n塊電路板的一個排列,即在機箱的第i個插槽中插入的電路板編號是x[i]。x所確定的電路板排列Density (x)密度定義為跨越相鄰電路板插槽的最大連線數。

例:如圖,設n=8, m=5,給定n塊電路板及其m個連接塊:B={1, 2, 3, 4, 5, 6, 7, 8},N1={4, 5, 6},N2={2, 3},N3={1, 3},N4={3, 6},N5={7, 8};其中兩個可能的排列如圖所示,則該電路板排列的密度分別是2,3。

『貳』 JAVA怎麼用回溯法列印出1,2,3,4的所有組合和排列

/*
*組合 回溯
*a為源數據,調用時用f(a,0,"")
*/
void f(int[] a,int n,String v){
if(n==a.length){
System.out.println(v);
}else{
f(a,n+1,v);
f(a,n+1,v+","+a[n]);
}
}

『叄』 java 八皇後問題 遞歸 回溯

你main方法也沒有加上,這樣吧,我給你看代碼,這個比較容易理解。

packagecom.aice.queen;
publicclassQueen{
//同欄是否有皇後,1表示有
privateint[]column;

//右上至左下是否有皇後
privateint[]rup;

//左上至右下是否有皇後
privateint[]lup;

//解答
privateint[]queen;

//解答編號
privateintnum;

publicQueen(){
column=newint[8+1];
rup=newint[(2*8)+1];
lup=newint[(2*8)+1];

for(inti=1;i<=8;i++)
column[i]=1;
for(inti=1;i<=(2*8);i++)
rup[i]=lup[i]=1;
queen=newint[8+1];
}

publicvoidbacktrack(inti){
if(i>8){
showAnswer();
}else{
for(intj=1;j<=8;j++){
if((column[j]==1)&&(rup[i+j]==1)&&
(lup[i-j+8]==1)){
queen[i]=j;
//設定為佔用
column[j]=rup[i+j]=lup[i-j+8]=0;
backtrack(i+1);
column[j]=rup[i+j]=lup[i-j+8]=1;
}
}
}
}

protectedvoidshowAnswer(){
num++;
System.out.println(" 解答"+num);

for(inty=1;y<=8;y++){
for(intx=1;x<=8;x++){
if(queen[y]==x){
System.out.print("Q");
}else{
System.out.print(".");
}
}
System.out.println();
}
}

publicstaticvoidmain(String[]args){
Queenqueen=newQueen();
queen.backtrack(1);
}
}

『肆』 java回溯法如何執行

回溯法也稱為試探法,該方法首先暫時放棄關於問題規模大小的限制,並將問題的候選解按某種順序逐一枚舉和檢驗。當發現當前候選解不可能是解時,就選擇下一個候選解;倘若當前候選解除了還不滿足問題規模要求外,滿足所有其他要求時,繼續擴大當前候選解的規模,並繼續試探。如果當前候選解滿足包括問題規模在內的所有要求時,該候選解就是問題的一個解。在回溯法中,放棄當前候選解,尋找下一個候選解的過程稱為回溯。擴大當前候選解的規模,以繼續試探的過程稱為向前試探。 1、回溯法的一般描述 可用回溯法求解的問題P,通常要能表達為:對於已知的由n元組(x1,x2,…,xn)組成的一個狀態空間E={(x1,x2,…,xn)∣xi∈Si ,i=1,2,…,n},給定關於n元組中的一個分量的一個約束集D,要求E中滿足D的全部約束條件的所有n元組。其中Si是分量xi的定義域,且 |Si| 有限,i=1,2,…,n。我們稱E中滿足D的全部約束條件的任一n元組為問題P的一個解。 解問題P的最樸素的方法就是枚舉法,即對E中的所有n元組逐一地檢測其是否滿足D的全部約束,若滿足,則為問題P的一個解。但顯然,其計算量是相當大的。 我們發現,對於許多問題,所給定的約束集D具有完備性,即i元組(x1,x2,…,xi)滿足D中僅涉及到x1,x2,…,xi的所有約束意味著j(j<i)元組(x1,x2,…,xj)一定也滿足D中僅涉及到x1,x2,…,xj的所有約束,i=1,2,…,n。換句話說,只要存在0≤j≤n-1,使得(x1,x2,…,xj)違反D中僅涉及到x1,x2,…,xj的約束之一,則以(x1,x2,…,xj)為前綴的任何n元組(x1,x2,…,xj,xj+1,…,xn)一定也違反D中僅涉及到x1,x2,…,xi的一個約束,n≥i>j。因此,對於約束集D具有完備性的問題P,一旦檢測斷定某個j元組(x1,x2,…,xj)違反D中僅涉及x1,x2,…,xj的一個約束,就可以肯定,以(x1,x2,…,xj)為前綴的任何n元組(x1,x2,…,xj,xj+1,…,xn)都不會是問題P的解,因而就不必去搜索它們、檢測它們。回溯法正是針對這類問題,利用這類問題的上述性質而提出來的比枚舉法效率更高的演算法。 回溯法首先將問題P的n元組的狀態空間E表示成一棵高為n的帶權有序樹T,把在E中求問題P的所有解轉化為在T中搜索問題P的所有解。樹T類似於檢索樹,它可以這樣構造: 設Si中的元素可排成xi(1) ,xi(2) ,…,xi(mi-1) ,|Si| =mi,i=1,2,…,n。從根開始,讓T的第I層的每一個結點都有mi個兒子。這mi個兒子到它們的雙親的邊,按從左到右的次序,分別帶權xi+1(1) ,xi+1(2) ,…,xi+1(mi) ,i=0,1,2,…,n-1。照這種構造方式,E中的一個n元組(x1,x2,…,xn)對應於T中的一個葉子結點,T的根到這個葉子結點的路徑上依次的n條邊的權分別為x1,x2,…,xn,反之亦然。另外,對於任意的0≤i≤n-1,E中n元組(x1,x2,…,xn)的一個前綴I元組(x1,x2,…,xi)對應於T中的一個非葉子結點,T的根到這個非葉子結點的路徑上依次的I條邊的權分別為x1,x2,…,xi,反之亦然。特別,E中的任意一個n元組的空前綴(),對應於T的根。 因而,在E中尋找問題P的一個解等價於在T中搜索一個葉子結點,要求從T的根到該葉子結點的路徑上依次的n條邊相應帶的n個權x1,x2,…,xn滿足約束集D的全部約束。在T中搜索所要求的葉子結點,很自然的一種方式是從根出發,按深度優先的策略逐步深入,即依次搜索滿足約束條件的前綴1元組(x1i)、前綴2元組(x1,x2)、…,前綴I元組(x1,x2,…,xi),…,直到i=n為止。 在回溯法中,上述引入的樹被稱為問題P的狀態空間樹;樹T上任意一個結點被稱為問題P的狀態結點;樹T上的任意一個葉子結點被稱為問題P的一個解狀態結點;樹T上滿足約束集D的全部約束的任意一個葉子結點被稱為問題P的一個回答狀態結點,它對應於問題P的一個解。 【問題】 組合問題 問題描述:找出從自然數1、2、……、n中任取r個數的所有組合。 例如n=5,r=3的所有組合為: (1)1、2、3 (2)1、2、4 (3)1、2、5 (4)1、3、4 (5)1、3、5 (6)1、4、5 (7)2、3、4 (8)2、3、5 (9)2、4、5 (10)3、4、5 則該問題的狀態空間為: E={(x1,x2,x3)∣xi∈S ,i=1,2,3 } 其中:S={1,2,3,4,5} 約束集為: x1<x2<x3 顯然該約束集具有完備性。 問題的狀態空間樹T: 2、回溯法的方法 對於具有完備約束集D的一般問題P及其相應的狀態空間樹T,利用T的層次結構和D的完備性,在T中搜索問題P的所有解的回溯法可以形象地描述為: 從T的根出發,按深度優先的策略,系統地搜索以其為根的子樹中可能包含著回答結點的所有狀態結點,而跳過對肯定不含回答結點的所有子樹的搜索,以提高搜索效率。具體地說,當搜索按深度優先策略到達一個滿足D中所有有關約束的狀態結點時,即「激活」該狀態結點,以便繼續往深層搜索;否則跳過對以該狀態結點為根的子樹的搜索,而一邊逐層地向該狀態結點的祖先結點回溯,一邊「殺死」其兒子結點已被搜索遍的祖先結點,直到遇到其兒子結點未被搜索遍的祖先結點,即轉向其未被搜索的一個兒子結點繼續搜索。 在搜索過程中,只要所激活的狀態結點又滿足終結條件,那麼它就是回答結點,應該把它輸出或保存。由於在回溯法求解問題時,一般要求出問題的所有解,因此在得到回答結點後,同時也要進行回溯,以便得到問題的其他解,直至回溯到T的根且根的所有兒子結點均已被搜索過為止。 例如在組合問題中,從T的根出發深度優先遍歷該樹。當遍歷到結點(1,2)時,雖然它滿足約束條件,但還不是回答結點,則應繼續深度遍歷;當遍歷到葉子結點(1,2,5)時,由於它已是一個回答結點,則保存(或輸出)該結點,並回溯到其雙親結點,繼續深度遍歷;當遍歷到結點(1,5)時,由於它已是葉子結點,但不滿足約束條件,故也需回溯。 3、回溯法的一般流程和技術 在用回溯法求解有關問題的過程中,一般是一邊建樹,一邊遍歷該樹。在回溯法中我們一般採用非遞歸方法。下面,我們給出回溯法的非遞歸演算法的一般流程: 在用回溯法求解問題,也即在遍歷狀態空間樹的過程中,如果採用非遞歸方法,則我們一般要用到棧的數據結構。這時,不僅可以用棧來表示正在遍歷的樹的結點,而且可以很方便地表示建立孩子結點和回溯過程。 例如在組合問題中,我們用一個一維數組Stack[ ]表示棧。開始棧空,則表示了樹的根結點。如果元素1進棧,則表示建立並遍歷(1)結點;這時如果元素2進棧,則表示建立並遍歷(1,2)結點;元素3再進棧,則表示建立並遍歷(1,2,3)結點。這時可以判斷它滿足所有約束條件,是問題的一個解,輸出(或保存)。這時只要棧頂元素(3)出棧,即表示從結點(1,2,3)回溯到結點(1,2)。

『伍』 java異常處理的機制有哪幾種

Java語言提供兩種異常處理機制:捕獲異常和聲明拋棄異常;

1)捕獲異常:在Java程序運行過程中系統得到一個異常對象是,它將會沿著方法的調用棧逐層回溯,尋找處理這一異常的代碼。找到能夠處理這種類型異常的方法後,運行時系統把當前異常交給這個方法處理;如果找不到可以捕獲異常的方法,則運行時系統將終止,相應的Java程序也將退出。捕獲異常是通過try-catch-finally語句實現的。語法為:

try{

...

}catch(ExceptionName1 e){

...

}catch(ExceptionName2 e){

...

}

...

}finally{

...

}

『陸』 java回溯和遞歸的區別,主要什麼回溯怎麼用,有代碼最好

N皇後問題的非遞歸迭代回溯法java代碼實現
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class NQueen {

static int n; // 皇後個數
static int[] x; // 當前解如{0,2,4,1,3}分別代表第1、2、3、4列的行值
static int totle; // 可行方案個數
public static void main(String[] args) {
int input = 0; //輸入n值
int sum = 0; //可行方案個數
String temp; //臨時存儲輸入值
System.out.println("請輸入N後問題的N值:");

try {
BufferedReader br = new BufferedReader(new InputStreamReader(
System.in));
temp = br.readLine();
input = Integer.parseInt(temp); //將輸入值轉換為int保存
if(input<=0){
throw new IOException("別輸負數好不?");
}
System.out.println("輸入的數是:" + input);

sum = nQueen(input); //調用nqueen方法

System.out.println("可行方案個數為:" + sum); //輸出sum

} catch (IOException e) {
System.out.println(e.getMessage());

}catch (NumberFormatException e){
System.out.println("請輸入數字。。。");
}
}
private static int nQueen(int input) {
n = input; //把輸入給全局變數n
totle = 0; //初始化totle
x = new int[n + 1];
for (int i = 0; i <= n; i++)
x[i] = 0; //初始化x
backtrack(); //調用回溯演算法
return totle;
}
private static void backtrack() {
int k = 1;
while (k > 0) {
x[k] += 1; //第k列皇後向下移一行
while ((x[k] <= n) && !(place(k))){ //如果當前第k列皇後未出界或者和其他皇後沖突
x[k] += 1; //第k列皇後向下移一行繼續尋找
System.out.println("在第"+k+"行 "+"第"+x[k]+"列放置皇後");
System.out.print("當前方案為 ");
for(int i=1;i<=k;i++) //列印尋找策略
System.out.print(x[i]+" ");
System.out.println();
}
if (x[k] <= n) //找到一個值並且未出界
if (k == n) { //已是最後一列說明已找到一個方案
totle++;
System.out.print("可行方案為: ");
for (int i = 1; i <= n; i++)
System.out.print(x[i] + " ");
System.out.println();
} else { //不是最後一列故尋找下一列
k++;
x[k] = 0;
}
else //找到的值已經出界,回退到上一列
k--;
}
}
//判斷皇後是否沖突
private static boolean place(int k) {
for (int j = 1; j < k; j++)
if ((Math.abs(k - j) == Math.abs(x[j] - x[k])) || (x[j] == x[k]))
return false;
return true;
}
}

『柒』 JAVA中八皇後問題演算法和流程圖。要求用回溯法,求大神解答,在線等如果有代碼就完美了

[cpp] view plainprint?
//--------------------------------------
//利用函數遞歸,解決八皇後問題
//
// zssure 2014-03-12
//--------------------------------------

#include <stdio.h>
#include <cmath>

int count=0;//全局計數變數

/*--------------------四個皇後----------------------*/
//#define QUEEN_NUM 4
//int label[QUEEN_NUM][QUEEN_NUM]={ 0,0,0,0,
// 0,0,0,0,
// 0,0,0,0,
// 0,0,0,0 };

/*--------------------五個皇後----------------------*/
//#define QUEEN_NUM 5
//int label[QUEEN_NUM][QUEEN_NUM]={ 0,0,0,0,0,
// 0,0,0,0,0,
// 0,0,0,0,0,
// 0,0,0,0,0,
// 0,0,0,0,0 };

/*--------------------六個皇後----------------------*/
//#define QUEEN_NUM 6
//int label[QUEEN_NUM][QUEEN_NUM]={ 0,0,0,0,0,0,
// 0,0,0,0,0,0,
// 0,0,0,0,0,0,
// 0,0,0,0,0,0,
// 0,0,0,0,0,0,
// 0,0,0,0,0,0
// };

/*--------------------七個皇後----------------------*/
//#define QUEEN_NUM 7
//int label[QUEEN_NUM][QUEEN_NUM]={ 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0
// };

/*--------------------八個皇後----------------------*/
#define QUEEN_NUM 8
int label[QUEEN_NUM][QUEEN_NUM]={0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0};

void FillChessbox(int m,int n,int num)
{
for(int i=0;i<QUEEN_NUM;++i)
for(int j=0;j<QUEEN_NUM;++j)
if(abs(i-m)==abs(j-n))//對角區域填充
{
if(label[i][j]==0)
label[i][j]=num;
}

int i=0,j=0;
while(i<QUEEN_NUM)//行填充
{
if(label[i][n]==0)
label[i][n]=num;
++i;
}
while(j<QUEEN_NUM)//列填充
{
if(label[m][j]==0)
label[m][j]=num;
++j;
}

}
void ClearChessBox(int m,int n,int num)
{
for(int i=0;i<QUEEN_NUM;++i)
for(int j=0;j<QUEEN_NUM;++j)
if(abs(i-m)==abs(j-n) && label[i][j]==num)
label[i][j]=0;
int i=0,j=0;
while(i<QUEEN_NUM)
{
if(label[i][n]==num)
label[i][n]=0;
++i;
}
while(j<QUEEN_NUM)
{
if(label[m][j]==num)
label[m][j]=0;
++j;
}
}
void AllClear()
{
for(int i=0;i<QUEEN_NUM;++i)
for(int j=0;j<QUEEN_NUM;++j)
label[i][j]=0;

}
void PrintResult()
{
for(int i=0;i<QUEEN_NUM;++i)
{
for(int j=0;j<QUEEN_NUM;++j)
printf("%d ",label[i][j]);
printf("\n");

}
}
bool EightQueen(int n/*皇後個數*/,int c/*已經放置的皇後個數*/)
{
//static int count=0;
//小於3x3的棋盤是無解的
if(n<4)
return false;

for(int i=0;i<n;++i)
{
if(label[c-1][i]==0)//存在可以放置第c個皇後的位置
{
label[c-1][i]=c+1;
if(c==n)/*已經放置完畢所有的皇後*/
{
++count;
PrintResult();
printf("**************************\n");
ClearChessBox(c-1,i,c+1);
//AllClear();
return true;
}
FillChessbox(c-1,i,c+1);
EightQueen(n,c+1);
ClearChessBox(c-1,i,c+1);
/*-------------------------------------------------------------------------------------------------------------------------
// 現場恢復,無論下一個皇後是否順利放置,都應該恢復現場。原因是
//
// 如果下一個皇後放置失敗,那麼自然應該將本次放置的皇後去除,重新放置,所以需要進行現場恢復(即回溯);
// 如果下一個皇後放置成功,意味著本次放置已經滿足條件,是一個解,此時需要恢復現場,進行下一次的重新放置,尋找下一個解。
//
//------------------------------------------------------------------------------------------------------------------------*/
//if(!EightQueen(n,c+1))
// ClearChessBox(c-1,i,c+1);

}
}
return false;
}

int main()
{
EightQueen(QUEEN_NUM,1);
printf("%d\n",count);
return 0;
}

『捌』 java 深度優先搜索(回溯法)求集合的冪集

import java.util.ArrayList;
import java.util.List;

public class BackTrack {
public static void main(String[] args) {
//初始化一個集合,放在list裡面
List<String> list=new ArrayList<String>();
list.add("1");
list.add("2");
list.add("3");
list.add("f");
List<String> li=new ArrayList<String>();
PowerSet(0,list,li);
}
//回溯法求冪集
public static void PowerSet(int i,List<String> list,List<String> li){

if(i>list.size()-1){System.out.println(li);}
else{
li.add(list.get(i));//左加
PowerSet(i+1,list,li); //遞歸方法
li.remove(list.get(i)); //右去
PowerSet(i+1, list, li);
}
}

}

註:該方法採用中序遍歷二叉樹(實際這棵樹是不存在的)。對於第一個元素,左節點加進去,右節點去掉。對於第i一個節點,左加,右去。直到i大於元素的總個數。

輸出結果:
[1, 2, 3, 4]
[1, 2, 3]
[1, 2, 4]
[1, 2]
[1, 3, 4]
[1, 3]
[1, 4]
[1]
[2, 3, 4]
[2, 3]
[2, 4]
[2]
[3, 4]
[3]
[4]
[]

『玖』 20 java回溯和遞歸的區別,主要什麼回溯怎麼用,有代碼最好

遞歸的精華就在於大問題的分解,要學會宏觀的去看問題,如果這個大問題可以分解為若干個性質相同的規模更小的問題,那麼我們只要不斷地去做分解,當這些小問題分解到我們能夠輕易解決的時候,大問題也就能迎刃而解了。如果你能獨立寫完遞歸創建二叉樹,前序、中序、後序遞歸遍歷以及遞歸計算二叉樹的最大深度,遞歸就基本能掌握了。回溯本人用得很少,僅限於八皇後問題,所以幫不上啥了。

熱點內容
webrtc伺服器搭建哪家價格低 發布:2024-04-27 01:30:08 瀏覽:139
oracle資料庫無法啟動 發布:2024-04-27 01:29:20 瀏覽:612
倪萍超級訪問 發布:2024-04-27 01:23:29 瀏覽:704
java集合循環 發布:2024-04-27 01:17:18 瀏覽:593
解壓喪屍片 發布:2024-04-27 01:02:28 瀏覽:370
編程師加班 發布:2024-04-27 00:49:24 瀏覽:910
lol四川伺服器雲空間 發布:2024-04-27 00:42:08 瀏覽:934
卡宴怎麼看配置 發布:2024-04-27 00:41:08 瀏覽:942
央視影音緩存視頻怎麼下載視頻 發布:2024-04-27 00:25:55 瀏覽:584
手機緩存的視頻怎麼看 發布:2024-04-27 00:11:05 瀏覽:58