Improving efficiency of using tables
Afficher commentaires plus anciens
A simple working example of my code is given below.
% Initialization
num = 10; time_limit = 10000;
agent = array2table(zeros(num,4),'VariableNames',{'loc','prev_loc','loc_time','collected'});
env = randi(10,10,10); env(1,1) = 0;
agent.loc = ones(num,1);
% Collect rewards one-by-one
agent.loc_time = ones(num,1);
tic
for t = 1:time_limit
for i = 1:num
% If agent i has reached a position at time t
if agent.loc_time(i) == t
% If there is a reward at agent's location
if env(agent.loc(i)) > 0
[agent(i,:),env] = return_with_reward(agent(i,:),env);
% Otherwise
else
[agent(i,:),env] = find_reward(agent(i,:),env);
end
end
end
end
toc
function [agent,env] = find_reward(agent,env)
agent.prev_loc = agent.loc;
% Select a location to go randomly
agent.loc = randi([2,length(env(:))],1);
% Find time to get there
agent.loc_time = agent.loc_time + abs(agent.loc - agent.prev_loc);
end
function [agent,env] = return_with_reward(agent,env)
loc = agent.loc;
% Update environment
env(loc) = max(0, env(loc) - 1);
agent.collected = agent.collected + 1;
agent.prev_loc = loc;
% Return to starting position
agent.loc = 1;
% Find time to reach
agent.loc_time = agent.loc_time + abs(agent.loc - agent.prev_loc);
end
In this, the agents start at position (1,1), go to random positions till they get a reward, return with that reward to (1,1), and go again. For 10 agents and 10k time steps, this takes about 2 seconds. I'm new to table-oriented programming, so I'm wondering if there are ways I can improve the efficiency of this process.
Réponses (1)
Hi Tejas,
We can optimize the code by improving the following key factors:
- Precomputing Random Locations: All random locations are generated before the loop, reducing runtime overhead.
- Vectorized Logical Indexing: Agents are processed in batches using logical indexing, which is faster than iterative loops.
- Batch Updating: Agents that found a reward and those that did not are updated in separate batches, leveraging MATLAB's efficient handling of array operations.
- Direct Assignment: The starting position for agents returning with a reward is assigned in one operation, rather than in a loop.
The optimized MATLAB code is as follows:
% Initialization
num = 10; time_limit = 10000;
agent = array2table(zeros(num,4),'VariableNames',{'loc','prev_loc','loc_time','collected'});
env = randi(10,10,10); env(1,1) = 0;
agent.loc = ones(num,1);
% Collect rewards one-by-one
agent.loc_time = ones(num,1);
tic
% Precompute random locations
random_locs = randi([2, numel(env)], num, time_limit);
for t = 1:time_limit
% Find agents that have reached their position at time t
active_agents_idx = find(agent.loc_time == t);
% Check for rewards at the agents' locations
rewards_available = env(agent.loc(active_agents_idx)) > 0;
% Update agents that found a reward
agents_with_reward_idx = active_agents_idx(rewards_available);
% Update agents that did not find a reward
agents_without_reward_idx = active_agents_idx(~rewards_available);
if ~isempty(agents_with_reward_idx)
[agent(agents_with_reward_idx,:), env] = return_with_reward(agent(agents_with_reward_idx,:), env);
end
if ~isempty(agents_without_reward_idx)
[agent(agents_without_reward_idx,:), env] = find_reward(agent(agents_without_reward_idx,:), env, random_locs(agents_without_reward_idx, t));
end
end
toc
function [agent,env] = find_reward(agent,env, random_locs)
agent.prev_loc = agent.loc;
% Use precomputed random locations
agent.loc = random_locs;
% Find time to get there
agent.loc_time = agent.loc_time + abs(agent.loc - agent.prev_loc);
end
function [agent,env] = return_with_reward(agent,env)
locs = agent.loc;
% Vectorized update to environment and agent properties
for loc = locs'
env(loc) = max(0, env(loc) - 1);
end
agent.collected = agent.collected + 1;
agent.prev_loc = locs;
% Return to starting position
agent.loc = ones(size(agent.loc)); % Assign an array of ones
% Find time to reach
agent.loc_time = agent.loc_time + abs(agent.loc - agent.prev_loc);
end
The optimized code runs 5 times faster than the original code by using the above methods.
You may refer to the following documentation links to have a better understanding on vectorization and precomputing arrays:
- https://www.mathworks.com/help/matlab/matlab_prog/preallocating-arrays.html
- https://www.mathworks.com/help/matlab/matlab_prog/vectorization.html
Catégories
En savoir plus sur Environments dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!