2016-03-28 2 views
5

ここでの最初のコメント擬似コードです:JavaScriptは無限ループを防ぎます - 動的認識パターンを持つ可能性がありますか?

// TODO: 
// Person A (80kg) nutrition intake requirements are: 
// nutrient  || Unit(g) 
// Vitamin A : 30, 
// Vitamin B1 : 2, 
// Vitamin C : 300, 
// Vitamin D : 3000, 
// Protein  : 100, 
// Calcium  : 30 

var nutrient_requirements = { 
    vita: {min: 30 ,max: 38}, 
    vitb1: {min:2, max:4}, 
    vitc: {min:300, max: 800}, 
    vitd: {min: 300, max:3000}, 
    protein: {min:100, max:200}, 
    calcium: {min:30, max:50} 
} 

// The calculated estimate amount of food 
// the person eats on a daily base is around 900(g) 
// The amount will be distributed among the terms 
// with a predefined pattern 

var food_amount = { 
    fruits:[200,200], 
    meat: [500] 
} 

// START (usefull anchor for this pseudocode) 

var calculated_nutrition = { 
    vita: 0, 
    vitb1: 0, 
    vitc: 0, 
    vitd: 0, 
    protein: 0, 
    calcium: 0 
} 

// The daily nutrition intake of this person 
// needs to be achieved by the following terms: 
// apple, banana, chicken breast 
// Term nutrient values per gramm 
var terms = { 
    fruits:[ 
    apple:{ 
     vita: 0.02, 
     vitc: 0.30, 
     vitd: 0.01, 
     protein: 0.08, 
     calcium: 0 
    }, 
    banana:{ 
     vita: 0.1, 
     vitc: 0.09, 
     vitd: 0.00, 
     protein: 0.1, 
     calcium: 0.2 
    } 
    ], 
    meat:[ 
    chicken_breast:{ 
     vita: 0.07, 
     vitc: 0.08, 
     vitd: 0.03, 
     protein: 0.4, 
     calcium: 0.2 
    } 
    ] 
} 

// Now we want to see if the normal amount and distribution 
// of the food covers the required amount 
// To do that we need to multiply the matching food amount 
// with the matching food/term and sum up all values 

for(let prop in terms){ 
    for(let i = 0; i < terms[prop].length; i++){ 
    for(let propb in terms[prop][i]){ 
     calculated_nutrition[propb] = terms[prop][i][propb] * food_amount[prop][i]; 
    } 
    } 
} 

// After that is done, we can compare calculated_nutrition to 
// nutrient_requirements to see whether something is too much 
// or too little 

for(let propa in nutrient_requirements){ 
    if(nutrient_requirements[propa].min > calculated_nutrition[propa]){ 
    // this nutrient level is too little 
    // now we need to increase some food/term 
    // in order to achieve the required minimum 
    // of this nutrient 
    alter_amount(propa, "up"); 
    return; 
    }else if(nutrient_requirements[propa].max < calculated_nutrition[propa]){ 
    // this nutrient level is too high 
    // now we need to decrease some food/term 
    // in order to achieve the required minimum 
    alter_amount(propa, "down"); 
    return; 
    }else{ 
    // this nutrient level is ok 
    return; 
    } 
} 

function alter_amount(prop, direction){ 
    // here we look in terms which food 
    // has the highest amount of prop 

    switch(direction){ 
    case "down": 
     // here we decrease the amount of 
     // the matching term in the amount object 
      // and re-run this whole calculation from 
     // point START 
     break; 
    case "up": 
     // here we increase the amount of 
     // the matching term in the amount object 
      // and re-run this whole calculation from 
     // point START 
    break; 
    } 
} 

は、私は簡単にこの例を説明しましょう。

計算された期待される結果は、毎日の栄養目標を達成するために、人は1日にX量のリンゴ、Y量のバナナおよび鶏の胸部を1日に食べる必要があるということです。

私の擬似コードでは、私のプログラムの基本的な機能を書き留めました。私が直面している現在の問題は、ある特定の食べ物が、あるループで量が増えるのにふさわしい場合、別のループの量を減らすのに最適です - 私は無限ループに終わります。

私の最小限の例に基づいて、アップルの量が増えれば、それは次のループで減少しないはずですが、私の実際のプログラムでは、より多くのプロパティ。したがって、それをカバーする複雑さは非常に高くなります。

パターンを認識するための方法を探していますが、結果が得られず、無限ループで終わらないように、2番目に優れた食べ物を増減させるよう指示します。

このような何かを回避されることを:

apple ++ 
apple ++ 
banana ++ 
apple ++ 
banana ++ 
meat -- 

apple -- 
apple -- 
banana -- 
apple -- 
banana -- 
meat ++ 

apple ++ 
apple ++ 
banana ++ 
apple ++ 
banana ++ 
meat -- 

apple -- 
apple -- 
banana -- 
apple -- 
banana -- 
meat ++ 
... 

EDIT

いくつかのハッシュを促進し、システムを格納下記の答えは、私は私のカスタムブラックリスト方式で発生する同じ結果につながります。

