Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ch 2 - Add Performance measure visualisation #133

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 138 additions & 0 deletions 2-Intelligent-Agents/c_cleaningRobot.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ function makeDiagram(selector) {
function renderWorld(diagram) {
for (let floorNumber = 0; floorNumber < diagram.world.floors.length; floorNumber++) {
diagram.floors[floorNumber].attr('class', diagram.world.floors[floorNumber].dirty? 'dirty floor' : 'clean floor');

}
diagram.robot.style('transform', `translate(${diagram.xPosition(diagram.world.location)}px,100px)`);
}
Expand Down Expand Up @@ -233,7 +234,144 @@ function makeTableControlledDiagram() {
}
}

/*Control the daigram based on the performance parameters set
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check spelling, punctuation, spacing everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I will surely correct them.

by the reader that the AI is supposed to follow.The animation flow
is similar to the first agent controlled diagram but there is an
additional table UI that lets the reader view the percepts and actions
being followed as well as change the rules followed by the agent.
*/
function makePerformanceControlledDaigram(){
//variable declarations for the agents
let diagram_agent1 = makeDiagram('#performance-controlled-diagram-agent1 svg');
let diagram_agent2 = makeDiagram('#performance-controlled-diagram-agent2 svg');
var parameters = getRulesFromPage(); //reader defined agent parameters
var score_agent1 = 0;
var score_agent2 = 0;
var performance_agent1 = [];
var performance_agent2 = [];
var agent2_interval;

//update agent1's environment
function update_agent1() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code for updating agent1 and the code for updating agent2 are almost the same. These two should use shared code.

let location = diagram_agent1.world.location;
let percept = diagram_agent1.world.floors[location].dirty;
let table = getRulesFromPage();
let action = reflexVacuumAgent(diagram_agent1.world, table);
setTimeout(function(){ if(action=='SUCK'){ score_agent1 = score_agent1+50; }
else{ score_agent1 = score_agent1-10; }
if(diagram_agent1.world.floors[0].dirty || diagram_agent1.world.floors[1].dirty)
{ score_agent1 = score_agent1-5; }
performance_agent1.push(score_agent1);
diagram_agent1.world.simulate(action);
renderWorld(diagram_agent1);
renderAgentPercept(diagram_agent1, percept);
renderAgentAction(diagram_agent1, action);},table[1]*1000);
}

//update agent2's environment
function update_agent2() {
let location = diagram_agent2.world.location;
let percept = diagram_agent2.world.floors[location].dirty;
let table = getRulesFromPage();
let action = reflexVacuumAgent(diagram_agent2.world, table);
setTimeout(function(){ if(action=='SUCK'){ score_agent2 = score_agent2+50; }
else{ score_agent2 = score_agent2-10; }
if(diagram_agent2.world.floors[0].dirty || diagram_agent2.world.floors[1].dirty)
{ score_agent2 = score_agent2-5-parseInt(parameters[0]); }
// extra score reduction due to agent2 working for a shorter duration
performance_agent2.push(score_agent2);
diagram_agent2.world.simulate(action);
renderWorld(diagram_agent2);
renderAgentPercept(diagram_agent2, percept);
renderAgentAction(diagram_agent2, action);},table[1]*1000);
}

//print performace scores
//setInterval(plotPerformance(performance_agent1, performance_agent2),STEP_TIME_MS);
setInterval(function(){ plotPerformance(performance_agent1, performance_agent2); },STEP_TIME_MS);

//get reader defined parameters
function getRulesFromPage() {
let table = d3.select("#performance-controlled-diagram table");
let dirt_freq = table.select("[data-action=dirt-freq] select").node().value;
let speed_agent1 = table.select("[data-action=speed-agent1] select").node().value;
let speed_agent2 = table.select("[data-action=speed-agent2] select").node().value;
let interval_agent2 = table.select("[data-action=interval-agent2] select").node().value;
return [dirt_freq, speed_agent1, speed_agent2, interval_agent2]
}

function makefloordirty() {
floorNumber = Math.floor(Math.random() * 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a local or a global?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made some mistakes while setting the scopes of the variable. I will correct it with other changes and be more careful in the future.

diagram_agent1.world.markFloorDirty(floorNumber);
diagram_agent1.floors[floorNumber].attr('class', 'dirty floor');
diagram_agent2.world.markFloorDirty(floorNumber);
diagram_agent2.floors[floorNumber].attr('class', 'dirty floor');
}
setInterval(makefloordirty,parameters[0]*1000);

//control agent1's state
update_agent1();
setInterval(update_agent1, STEP_TIME_MS);

//control agent2's state
function controlAgent2(){
clearInterval(agent2_interval);
setTimeout(function(){ agent2_interval = setInterval(update_agent2,1000); },5000);

}
controlAgent2();
setInterval(controlAgent2,5000+parameters[3]*1000) //parameter[3] defines the working interval of agent2

}

