public virtual bool OpinionFormed(Candidate can, BlackWhiteSubject? Opinion, UpdateCounter counter) { //ImportanceLevelに依存 //3つの条件の論理式 //意見を決められたか bool determined = Opinion != null; //現在のより大きいか? bool bigger = can.ImportanceLevel >= ImportanceLevel; //この候補にとって十分な意見が来たか? /* bool enoughUpd = counter.UpdateNum > 0 ? //この場合わけをすべきか? counter.UpdateRight >= can.JumpNumRight : //正だったらrightと比べる counter.UpdateLeft >= can.JumpNumLeft; //負だったらleftと比べる */ bool enoughUpd = counter.UpdateRight >= can.JumpNumRight || counter.UpdateLeft >= can.JumpNumLeft;//一番近いσを,超えられるか //意見を決められていて、候補の方が大きいか、 もしくは、十分な意見が来たか。 return (determined && bigger) || enoughUpd; }
public CandidateEventArgs(Candidate u) { cand = u; }
//候補集合を初期化 public void BuildCandidate(int neighbourNum, IThought thought)//ご近所の数と初期重要視度を渡されることで候補を生成 { if (neighbourNum <= 0) { return; } //Sigma=Thought PriorBelief=Thought updateFunc=BeliefUpdater lock (CandidateLock) { //ご近所の数 int dn = neighbourNum; //ご近所の数の2倍だけ作成 candidates = new Candidate[2 * dn]; double sigmaRight = thought.SigmaRight; double sigmaLeft = thought.SigmaLeft; double impLvl = 0.5; // Jumpnum = 3, 2, 1と調べていく. for (int l = dn; l >= 0; l--) { //importance levelを上げていって,beliefがしきい値を超えたときその値を使う. for (; impLvl <= 1; impLvl += 0.001) { if (BeliefUpdater.updateFunc(thought.PriorBelief, impLvl, l) > sigmaRight) { Candidate newcan = new Candidate(l, impLvl); //この重要視度で、逆側に行くときは、何ステップでいけるのか? double tmpBelief = thought.PriorBelief; int count = 0; do { tmpBelief = BeliefUpdater.updateFunc(tmpBelief, 1 - impLvl);//逆では1-impLvl count++; } while (!(tmpBelief <= sigmaLeft)); newcan.OtherJumpNum = count; candidates[l - 1] = newcan; break; } } } impLvl = 0.5; for (int l = dn; l >= 0; l--) { for (; impLvl <= 1; impLvl += 0.001) //impLvl ∈ (0.5, 1.0) { if (BeliefUpdater.updateFunc(thought.PriorBelief, 1 - impLvl,l) < sigmaLeft) { //重要視度を決定 Candidate newcan = new Candidate(-l, impLvl); //この重要視度で、逆側に行くときは、何ステップでいけるのか? double tmpBelief = thought.PriorBelief; int count = 0; do { tmpBelief = BeliefUpdater.updateFunc(tmpBelief, impLvl);//1-impLvlの逆なのでimpLvl count++; } while (!(tmpBelief >= sigmaRight));//0.8を超えたら newcan.OtherJumpNum = count; candidates[l - 1 + dn] = newcan; break; } } } }//lock CurrentCandidate = candidates.Last(); OnEstimationChanged(new EstimationEventArgs(Candidates)); OnCandidateChanged(new CandidateEventArgs(CurrentCandidate)); }
// step 1 of AAT プログラムの最初に呼び出す 馬鹿正直.まだまだ最適化できる. public virtual IEnumerable<Candidate> BuildCandidates() { lock (CandidateLock) { //ご近所の数 int dn = base.Neighbours.Count(); //ご近所の数の2倍だけ作成 candidates = new Candidate[2 * dn]; double sigmaRight = Sigma; double sigmaLeft = 1 - Sigma; double impLvl = 0.5; // Jumpnum = 3, 2, 1と調べていく. for (int l = dn; l >= 0; l--) { //importance levelを上げていって,beliefがしきい値を超えたときその値を使う. for (; impLvl <= 1; impLvl += 0.001) { if (updateFunc(l, PriorBelief, impLvl) > sigmaRight) { Candidate newcan = new Candidate(l, impLvl); //この重要視度で、逆側に行くときは、何ステップでいけるのか? double tmpBelief = PriorBelief; int count = 0; do { tmpBelief = updateFunc(tmpBelief, 1 - impLvl);//逆では1-impLvl count++; } while (!(tmpBelief <= 1 - Sigma)); newcan.OtherJumpNum = count; candidates[l - 1] = newcan; break; } } } impLvl = 0.5; for (int l = dn; l >= 0; l--) { for (; impLvl <= 1; impLvl += 0.001) //impLvl ∈ (0.5, 1.0) { if (updateFunc(l, PriorBelief, 1 - impLvl) < sigmaLeft) { //重要視度を決定 Candidate newcan = new Candidate(-l, impLvl); //この重要視度で、逆側に行くときは、何ステップでいけるのか? double tmpBelief = PriorBelief; int count = 0; do { tmpBelief = updateFunc(tmpBelief, impLvl);//1-impLvlの逆なのでimpLvl count++; } while (!(tmpBelief >= Sigma));//0.8を超えたら newcan.OtherJumpNum = count; candidates[l - 1 + dn] = newcan; break; } } } } return candidates; }
// step 3 public Candidate SelectTheBest() { Candidate[] sortedCandidates = new Candidate[candidates.Count()]; //昇順に並び替える IEnumerable<Candidate> sorted = candidates.OrderBy((el) => el.ImportanceLevel); for (int i = 0; i < candidates.Length; i++) { sortedCandidates[i] = sorted.ElementAt(i); } {//選ばれないときがあるから注意!!! //最初(currentCandidateが一度も選ばれてないとき)は適当に選択 if (currentCandidate == null) {//最初のみ。 return sortedCandidates.Last();//おっきいやつを選ぶ; } //現在使っている候補 int i = Array.IndexOf(sortedCandidates, currentCandidate); //Debug.Assert(sortedCandidates[i] == currentCandidate); if (i == -1) { i = 0; } //小さければ一個すすめる if (sortedCandidates[i].AwarenessRate < h_trg) { i++; } //一個下がh_trg以上ならば戻る. else if ((i > 0) && sortedCandidates[i - 1].AwarenessRate > h_trg) { i--; } else { ;//現状維持 } if (i < 0) i = 0; if (i >= sortedCandidates.Length) i = sortedCandidates.Length - 1; return sortedCandidates[i]; } // */ }
// step2で使われる。このimportance levelは意見形成できるかどうか public virtual bool OpinionFormed(Candidate can) { //3つの条件の論理式 //意見を決められたか bool determined = Opinion != null; //現在のより大きいか? bool bigger = can.ImportanceLevel >= ImportanceLevel; //この候補にとって十分な意見が来たか? bool enoughUpd = updatedNum > 0 ? updatedNum >= can.JumpNumRight: //正だったらrightと比べる -updatedNum >= can.JumpNumLeft; //負だったらleftと比べる //意見を決められていて、候補の方が大きいか、 もしくは、十分な意見が来たか。 return (determined && bigger) || enoughUpd; }
//コンストラクト時に呼ばれる public override void Initialize() { base.Initialize(); //h_trgは多分変わってないだろう candidates = null; currentCandidate = null; updatedNum = 0; }