私のブラックリスト方式は、次のように動作します

アップルの量は、(減少/増加)に変更されました - >配列をブラックリストに載せることを保存します。

blacklist = [{product: "apple", altered: "down/up"},...] 

増分または減分する食品を選択する前のすべてのループごとに、ブラックリストがスキャンされます。完璧なフィットが配列内にある場合は、2番目に最適なフィットが選択されます。

次のようないくつかの追加の制限があります。りんごは総量のx%を超えてはならない。またはリンゴは総量のx%以上であってはならない。進行なしの制約の組み合わせ+で

私のプログラムは、それが増減するためにこれ以上の異なる食品を持っていないし、単に何も変更しないと無限ループに終了状態で終了しブラックリストに載った製品

Iドンその問題をプログラマチックに解決する方法があるかどうかを知ることさえありません。あるいは、ちょっと、ちょっと、その問題は解決できません。

私が考えているのは、機能が実装されていることをプログラムが認識していることを認識していることです。 - >固まった状態につながるパターンを記憶して、別のアプローチで再度試みます。しかし、それは考え過ぎるかもしれません。

+0

スタックオーバーフローのガイドラインでは、コードを質問に入れる必要があります。質問を理解するため、および/または回答を形成するために必要なコードは、質問自体に含まれていなければなりません。あなたがjsFiddleで持っているコードの量は、あまりにも多くのコードを直接質問に入れることではありません。この理由は、外部リンクが消えたり変更されたりする傾向があるため、将来の参照ソースとして役立たずになります。 – jfriend00

+0

ありがとう私はコードを追加しました。 –

+0

サンプルテストケースを入力してください(入力と希望出力)。 –

答えて

3

解決策は、以前に訪れたすべての州のセットを覚えておき、州を2回入力することを避けることです(「タブー」としてマークする)。

状態変化が小さい場合(つまり、あなただけのいくつかの値を変異させた場合)、その後に有用なトリックは、次の状態のハッシュコードがnは、変更の数ですO(n)で計算することができるように、「zobrist hashing"を使用することです変数の数ではなく、変数の数ではありません。

+0

「タブー」はいつ削除されますか?私があなたのソリューションを正しく理解していれば、変異したすべてのオブジェクトを含む配列を作成できます。オブジェクトがリストにある場合は、次のループなどでは避けてください。リストにすべての変更されたオブジェクトを置くだけでは、何も残されません。 –

+0

@ noa-dev:アイデアは配列を保持することです**全体のソリューション**はすでに検討されており、ソリューション全体が存在する場合は、再度チェックしないでください。解決策が既に訪問済みのリストにあるかどうかをチェックする速度を上げるために、ハッシングとゾブリストハッシュを使用することができます。これは、小さな変更に対してハッシュコードの計算を高速化するテクニックです。 – 6502

+0

あなたはとても親切で、私のユースケースに基づいた例を提供しますか?私は本当にそれを感謝します! –

1

あなたの説明に基づいて、私はあなたが古典的な(Unbounded) Knapsack Problemを扱っていると思います。その目的は、特定の測定値を達成するためのアイテム(食品タイプ)の最適な組み合わせを見つけることですあなたの疑似コードはこの問題を正しく解決することはできません。

この問題にはさまざまなパラメータがあります。

  • 各栄養の重さはどれくらいですか?
  • より良い結果を得るために、1つの栄養が少しを超えることはできますか?
  • どのコンボが優れているかをどのように判断しますか? (コンボをスコアに減らす方法)
  • 同じように良いと考えられるコンボがいくつかある場合は、どちらを選択するのですか?

これらの質問に答えられない場合は、理想的な結果が得られません。物事が悪くなったら、あなたはアルゴリズムに悩まされます。

私は、上記の質問に対する答えとして私の個人的な考えを使用して、2つの栄養素と2つの食物タイプで、ブルートフォースの解決策を実証するスニペットを書きました。

栄養/食品の種類を追加するときに問題のスペースが非常に迅速になりますが、現代のブラウザでは妥当な時間枠内で実行できるように、さまざまな調整をいつでも行うことができます。

JSFiddleを参照してください。 (行の折り返しを無効にすることができます)

+0

あなたの答えをありがとう - 私はすぐにそれを調べます。あなたの質問に答えるには、 "それぞれの栄養の重さはどれですか"。金額オブジェクトでは、金額と金額がGRAMMS(g)に等しいことがわかります。 –

+0

栄養要求オブジェクトは、達成する必要のある最小値と超えてはならない最大値からなる「行き先」の値を表します –

+0

@ noa-dev混乱のために申し訳ありませんが、 "の代わりに" weight(ing) "を使用します。組み合わせを作成するとき、アイテムは異なる重要性を持つことがあります。バッグに物を入れるときは、「最高値」または「最大量」を目指すことができます。この設定によって、異なるコンボが「より良い」と見なされる場合があります。私はデモでも同じ重要性を使用しました。アルゴリズムを調整するために、これを(指定した範囲とともに)変更することができます。 – Dai

関連する問題