バックトラッキング関数に問題があり、特定のデータでループします。プログラムコード全体をここに書くことはできませんが、関数をここに置くことはできます。
bool shareMoney(int quantity, int *values, int index, int moneyA, int half, bool *ifChosen)
{
if(moneyA == half)
return true;
else if(index >= quantity)
return false;
moneyA += values[index];
if(shareMoney(quantity, values,index+1, moneyA, half, ifChosen))
{
ifChosen[index] = true;
return true;
};
moneyA -= values[index];
if(shareMoney(quantity, values,index+1, moneyA, half, ifChosen))
{
ifChosen[index] = false;
return true;
};
return false;
}
ここに説明があります:
quantity - 値配列内の要素
の数 values -数値の配列
index - 再帰を制御する
変数 moneyA - 配列値の要素の合計を格納する変数half
-
再帰が行われた後に moneyA が到達する必要がある数値
配列値を参照します
この関数は、長さの値の配列である要素の数量を取得します。値は、数値を含む配列を最高のものから最低のものに並べ替え、インデックスは再帰を制御し、デフォルトは 0 であるため、最初の要素から開始します。money からの数値を格納する変数値配列と、値配列から合計された数値の半分である半分に達する必要があり、ifChosen は選択された数値を格納します。
関数全体がこれを行い、values 配列の要素を合計し、半分未満の場合は半分に達したかどうかをチェックし、それを moneyA に追加し、ifChosen でマークしてから、合計が半分より大きい場合は次の要素に進みます戻り、ifChosen 配列でマークを外し、moneyA から減算します。常に最高の要素を取得する必要があります。
簡単な例を次に示します。
6 - number of elements
50, 20, 19, 15, 2, 2 - elements stored in values array
total sum is - 108
half of elements - 54
この結果は次のようになります。
50, 2, 2 - marked as true in ifChosen
20, 19, 15 - marked as false in ifChosen
もちろん、この単純な例では素晴らしい仕事をしますが、より多くの数字を持ち、1 つの数字が複数回出現するより複雑な例では、ループして再帰が停止しません。私は実際にこれに1.5週間取り組んでおり、すべての友人に尋ねましたが、何が問題なのか誰も知りません. ナップザックの問題と少し関係があることは知っていますが、まだそれを持っていないので、まだ勉強する必要があります.
役立つ回答をお待ちしております。
句読点で申し訳ありませんが、私は初めてここに来て、フォーマットに慣れていませんでした。
ここに1つの例があります:
89 86 83 67 53 45 5 1
44 43 34 33 33 24 23 23 23 22 21 21 19 12 11 9 8 7 5 3 2 2 2 1 1 1 1 1
real 0m28.007s
user 0m27.926s
sys 0m0.028s
今、私はそれが永遠にループすると思うもの: 43 要素:
12 2 2 1 3 4 5 6 7 89 33 12 45 23 44 23 11 44 1 3 5 7 88 33 8 19 43 22 86 5 34 23 21 67 83 24 21 53 9 11 34 1 1
@Karl Bielefeldtはい、非常に多くの組み合わせがあることを知っているので、速度を上げようとしています。今のところこれですべてですが、特定の入力に対して間違った結果が得られます。誰でもそれを修正できますか?以前よりもはるかに高速に動作しますか?
bool shareMoney(int quantity, int *values, int index, int moneyA, int half, bool *ifChosen){
if(index>=quantity && moneyA == half){ return true;}
else if(index>=quantity) return false;
moneyA+=values[index];
ifChosen[index]=true;
if(moneyA<=half){
shareMoney(quantity,values,index+1,moneyA, half,ifChosen);
if(moneyA==half) return true;
return true;
}else{
shareMoney(quantity,values,index+1,moneyA, half,ifChosen);
moneyA-=values[index];
ifChosen[index]=false;
return true;
}
return false;}