private void CandidateCB_SelectedValueChanged(object sender, EventArgs e) { Candidate newcand = Candidates_CB.SelectedValue as Candidate; if (newcand != null) { IAATBasedAgent aat = registeredAgent as IAATBasedAgent; /* * aat.CurrentCandidate = newcand; */ } }
//このメソッドはInvokeの中から呼ばれる private void PrepareCandidatesCB(IAATBasedAgent aat) { if (aat.Candidates == null) { return; } Candidates_CB.SelectedValueChanged -= CandidateCB_SelectedValueChanged; //Comboboxの中身をまず空にする。 Candidates_CB.DataSource = null; //毎回列の設定してる。もうすこし最適化できるはず。 DataTable CandidateTable = new DataTable(); CandidateTable.Columns.Add("STR", typeof(string)); CandidateTable.Columns.Add("CAND", typeof(Candidate)); lock (aat.CandidateLock) { var cands = aat.Candidates; var orderedCands = cands.OrderBy((c) => c.ImportanceLevel); foreach (Candidate cand in orderedCands) { DataRow row = CandidateTable.NewRow(); row["STR"] = string.Format("<< {0,-2} t: {1,-4:f2} h: {2,-4:f2} {3,2} >>" , cand.JumpNumLeft, cand.ImportanceLevel, cand.AwarenessRate, cand.JumpNumRight); row["CAND"] = cand; CandidateTable.Rows.Add(row); } } Candidates_CB.DataSource = CandidateTable; Candidates_CB.DisplayMember = "STR"; Candidates_CB.ValueMember = "CAND"; Candidates_CB.SelectedValue = aat.CurrentCandidate; //Candidates_CB.SelectedValueChanged += CandidateCB_SelectedValueChanged; }
static public AgentAlgorithm CreateAlgorithm(string name, double h_trg) { IAATBasedAgent algo = creators[name](); //信念など if (algo is SubOpinion) //今はまだ場合分けが少ないからいいけどいずれはFactory Methodになるかも。 { algo.Thought = new ThoughtTwin(RandomPool.Get("envset").NextNormal(0.5, 0.1)); } else { algo.Thought = new Thought(RandomPool.Get("envset").NextNormal(0.5, 0.1)); } //候補集合 algo.CandidateSelector = new CandidateUpdaterSelector(); algo.TargetAwarenessRate = h_trg; //最後に初期化 algo.Initialize(); return(algo as AgentAlgorithm); }
//エージェントの内部状態を見るもの public void RegisterAgent(IAgent agent) { //******すでに登録されていて、違うエージェントだったら既存のイベントを削除****** if (registeredAgent != null && registeredAgent != agent) { removeEvents(registeredAgent); } //******引数がnullだったら 表示を空っぽにして終了****** if(agent==null) { //nullが渡されたなら,nullを登録 registeredAgent = null; //候補をクリア Candidates_CB.DataSource = null; Candidates_CB.Items.Add(new object()); Candidates_CB.Items.Clear(); //表示を更新 Invoke(new Action(() => { IDLabel.Text = "ID"; AlgorithmLabel.Text = "Algorithm"; TargetAwarenessRateLabel.Text = "h_trg"; })); //再描画 Invalidate(); return; } //******型が合ってるかチェック*** IAATBasedAgent aat = null; if (agent is IAATBasedAgent && agent is AgentAlgorithm) { aat = agent as IAATBasedAgent; } else { Console.WriteLine("このパネルでは,AATベースのエージェントアルゴリズムしか監視できません."); return; } //****** ここまで来たら,晴れて合格.AATベースのエージェントを登録 ****** //新たなエージェントを追加 registeredAgent = aat; //イベントを監視開始 addEvents(registeredAgent); //ネットワークの指標を計算 INode bodyAsINode = ((aat as AgentAlgorithm).Body as INode); double cluster = NetworkIndexes.cluster(bodyAsINode, bodyAsINode.Network); //表示を変更する Invoke(new Action(() => { //ちょっと複雑・・・ IDLabel.Text = "ID" + (aat as AgentAlgorithm).ID;//結局Body=AgentIOを参照してる AlgorithmLabel.Text = aat.GetType().Name; TargetAwarenessRateLabel.Text = aat.TargetAwarenessRate.ToString(); PrepareCandidatesCB(aat); otherStates.Text = "cluster = " + cluster + "\r\n" + "friend = " + bodyAsINode.Neighbours.Count; })); Invalidate(); #region SHOW Console.WriteLine("registered :"+ registeredAgent); if (registeredAgent.CandidateSelector != null && registeredAgent.CandidateSelector.Candidates != null) { var candidates_greater = registeredAgent.CandidateSelector.Candidates.OrderBy((c) => c.ImportanceLevel); int i = 0; foreach (var candidate in candidates_greater) { Console.Write("[0] l: {1} r: {2} t: {3} h: {4}", i++, candidate.JumpNumLeft, candidate.JumpNumRight, candidate.ImportanceLevel, candidate.AwarenessRate); if (candidate == registeredAgent.CandidateSelector.CurrentCandidate) { Console.Write("<==== this one!"); } Console.WriteLine(); } } #endregion }
private void removeEvents(IAATBasedAgent a) { a.BeliefChanged -= AgentBeliefChanged; a.OpinionChanged -= AgentOpinionChanged; a.CandidateChanged -= AgentCandidateChanged;//イベントも追加 }
public void RegisterAgent(IAgent agent)//エージェントの内部状態を見るもの { //******すでに登録されていて、違うエージェントだったら既存のイベントを削除****** if (registeredAgent != null && registeredAgent != agent) { removeEvents(registeredAgent); } //******引数がnullだったら 表示を空っぽにして終了****** if (agent == null) { //nullが渡されたなら,nullを登録 registeredAgent = null; //候補をクリア Candidates_CB.DataSource = null; Candidates_CB.Items.Add(new object()); Candidates_CB.Items.Clear(); //表示を更新 Invoke(new Action(() => { IDLabel.Text = "ID"; AlgorithmLabel.Text = "Algorithm"; TargetAwarenessRateLabel.Text = "h_trg"; })); //再描画 Invalidate(); return; } //******型が合ってるかチェック*** IAATBasedAgent aat = null; if (agent is IAATBasedAgent && agent is AgentAlgorithm) { aat = agent as IAATBasedAgent; } else { Console.WriteLine("このパネルでは,AATベースのエージェントアルゴリズムしか監視できません."); return; } //****** ここまで来たら,晴れて合格.AATベースのエージェントを登録 ****** //新たなエージェントを追加 registeredAgent = aat; //イベントを監視開始 addEvents(registeredAgent); //ネットワークの指標を計算 INode bodyAsINode = ((aat as AgentAlgorithm).Body as INode); double cluster = NetworkIndexes.cluster(bodyAsINode, bodyAsINode.Network); //表示を変更する Invoke(new Action(() => { //ちょっと複雑・・・ IDLabel.Text = "ID" + (aat as AgentAlgorithm).ID;//結局Body=AgentIOを参照してる AlgorithmLabel.Text = aat.GetType().Name; TargetAwarenessRateLabel.Text = aat.TargetAwarenessRate.ToString(); PrepareCandidatesCB(aat); otherStates.Text = "cluster = " + cluster + "\r\n" + "friend = " + bodyAsINode.Neighbours.Count; })); Invalidate(); #region SHOW Console.WriteLine("registered :" + registeredAgent); if (registeredAgent.CandidateSelector != null && registeredAgent.CandidateSelector.Candidates != null) { var candidates_greater = registeredAgent.CandidateSelector.Candidates.OrderBy((c) => c.ImportanceLevel); int i = 0; foreach (var candidate in candidates_greater) { Console.Write("[0] l: {1} r: {2} t: {3} h: {4}", i++, candidate.JumpNumLeft, candidate.JumpNumRight, candidate.ImportanceLevel, candidate.AwarenessRate); if (candidate == registeredAgent.CandidateSelector.CurrentCandidate) { Console.Write("<==== this one!"); } Console.WriteLine(); } } #endregion }
private void FigurePanel_Paint(object sender, PaintEventArgs e) { if (agentViews == null) { return; } //***************************基本的な設定*************************** var g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; int ActualWidth = this.ClientSize.Width; int ActualHeight = this.ClientSize.Height; //***************************ブラシなどの準備*************************** //色の基本 float hue = 200; //色相 青系:200 float vOffset = 0.3f; //Vのオフセット 高いほど明るくなる //色 Color OpWhiteColor = Util.StaticColor.ConvertHSBtoARGB(hue, 1f - 1f, 1f); Color OpBlackColor = Util.StaticColor.ConvertHSBtoARGB(hue, 1f - 0f, vOffset); Color OpUndeterColor = Util.StaticColor.ConvertHSBtoARGB(hue, 1f - 0.5f, (1f - vOffset) * 0.5f + vOffset); Color OrangeColor = Util.StaticColor.ConvertHSBtoARGB(40F, 0.9F, 0.9F); Color GreenColor = Util.StaticColor.ConvertHSBtoARGB(91F, 0.62F, 0.80F); Color PriorColor = Util.StaticColor.ConvertHSBtoARGB(hue, 0.5f, 0f); //ペン Pen blackPen = new Pen(Color.Black); Pen blackThinPen = new Pen(Color.Black); blackThinPen.Width = 1; Pen grayPen = new Pen(Color.Gray); grayPen.Width = 2; grayPen.StartCap = grayPen.EndCap = LineCap.Round; Pen priorBeliefPen = new Pen(PriorColor); priorBeliefPen.StartCap = priorBeliefPen.EndCap = LineCap.Round; priorBeliefPen.Width = 1; Pen linkPen = new Pen(GreenColor); linkPen.Width = 1.5f; Pen selectedLinkPen = new Pen(new SolidBrush(Color.Red)); selectedLinkPen.Width = 3f; Pen sensorPen = new Pen(OrangeColor); sensorPen.Width = 10; Pen sensorNetworkPen = new Pen(OrangeColor); sensorNetworkPen.Width = 10; Pen redPen = new Pen(Color.Red); redPen.Width = 3; Pen meterPen = new Pen(Util.StaticColor.ConvertHSBtoARGB(hue, 1f - 0f, vOffset)); meterPen.Width = 2; meterPen.StartCap = meterPen.EndCap = LineCap.Round; //ブラシ SolidBrush redBrush = new SolidBrush(Color.Red); SolidBrush grayBrush = new SolidBrush(Color.Gray); SolidBrush lightGrayBrush = new SolidBrush(Color.LightGray); SolidBrush beliefBrush = new SolidBrush(Util.StaticColor.ConvertHSBtoARGB(100F, 0.9F, 0.8F)); SolidBrush opinionBrush = new SolidBrush(Util.StaticColor.ConvertHSBtoARGB(0F, 0F, 1F)); //四隅をためしに描画 g.FillRectangle(beliefBrush, 0, 0, 10, 10); g.FillRectangle(beliefBrush, ActualWidth - 10, 0, 10, 10); g.FillRectangle(beliefBrush, ActualWidth - 10, ActualHeight - 10, 10, 10); g.FillRectangle(beliefBrush, 0, ActualHeight - 10, 10, 10); //***************************縮尺を変更*************************** Matrix scaleMat = new Matrix(); scaleMat.Scale(scale, scale); g.Transform = scaleMat; //AgentPanelに監視されてるエージェント IAATBasedAgent selected = AgentStatePanel.Agent; //リンクを描く 緑の線 if (DrawLinks) { foreach (Link li in Environment.Network.Links) { AgentIO agent1 = li.Node1 as AgentIO; AgentIO agent2 = li.Node2 as AgentIO; Point p1 = new Point((int)agentViews[agent1].X, (int)agentViews[agent1].Y); Point p2 = new Point((int)agentViews[agent2].X, (int)agentViews[agent2].Y); //センサーネットワークを表示する場合表示 if (showSensorNetworkCB.Checked) { if (agent1.HasSensor || agent2.HasSensor) { g.DrawLine(sensorNetworkPen, p1, p2); } else if (showOnlySensorNetworkCB.Checked) { continue; } } //選択中のものならばそう表示 if (selected != null && (agent1.Algorithm == selected || agent2.Algorithm == selected)) { g.DrawLine(selectedLinkPen, p1, p2); } else { g.DrawLine(linkPen, p1, p2); } } } //絶対行列を記録 Matrix absoluteMatrix = g.Transform; //エージェントを描く foreach (AgentIO agentIO in Environment.Network.Nodes) { //******************各種サイズ************************** float r = agentViews[agentIO].R; float r2 = r * 2; float r3 = r * 3; float r4 = r * 4; float r_outer = r3; { //エージェントの位置に移動 //絶対行列に戻す g.Transform = absoluteMatrix; //エージェントの位置に移動 Matrix agentMatrix = g.Transform; agentMatrix.Translate(agentViews[agentIO].X, agentViews[agentIO].Y); g.Transform = agentMatrix; } //センサーネットワークだけを表示する設定になっている場合 if (showSensorNetworkCB.Checked && showOnlySensorNetworkCB.Checked) { //センサーネットワークに入っているか否か bool inNetwork = false; //センサーエージェントならば入っている if (agentIO.HasSensor) { inNetwork = true; } //それ以外でも,友達がセンサーネットワークならばOK else { //友達を調べる foreach (var neighbour in agentIO.Neighbours) { if ((neighbour as AgentIO).HasSensor) { inNetwork = true; } } } //ネットワークに入っているならば処理を続ける. if (inNetwork == true) { //ok } //ネットワーに入っていないならば処理を中断する. else { continue; } } //エージェントが描けない場合は丸書いて終わり if (!agentIO.Drawable) { g.FillEllipse(grayBrush, -r_outer / 2, -r_outer / 2, r_outer, r_outer); continue;//break;にすべきかも } IAATBasedAgent aat = agentIO.Algorithm as IAATBasedAgent; //エージェントの内部状態 float agentBelief = (float)(aat.Belief); float priorBelief = (float)(aat.PriorBelief); float sigmaRight = (float)(aat.Sigma); float sigmaLeft = 1 - sigmaRight; //ペンの太さを設定 priorBeliefPen.Width = agentViews[agentIO].PenWidth; sensorPen.Width = priorBeliefPen.Width; //意見によってブラシの色を変更 if (agentIO.Opinion == BlackWhiteSubject.White) { opinionBrush.Color = OpWhiteColor; } else if (agentIO.Opinion == BlackWhiteSubject.Black) { opinionBrush.Color = OpBlackColor; } else { opinionBrush.Color = OpUndeterColor; } //信念によってブラシの色を変更 //beliefBrush.Color = Util.StaticColor.ConvertHSBtoARGB(240 - (240 * agentBelief), 1f, 1f); beliefBrush.Color = Util.StaticColor.ConvertHSBtoARGB(hue, 1f - agentBelief, (1 - vOffset) * agentBelief + vOffset); //初期値は今は使ってない priorBeliefPen.Color = Util.StaticColor.ConvertHSBtoARGB(hue, 1f - priorBelief, (1 - vOffset) * priorBelief + vOffset); //panelによって注目しているエージェントを描画 if (agentIO == selected)//|| i.ChangedOpinion) { g.DrawEllipse(redPen, -r2, -r2, r2 * 2, r2 * 2); } //意見の円 g.FillEllipse(opinionBrush, -r_outer / 2, -r_outer / 2, r_outer, r_outer); //扇型を表示 { float zeroDeg = 180f; float sigmaLeftDeg = (sigmaLeft * 180f + zeroDeg); float sigmaRightDeg = (sigmaRight * 180f + zeroDeg); float sigmaSweepDeg = (sigmaRight - sigmaLeft) * 180f; g.FillPie(lightGrayBrush, -r_outer / 2, -r_outer / 2, r_outer, r_outer, zeroDeg, 180); g.FillPie(grayBrush, -r_outer / 2, -r_outer / 2, r_outer, r_outer, sigmaLeftDeg, sigmaSweepDeg); } //髪の毛を生成.しかし,毎回つくるのはしゃくだな・・・ var beliefList = calcBeliefList(aat.PriorBelief, aat.Sigma, aat.CandidateSelector.BeliefUpdater); /* 将来なるであろうBelief */ foreach (double futureBelief in beliefList) { g.DrawLine(blackThinPen, 0, 0, r_outer / 2 * (float)Math.Cos(Math.PI * futureBelief + Math.PI), r_outer / 2 * (float)Math.Sin(Math.PI * futureBelief + Math.PI)); } //priorBelief g.DrawLine(blackThinPen, 0, 0, r_outer / 2 * (float)Math.Cos(Math.PI * priorBelief + Math.PI), r_outer / 2 * (float)Math.Sin(Math.PI * priorBelief + Math.PI)); //*/ //外枠の円 g.DrawEllipse(priorBeliefPen, -r_outer / 2, -r_outer / 2, r_outer, r_outer); //信念のmeter g.DrawLine(meterPen, 0, 0, r3 * (float)Math.Cos(Math.PI * agentBelief + Math.PI), r3 * (float)Math.Sin(Math.PI * agentBelief + Math.PI)); //信念の円 g.FillEllipse(beliefBrush, -r / 2, -r / 2, r2 / 2, r2 / 2); } g.Transform = absoluteMatrix; //センサーを描く foreach (var s in Environment.Sensors) { var view = agentViews[s.Agent as AgentIO]; float r2 = view.R * 2; g.DrawRectangle(sensorPen, view.X - r2, view.Y - r2, r2 * 2, r2 * 2); } }
//float plustheta = 0;//無駄コード public void calcAgentViews() { //エージェント数からレイヤー数を決めるべき //ノードの数 int N = Environment.Network.Nodes.Count(); int layerNum = (int)Math.Ceiling((double)N / 90);//層の分割数 //画面幅 int ActualWidth = this.ClientSize.Width; int ActualHeight = this.ClientSize.Height; //小さい方 = 使うサイズ int ActualSize = Math.Min(ActualWidth, ActualHeight); //View agentViews = new Dictionary <AgentIO, AgentView>(); //レイヤーにどう割り振るかの配列 var divideArray = Enumerable.Range(1, layerNum); // 1, 2, 3, 4=layerNum var cumDivideArray = cum(divideArray); // 1, 3, 6, 10=divideNum int divideNum = divideArray.Sum(); // 1+2+3+4 //それぞれのレイヤーの数 int[] Ns = new int[layerNum]; for (int i = 0; i < layerNum; i++) { Ns[i] = (int)(Math.Ceiling((float)N * (layerNum - i) / divideNum)); //layerNum=4 = divideArray.Last } //エージェントを均等に配置したときの角度 float[] dthetas = new float[layerNum]; for (int i = 0; i < layerNum; i++) { dthetas[i] = (float)1 / Ns[i] * 2 * (float)Math.PI;//小 } //集団の丸 float R = (float)ActualSize / 2F * 0.95F; float R2 = R / 2; //エージェントの半径 float r = dthetas[0] * R / 4;// float w = r / 4; float[] thetas = new float[layerNum]; int agent_i = 0; foreach (AgentIO agent in Environment.Network.Nodes) { IAATBasedAgent aat = agent.Algorithm as IAATBasedAgent; float theta = 0; float newR = R; //どう移動するか、図的には決まってるのでアルゴリズム的に考えなくては。 //まずは、divideNumで%する。出てきた数字を4444333221となめていく。 //変数使わずにできるか? int mod = agent_i++ % divideNum; mod += 1; for (int i = 0; i < layerNum; i++) { if (mod <= cumDivideArray.ElementAt(i)) { newR *= (i + 1f) / layerNum; thetas[layerNum - 1 - i] += dthetas[layerNum - 1 - i]; theta = thetas[layerNum - 1 - i]; break; } } float x = (float)Math.Sin(theta) * newR + ActualWidth / 2; float y = (float)Math.Cos(theta) * newR + ActualHeight / 2; agentViews[agent] = new AgentView(x, y, r, w); } }