//Plotting the performance of the agents on a dynamic line chart
var label = [0,1,2,3];
var index = 3;
function plotPerformance(performanceAgent1, performanceAgent2){
var performance_agent1 = performanceAgent1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to put this array to make the y-axis of the chart more readable.

var performance_agent2 = performanceAgent2;
var ctx = document.getElementById('chartContainer').getContext('2d');
if(performance_agent1.length != 0 || performance_agent2.length != 0){
var chart = new Chart(ctx, {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no way to reuse the Chart object? The animations are very distracting!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to work on it as it was previously mentioned by you, but was unable to do so. I don't know if it is possible to do so.

type: 'line',

data: {
labels: label,
datasets: [{
label: "Performance Agent1",
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: performance_agent1,
fill: false,
},
{
label: "Performance Agent2",
backgroundColor: 'rgb(0, 99, 132)',
borderColor: 'rgb(0, 99, 132)',
data: performance_agent2,
fill: false,
}
]
},


options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
index++;
label.push(index);
}

}

makeAgentControlledDiagram();
makeReaderControlledDiagram();
makeTableControlledDiagram();
makePerformanceControlledDaigram();
5 changes: 3 additions & 2 deletions 2-Intelligent-Agents/cleaningRobot.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ class World {

// Rules are defined in code
function reflexVacuumAgent(world) {
if (world.floors[world.location].dirty) { return 'SUCK'; }
if (world.floors[world.location].dirty) { return 'SUCK'; }
else if (world.location == 0) { return 'RIGHT'; }
else if (world.location == 1) { return 'LEFT'; }
else if (world.location == 1) { return'LEFT'; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what you're trying to do with the change to this function

Copy link
Contributor Author

@Dragneel7 Dragneel7 Jan 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was a mistake I might have committed when I was working to implement the visualization.
I will correct this and all the above mentioned.
Thanks for the Review.

return action;
}

// Rules are defined in data, in a table indexed by [location][dirty]
Expand Down
93 changes: 85 additions & 8 deletions 2-Intelligent-Agents/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
<title>2 Intelligent Agents</title>
<link rel="stylesheet" href="../styles.css">
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.min.js"></script>
<script type="text/javascript" src="../main.js"></script>

<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
.floor:hover { cursor: pointer; }
Expand Down Expand Up @@ -64,7 +65,7 @@ <h2 id="rules-to-follow">Rules for the agent to follow</h2>
The robot will follow the rules you choose. Click on a rule in the table to change it.
</p>

<table class="agent-actions"
<table class="agent-actions">
<thead>
<tr>
<th rowspan="2" valign="bottom">Percept</th>
Expand Down Expand Up @@ -120,26 +121,102 @@ <h2 id="rules-to-follow">Rules for the agent to follow</h2>
obvious what set of rules to use. How would we find the
rules?
</p>
</div>

<div id="performance-controlled-diagram">

<h2 id="performance-measures">Performance measures</h2>

<p>
We can choose a metric that evaluates how well the agent
performs on the given problem.
</p>

TODO: dirty/clean should be controlled automatically,
reproducibly (seeded RNG), and then display a line chart
with the performance measure

<p>
This is a case study of 2 agents:-
<ul>
<li> Agent1 that cleans continously but is slow in learning the environment</li>
<li> Agent2 that takes less time to clean but cleans at regular intervals</li>
</ul>
</p>
<p>
The performance measure of the agents would be a sum total of scores evaluted from:-
<ul>
<li> The amount of time the agent is working( 10 points would be deducted from the total score for each move)</li>
<li> The cleaniness of the environment( 50 points would be awarded for for cleaning the environment and 5 points would be deducted for each time interval the environment remains dirty)</li>
</ul>
</p>
<p>
Following control the agent's performance in a given environment.
</p>
<table class="agent-actions">
<thead>
<tr>
<th colspan="7">Performance Factors</th>
</tr>
<tr>
<th data-input="dirt-freq">dirt-frequency</th>
<th data-input="speed-agent1">speed-agent1</th>
<th data-input="speed-agent2">speed-agent2</th>
<th data-input="interval-agent2">interval-agent2</th>
</tr>
<tr>
<td data-action="dirt-freq">
<select class="custom-select">
<option value= 8 selected>8</option>
<option value= 10>10</option>
<option value= 12>12</option>
<option value= 14>14</option>
</select>
</td>
<td data-action="speed-agent1">
<select class="custom-select">
<option value=3 selected>3</option>
<option value=4>4</option>
<option value=5>5</option>
<option value=6>6</option>
</select>
</td>
<td data-action="speed-agent2">
<select class="custom-select">
<option value=.5 selected>.5</option>
<option value=1>1</option>
<option value=1.5>1.5</option>
<option value=2>2</option>
</select>
</td>
<td data-action="interval-agent2">
<select class="custom-select">
<option value=10 selected>10</option>
<option value=15>15</option>
<option value=20>20</option>
<option value=25>25</option>
</select>
</td>
</tr>
</thead>
</table>

<div class="performance-agent-container" style="display: inline-flex;position: relative;right:100px; top:20px;">
<div id="performance-controlled-diagram-agent1" style="text-align: center;" >
<h4>Agent1</h4>
<svg width="400" height="300" viewBox="0 0 600 300"></svg>
</div>

<div id="performance-controlled-diagram-agent2" style="text-align: center;">
<h4>Agent2</h4>
<svg width="400" height="300" viewBox="0 0 600 300"></svg>
</div>
</div>
<h4>Agent's Performance Plot</h3>
<canvas id="chartContainer" style="height: 300px; width: 100%;"></canvas>

<h3>Evaluating multiple agents</h3>

TODO: many different agents on the same data sequence

<h3>Evaluating many data sets</h3>

TODO: one agent on many different data sequences (avoid overfitting)

</div>
</div>

Expand Down