❶ java回溯法解四皇後問題
程序錯誤,你這是C++程序,哪是JAVA程序。
❷ 求java用回溯法解決子集和問題
很簡單 思路就是循環集合 先不同的2個數相加 然後3個 一直到s.length個相加 if(sum==c)輸出
❸ 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中八皇後問題演算法和流程圖。要求用回溯法,求大神解答,在線等如果有代碼就完美了
[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是不是很難學謝謝
世上無難事,只怕有心人。
Java是編程語言中比較難學的一門語言,它的難度並不低,相對比於C語言、Python語言來說,他們的學習難度要比Java輕松很多;
Java的學習中最難得就是,各種各樣的框架,框架的使用、整合、最後項目;
學習Java剛開始我們要學習各種各樣的基礎知識:
Java的基礎:
數據結構和演算法、集合(容器)、IO流、多線程、封裝、多態、繼承等等
資料庫的基礎:
MySQL基礎、MySQL 增刪改查語句、資料庫對象、JDBC、反射和註解等
Java web基礎知識:
前端的基礎:
JS(JavaScript)、jQuery、HEML、CSS等
當我們學完這些基礎知識以後我們將邁入Java中的高級階段 JavaEE
這個階段中會需要我們將所有的,知識總結在一起揉吧揉吧和一塊,「難就難在這里」以我對學習Java來看就是這種想像,起個名詞「學英語」;
就是那種 「ABCDEFG···」我都會,但是合在一起的話我們就變得,不能理解甚至無從下手。原本很簡單的基礎知識,什麼 封裝多態簡單、什麼 HTML/CSS簡單、什麼資料庫簡單!!但是他們集合在一起會導致我們不知道從哪裡開始
學習Java不止要靠毅力、腦力、思維力,還要靠人際交流問題需要靠你的花言巧語找大牛為你指點江山,走上成功之路!
希望會給大家帶來幫助!
❻ java回歸和遞歸的區別,主要什麼回歸怎麼用,有代碼最好
回歸是什麼?
❼ 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 深度優先搜索(回溯法)求集合的冪集
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]
[]
❾ 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)。
❿ 回溯法解決0-1背包問題 java寫的 求大神指點~~~~(>_<)~~~~
因為你把n和c 定義為static ,而且初始化為0,。數組也為靜態的,一個類中靜態的變數在這個類載入的時候就會執行,所以當你這類載入的時候,你的數組static int[] v = new int[n];
static int[] w = new int[n];
就已經初始化完畢,而且數組大小為0。在main方法里動態改變n的值是改變不了已經初始化完畢的數組的大小的,因為組已經載入完畢。
我建議你可以在定義n,c是就為其賦初值。比如(static int n=2 static int c=3)