バックトラック - サブセット和問題

(1)問題の説明:問題のサブセットと、例えば<データ、NUM>。{式中、X =データ。1、X 2、...、X n-は }正の整数の集合であり、targetValueは正の整数です。データのそこDATA1サブセット場合サブセット和問題の決定は、そのようなことを

X 1 + X 2  + ... + X N = targetValue(X€DATA1)

(2)アルゴリズムを設計:バックトラッキングアルゴリズムは、所与のセットのために、ツリーのサブセットを解決するために使用される{X =データ。1、X 2、...、X N- } targetValueとデータDATA1のサブセット計算正の整数、 [X満たす。1  + X 2  + ... + X N-  = targetValue(X€DATAL)]

(3)アルゴリズムコード:

パブリック クラスSubsetSum { 

    / ** 
     *目標
     * / 
    プライベート 静的整数targetValue; 

    / ** 
     *現在選択されている要素の和
     * / 
    プライベート 静的整数SUM = 0 ; 

    / ** 
     *データの数
     * / 
    プライベート 静的NUM整数。

    / ** 
     *未定着値
     * / 
    プライベート 静的整数indeterminacyValue = 0 ; 

    / * 
     *データアレイ
     * / 
    プライベート 静的整数[]データ; 

    / ** 
     *データストレージ[0:1ストレージ:ストア] 
     * / 
    プライベート 静的整数[]ストア; 

    / ** 
     *初期化データ
     * / 
    プライベート 静的 無効initData(){ 
        スキャナ入力 = 新しい新しいスキャナ(System.in); 
        System.out.printlnは( "ターゲットを入力してください:" ); 
        targetValue = INPUT。 nextInt(); 
        
        System.out.printlnは( "データの番号を入力してください:" ); 
        NUM = input.nextInt(); 

        データ = 新新[NUM]整数; 
        ストア = 新しい新しい[NUM]整数; 
        System.out.printlnは(「それぞれの番号を入力してください:」);
         のためのInt I = 0; I <data.length; I ++ ){ 
            DATA [I] = input.nextInt(); 
            ストア[I] = 0;                // 初期化が格納されていない 
            indeterminacyValue + = データ[I]; 
        } 
    } 

    / ** 
     *バック見つける
     * / 
    プライベート 静的ブール後戻り(int型I){
         IF(SUM == targetValue){    // 直接戻るtrueに、実現可能な解決策を見つける
            リターン trueに; 
        } 
        のIF(data.length == I){      // 取得少ない実現可能な解決策よりも、直接のリターン偽
            リターン ; 
        } 
        IndeterminacyValue - =データは、[I]は;                   // 数の合計が決定されていない計算
        IF(和+データ[I] <= targetValue ){              // 現在の和+データ[I] <= targetValue 直接に左サブツリー 
            ストア[I] = 1;                                // 選択された加算値に含まれるiが格納されたデータ、 
            SUM + = データ[I];
             IF(バックトラック(I + 1)){                   // 継続加算層深さ決意
                リターン trueにします; 
            } 
            合計 - =データ[I];                              // 完成深さを解決するため、溶液が満たされていない必要に応じて、現在の開始値和を復元するために必要性を戻っ
        }
         IF(+ indeterminacyValue SUM> = targetValue){   // プルーニング関数[+未定値現在の和> =目標値であれば、右サブツリー検索深度に入る前に、そうでなければ、何の意味] 
            ストア[I] = 0;                                // 私はこの場合、データは選択された加数に含まれ、格納されていない
            IF(バックトラック(I + 1 )){
                 リターン trueに; 
            } 
        } 
        indeterminacyValue ; + =データ[I]は                   // の条件下で満足ならば、完成し深さを解決します解決策は、現在の開始値indeterminacyValueの復元するために、バックトラックを必要と
        リターン falseにする; 
    } 

    / ** 
     *出力
     * / 
    プライベート 静的 無効印刷(){ 
        System.out.printlnは(「\ n型データ配列:」); 
        Stream.of(データ).forEach(素子 - > System.out.print(エレメント+ "" )); 
        System.out.println(); 
        System.out.println( "数据存放:" ); 
        Stream.of(店舗).forEach(素子 - > System.out.print(エレメント+ "" )); 
        System.out.println(); 
        System.out.println( "组成该目标值的数为:" );
        以下のためにINT ; I <store.length; iが0 = I ++ ){
             場合(ストア[I] == 1 ){ 
                System.out.print(データ[I] + "" )。
            } 
        } 
        システム。
    
     静的 ボイドメイン(文字列[]引数){
         // 初期化データ
        initData(); 

        // バック見つけるために 
        バックトラックを(0 ); 

        // 出力
        プリント(); 
    } 

}
そして、コアコードの問題のサブセット

(4)入力と出力:

ターゲットを入力してください
 10は、
データの番号を入力:
 5は
:それぞれの数値入力
 22654 

データ配列:
 22654  
データストレージ:
 11100  
ターゲット組成の数である:
 226
入力出力

(5)まとめ:サブセットとも完全にツリーをバックトラックサブセットのコア思想、O(2の時間複雑さを反映N-をストレージソリューションによって、)と存在しない場合は、一度、かプルーン、侵入深さ検索を決定しますへの即時復帰への解決策を検索します。

  推奨事項:私は紙で絵を描く、私のコードの考えによると、肉眼を理解していない場合は再度、簡単にコードを理解するために、プロセスを解決歩く、セットツリーをバックトラックの核となるアイデアをマスターするための別の方法。

おすすめ

転載: www.cnblogs.com/blogtech/p/12302565.html