<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Puzzler:  Difficult algorithm development challenge</title>
	<atom:link href="http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/</link>
	<description>Doug Hull is a proud MathWorker who is on a mission to help you with MATLAB.</description>
	<lastBuildDate>Fri, 10 Feb 2012 20:31:50 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
	<item>
		<title>By: dhull</title>
		<link>http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1287</link>
		<dc:creator>dhull</dc:creator>
		<pubDate>Thu, 08 Jan 2009 15:21:02 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1287</guid>
		<description>Dav,

I am sorry, I do not understand your question.  Please show more details of code you have tried and where it is not working.

thanks,
Doug</description>
		<content:encoded><![CDATA[<p>Dav,</p>
<p>I am sorry, I do not understand your question.  Please show more details of code you have tried and where it is not working.</p>
<p>thanks,<br />
Doug</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: D</title>
		<link>http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1286</link>
		<dc:creator>D</dc:creator>
		<pubDate>Thu, 08 Jan 2009 09:26:22 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1286</guid>
		<description>Hi all,
I am a biologist working on a project where the location of the trees are already known on a plot. 
I have to set some  boxes of 25 by 4 randomly on this plot. 
Then find which trees have fallen in the box.
Seems I can easily do it using Matlab but am new and Alien to theis malab wrold. 
Grateful if someone can help or guide me please 
Thx
Dav</description>
		<content:encoded><![CDATA[<p>Hi all,<br />
I am a biologist working on a project where the location of the trees are already known on a plot.<br />
I have to set some  boxes of 25 by 4 randomly on this plot.<br />
Then find which trees have fallen in the box.<br />
Seems I can easily do it using Matlab but am new and Alien to theis malab wrold.<br />
Grateful if someone can help or guide me please<br />
Thx<br />
Dav</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Pepelio</title>
		<link>http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1018</link>
		<dc:creator>Pepelio</dc:creator>
		<pubDate>Tue, 01 Jul 2008 01:26:13 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1018</guid>
		<description>Doug, thanks for this interesting problem. However, the proposed solution is wrong. I can think of at least one tree configuration (not a boundary condition) that will make the algorithm fail. In the sense that it will not find the largest rectangle.

Do you want me to tell you or do you like me to keep this as an added problem to solve?

I think that if you try to prove in a rigorous way that your algorithm always finds the largest rectangle you will probably realize that it doesn&#039;t.</description>
		<content:encoded><![CDATA[<p>Doug, thanks for this interesting problem. However, the proposed solution is wrong. I can think of at least one tree configuration (not a boundary condition) that will make the algorithm fail. In the sense that it will not find the largest rectangle.</p>
<p>Do you want me to tell you or do you like me to keep this as an added problem to solve?</p>
<p>I think that if you try to prove in a rigorous way that your algorithm always finds the largest rectangle you will probably realize that it doesn&#8217;t.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Timur</title>
		<link>http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1017</link>
		<dc:creator>Timur</dc:creator>
		<pubDate>Wed, 18 Jun 2008 19:20:01 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1017</guid>
		<description>&lt;pre&gt;&lt;code&gt;
function [bigArea, boundBox] = main(trees)

boundBox      = findBoundBox(trees.x, trees.y);
includedTrees = findIncludedTrees(boundBox, trees);
areaList      = findArea(boundBox, boundBox, includedTrees, trees, trees);

% find biggest area
[v,i] = max([areaList(:).width] .* [areaList(:).height]);
numel(areaList);
bigArea = areaList(i);

function boundBox = findBoundBox(x,y)

boundBox.trees = [];

[left index] = min(x);
boundBox.trees = [boundBox.trees index];
[right index] = max(x);
boundBox.trees = [boundBox.trees index];
[bottom index] = min(y);
boundBox.trees = [boundBox.trees index];
[top index] = max(y);
boundBox.trees = [boundBox.trees index];

boundBox.x = left;
boundBox.y = bottom;
boundBox.width  = right - left;
boundBox.height = top - bottom;
boundBox.trees = unique(boundBox.trees);

function includedTrees = findIncludedTrees(boundBox, trees)
goodX = (trees.x &gt; boundBox.x                  ) &amp; ...
        (trees.x &lt; boundBox.x + boundBox.width );

goodY = (trees.y &gt; boundBox.y                  ) &amp; ...
        (trees.y &lt; boundBox.y + boundBox.height);

goodIndex = goodX &amp; goodY;

includedTrees.x = trees.x(goodIndex);
includedTrees.y = trees.y(goodIndex);

function areaList = findArea(boundBox, newBoundBox, includedTrees, trees, newTrees)

areaList = [];

if isempty(includedTrees.x) %No obstructions
    areaList = newBoundBox; %send back the boundingbox
    return
end

if numel(newTrees.x) &gt; 2
    for i = newBoundBox.trees
        newerTrees            = newTrees;
        newerTrees.x(i)       = [];
        newerTrees.y(i)       = [];

        newBoundBox             = findBoundBox(newerTrees.x, newerTrees.y);
        newIncludedTrees        = findIncludedTrees(newBoundBox, trees);
        newAreaListItems        = findArea(boundBox, newBoundBox, newIncludedTrees, trees, newerTrees);
        areaList                = [areaList newAreaListItems];

        if boundBox.x ~= newBoundBox.x
            newBoundBoxXP           = newBoundBox;
            newBoundBoxXP.x         = boundBox.x;
            newBoundBoxXP.width     = newBoundBox.width + (newBoundBox.x - boundBox.x);

            newIncludedTrees        = findIncludedTrees(newBoundBoxXP, trees);
            newAreaListItems        = findArea(boundBox, newBoundBoxXP, newIncludedTrees, trees, newerTrees);
            areaList                = [areaList newAreaListItems];
        end

        if boundBox.x ~= newBoundBox.x &amp;&amp; boundBox.width + boundBox.x ~= newBoundBox.width + newBoundBox.x
            newBoundBoxXP           = newBoundBox;
            newBoundBoxXP.x         = boundBox.x;
            newBoundBoxXP.width     = boundBox.width;

            newIncludedTrees        = findIncludedTrees(newBoundBoxXP, trees);
            newAreaListItems        = findArea(boundBox, newBoundBoxXP, newIncludedTrees, trees, newerTrees);
            areaList                = [areaList newAreaListItems];
        end

        if boundBox.y ~= newBoundBox.y
            newBoundBoxXP           = newBoundBox;
            newBoundBoxXP.y         = boundBox.y;
            newBoundBoxXP.height    = newBoundBox.height + (newBoundBox.y - boundBox.y);
            newIncludedTrees        = findIncludedTrees(newBoundBoxXP, trees);
            newAreaListItems        = findArea(boundBox, newBoundBoxXP, newIncludedTrees, trees, newerTrees);
            areaList                = [areaList newAreaListItems];
        end

        if boundBox.y ~= newBoundBox.y &amp;&amp; boundBox.height + boundBox.y ~= newBoundBox.height + newBoundBox.y
            newBoundBoxXP           = newBoundBox;
            newBoundBoxXP.y         = boundBox.y;
            newBoundBoxXP.height     = boundBox.height;

            newIncludedTrees        = findIncludedTrees(newBoundBoxXP, trees);
            newAreaListItems        = findArea(boundBox, newBoundBoxXP, newIncludedTrees, trees, newerTrees);
            areaList                = [areaList newAreaListItems];
        end

        if boundBox.x + boundBox.width  ~= newBoundBox.x + newBoundBox.width
            newBoundBoxXP           = newBoundBox;
            newBoundBoxXP.width     = (boundBox.width + boundBox.x) - newBoundBox.x;
            newIncludedTrees        = findIncludedTrees(newBoundBoxXP, trees);
            newAreaListItems        = findArea(boundBox, newBoundBoxXP, newIncludedTrees, trees, newerTrees);
            areaList                = [areaList newAreaListItems];
        end

        if boundBox.y + boundBox.height  ~= newBoundBox.y + newBoundBox.height
            newBoundBoxXP           = newBoundBox;
            newBoundBoxXP.height    = (boundBox.height + boundBox.y) - newBoundBox.y;
            newIncludedTrees        = findIncludedTrees(newBoundBoxXP, trees);
            newAreaListItems        = findArea(boundBox, newBoundBoxXP, newIncludedTrees, trees, newerTrees);
            areaList                = [areaList newAreaListItems];
        end

    end
end


&lt;/pre&gt;&lt;/code&gt;</description>
		<content:encoded><![CDATA[<pre><code>
function [bigArea, boundBox] = main(trees)

boundBox      = findBoundBox(trees.x, trees.y);
includedTrees = findIncludedTrees(boundBox, trees);
areaList      = findArea(boundBox, boundBox, includedTrees, trees, trees);

% find biggest area
[v,i] = max([areaList(:).width] .* [areaList(:).height]);
numel(areaList);
bigArea = areaList(i);

function boundBox = findBoundBox(x,y)

boundBox.trees = [];

[left index] = min(x);
boundBox.trees = [boundBox.trees index];
[right index] = max(x);
boundBox.trees = [boundBox.trees index];
[bottom index] = min(y);
boundBox.trees = [boundBox.trees index];
[top index] = max(y);
boundBox.trees = [boundBox.trees index];

boundBox.x = left;
boundBox.y = bottom;
boundBox.width  = right - left;
boundBox.height = top - bottom;
boundBox.trees = unique(boundBox.trees);

function includedTrees = findIncludedTrees(boundBox, trees)
goodX = (trees.x > boundBox.x                  ) &#038; ...
        (trees.x < boundBox.x + boundBox.width );

goodY = (trees.y > boundBox.y                  ) &#038; ...
        (trees.y < boundBox.y + boundBox.height);

goodIndex = goodX & goodY;

includedTrees.x = trees.x(goodIndex);
includedTrees.y = trees.y(goodIndex);

function areaList = findArea(boundBox, newBoundBox, includedTrees, trees, newTrees)

areaList = [];

if isempty(includedTrees.x) %No obstructions
    areaList = newBoundBox; %send back the boundingbox
    return
end

if numel(newTrees.x) &gt; 2
    for i = newBoundBox.trees
        newerTrees            = newTrees;
        newerTrees.x(i)       = [];
        newerTrees.y(i)       = [];

        newBoundBox             = findBoundBox(newerTrees.x, newerTrees.y);
        newIncludedTrees        = findIncludedTrees(newBoundBox, trees);
        newAreaListItems        = findArea(boundBox, newBoundBox, newIncludedTrees, trees, newerTrees);
        areaList                = [areaList newAreaListItems];

        if boundBox.x ~= newBoundBox.x
            newBoundBoxXP           = newBoundBox;
            newBoundBoxXP.x         = boundBox.x;
            newBoundBoxXP.width     = newBoundBox.width + (newBoundBox.x - boundBox.x);

            newIncludedTrees        = findIncludedTrees(newBoundBoxXP, trees);
            newAreaListItems        = findArea(boundBox, newBoundBoxXP, newIncludedTrees, trees, newerTrees);
            areaList                = [areaList newAreaListItems];
        end

        if boundBox.x ~= newBoundBox.x &amp;&amp; boundBox.width + boundBox.x ~= newBoundBox.width + newBoundBox.x
            newBoundBoxXP           = newBoundBox;
            newBoundBoxXP.x         = boundBox.x;
            newBoundBoxXP.width     = boundBox.width;

            newIncludedTrees        = findIncludedTrees(newBoundBoxXP, trees);
            newAreaListItems        = findArea(boundBox, newBoundBoxXP, newIncludedTrees, trees, newerTrees);
            areaList                = [areaList newAreaListItems];
        end

        if boundBox.y ~= newBoundBox.y
            newBoundBoxXP           = newBoundBox;
            newBoundBoxXP.y         = boundBox.y;
            newBoundBoxXP.height    = newBoundBox.height + (newBoundBox.y - boundBox.y);
            newIncludedTrees        = findIncludedTrees(newBoundBoxXP, trees);
            newAreaListItems        = findArea(boundBox, newBoundBoxXP, newIncludedTrees, trees, newerTrees);
            areaList                = [areaList newAreaListItems];
        end

        if boundBox.y ~= newBoundBox.y &amp;&amp; boundBox.height + boundBox.y ~= newBoundBox.height + newBoundBox.y
            newBoundBoxXP           = newBoundBox;
            newBoundBoxXP.y         = boundBox.y;
            newBoundBoxXP.height     = boundBox.height;

            newIncludedTrees        = findIncludedTrees(newBoundBoxXP, trees);
            newAreaListItems        = findArea(boundBox, newBoundBoxXP, newIncludedTrees, trees, newerTrees);
            areaList                = [areaList newAreaListItems];
        end

        if boundBox.x + boundBox.width  ~= newBoundBox.x + newBoundBox.width
            newBoundBoxXP           = newBoundBox;
            newBoundBoxXP.width     = (boundBox.width + boundBox.x) - newBoundBox.x;
            newIncludedTrees        = findIncludedTrees(newBoundBoxXP, trees);
            newAreaListItems        = findArea(boundBox, newBoundBoxXP, newIncludedTrees, trees, newerTrees);
            areaList                = [areaList newAreaListItems];
        end

        if boundBox.y + boundBox.height  ~= newBoundBox.y + newBoundBox.height
            newBoundBoxXP           = newBoundBox;
            newBoundBoxXP.height    = (boundBox.height + boundBox.y) - newBoundBox.y;
            newIncludedTrees        = findIncludedTrees(newBoundBoxXP, trees);
            newAreaListItems        = findArea(boundBox, newBoundBoxXP, newIncludedTrees, trees, newerTrees);
            areaList                = [areaList newAreaListItems];
        end

    end
end
</pre>
<p></p></code>
</pre>]]></content:encoded>
	</item>
	<item>
		<title>By: Doug</title>
		<link>http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1016</link>
		<dc:creator>Doug</dc:creator>
		<pubDate>Tue, 17 Jun 2008 18:31:01 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1016</guid>
		<description>Joel,

I tried the above code.  It does not work for me.  I looks to me like the logic test:

&lt;pre&gt;&lt;code&gt;
% Eliminate boxes which contain points
for i = 1:length(box_i)
	points_outside = (tree.x=box_right(box_i(i)) &#124;...
                     tree.y=box_top(box_i(i)));
    if all(points_outside)
        break % Found a good one
    end
end
&lt;/code&gt;&lt;/pre&gt;

Is implemented incorrectly.  You are only checking for top and right, but not bottom and left.  Also, the single equals sign is an assignment, I think you wanted a greater than.  Once I added the other checks, I found that this finds a valid rectangle, but never the best one.  I think the reason for that is the &quot;indexing into something that indexes into something else&quot; is done incorrectly.

I think these changes can be fixed, but a simpler scheme might make it easier to avoid such errors.

-Doug</description>
		<content:encoded><![CDATA[<p>Joel,</p>
<p>I tried the above code.  It does not work for me.  I looks to me like the logic test:</p>
<pre><code>
% Eliminate boxes which contain points
for i = 1:length(box_i)
	points_outside = (tree.x=box_right(box_i(i)) |...
                     tree.y=box_top(box_i(i)));
    if all(points_outside)
        break % Found a good one
    end
end
</code></pre>
<p>Is implemented incorrectly.  You are only checking for top and right, but not bottom and left.  Also, the single equals sign is an assignment, I think you wanted a greater than.  Once I added the other checks, I found that this finds a valid rectangle, but never the best one.  I think the reason for that is the &#8220;indexing into something that indexes into something else&#8221; is done incorrectly.</p>
<p>I think these changes can be fixed, but a simpler scheme might make it easier to avoid such errors.</p>
<p>-Doug</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Joel</title>
		<link>http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1015</link>
		<dc:creator>Joel</dc:creator>
		<pubDate>Tue, 17 Jun 2008 16:55:27 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1015</guid>
		<description>&lt;pre&gt;&lt;code&gt;
% Create Trees
num_trees = 10;
width = 40;
height = 30;
tree.x = rand(num_trees,1)*width;
tree.y = rand(num_trees,1)*height;

% Big bounding box
bounding = [min(tree.x),...
            min(tree.y),...
            max(tree.x)-min(tree.x),...
            max(tree.y)-min(tree.y)];

% Brute force combination search
pairs = combnk(1:num_trees,2);
combinations = combnk(1:size(pairs,1),2);

% All combinations
box_left = min(tree.x(pairs(combinations(:,1),1)),tree.x(pairs(combinations(:,1),2)));
box_right = max(tree.x(pairs(combinations(:,1),1)),tree.x(pairs(combinations(:,1),2)));
box_bottom = min(tree.y(pairs(combinations(:,2),1)),tree.y(pairs(combinations(:,2),2)));
box_top = max(tree.y(pairs(combinations(:,2),1)),tree.y(pairs(combinations(:,2),2)));
box_widths = box_right-box_left;
box_heights = box_top-box_bottom;
box_areas = box_widths.*box_heights;

% Sort the results
[box_areas box_i] = sort(box_areas,&#039;descend&#039;);

% Eliminate boxes which contain points
for i = 1:length(box_i)
	points_outside = (tree.x=box_right(box_i(i)) &#124;...
                     tree.y=box_top(box_i(i)));
    if all(points_outside)
        break % Found a good one
    end
end
biggest_box = [box_left(box_i(i)),...
               box_bottom(box_i(i)),...
               box_widths(box_i(i)),...
               box_heights(box_i(i))];

% Display the results
figure
scatter(tree.x,tree.y,&#039;o&#039;)
rectangle(&#039;Position&#039;,bounding)
rectangle(&#039;Position&#039;,biggest_box,&#039;EdgeColor&#039;,&#039;red&#039;)
&lt;/code&gt;&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<pre><code>
% Create Trees
num_trees = 10;
width = 40;
height = 30;
tree.x = rand(num_trees,1)*width;
tree.y = rand(num_trees,1)*height;

% Big bounding box
bounding = [min(tree.x),...
            min(tree.y),...
            max(tree.x)-min(tree.x),...
            max(tree.y)-min(tree.y)];

% Brute force combination search
pairs = combnk(1:num_trees,2);
combinations = combnk(1:size(pairs,1),2);

% All combinations
box_left = min(tree.x(pairs(combinations(:,1),1)),tree.x(pairs(combinations(:,1),2)));
box_right = max(tree.x(pairs(combinations(:,1),1)),tree.x(pairs(combinations(:,1),2)));
box_bottom = min(tree.y(pairs(combinations(:,2),1)),tree.y(pairs(combinations(:,2),2)));
box_top = max(tree.y(pairs(combinations(:,2),1)),tree.y(pairs(combinations(:,2),2)));
box_widths = box_right-box_left;
box_heights = box_top-box_bottom;
box_areas = box_widths.*box_heights;

% Sort the results
[box_areas box_i] = sort(box_areas,'descend');

% Eliminate boxes which contain points
for i = 1:length(box_i)
	points_outside = (tree.x=box_right(box_i(i)) |...
                     tree.y=box_top(box_i(i)));
    if all(points_outside)
        break % Found a good one
    end
end
biggest_box = [box_left(box_i(i)),...
               box_bottom(box_i(i)),...
               box_widths(box_i(i)),...
               box_heights(box_i(i))];

% Display the results
figure
scatter(tree.x,tree.y,'o')
rectangle('Position',bounding)
rectangle('Position',biggest_box,'EdgeColor','red')
</code></pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Doug</title>
		<link>http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1014</link>
		<dc:creator>Doug</dc:creator>
		<pubDate>Tue, 17 Jun 2008 13:56:14 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1014</guid>
		<description>Daniel,

Yes, I had an inkling of the same conclusion, but did not pursue it.  My original outline on paper proposed something like that, but I wanted to keep it simple.  I often find that I will compromise: taking simplicity over efficiency and then continue to optimize from there.  Since this algorithm works, I stopped.  If the inefficiency started to matter, that would be the lowest hanging fruit to go after.

What I like about MATLAB is that it is pretty easy to prototype ideas. I can afford to throw this together, see how it works and then iterate on my code because it is fast to program.

-Thanks,
Doug</description>
		<content:encoded><![CDATA[<p>Daniel,</p>
<p>Yes, I had an inkling of the same conclusion, but did not pursue it.  My original outline on paper proposed something like that, but I wanted to keep it simple.  I often find that I will compromise: taking simplicity over efficiency and then continue to optimize from there.  Since this algorithm works, I stopped.  If the inefficiency started to matter, that would be the lowest hanging fruit to go after.</p>
<p>What I like about MATLAB is that it is pretty easy to prototype ideas. I can afford to throw this together, see how it works and then iterate on my code because it is fast to program.</p>
<p>-Thanks,<br />
Doug</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daniel Armyr</title>
		<link>http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1013</link>
		<dc:creator>Daniel Armyr</dc:creator>
		<pubDate>Tue, 17 Jun 2008 09:48:56 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1013</guid>
		<description>Hi.
Unfortunately, this problem is a bit on the lengthy side for me to give a go at during office hours, but I realized somthing when I was thinking through how I would solve it and while watching the solution.

The proposed algorithm will find the largest area twice using the scenario from the video. Had there been three trees inside the bounding box that enclosed the largesty area I  believe it would be found 3 times. This sounds somewhat inefficient. Could one device a check inside the algoritm that stops once the largest area is found the first time?

A little white-board scetching tells me that once you start subdividing around the second tree, if an area contains the first tree than you can immediately stop because if there is an interesting area there, then it has allready been found. This should trivially extend to N trees.

Anyone have a comment on my reasoning here?

--DA</description>
		<content:encoded><![CDATA[<p>Hi.<br />
Unfortunately, this problem is a bit on the lengthy side for me to give a go at during office hours, but I realized somthing when I was thinking through how I would solve it and while watching the solution.</p>
<p>The proposed algorithm will find the largest area twice using the scenario from the video. Had there been three trees inside the bounding box that enclosed the largesty area I  believe it would be found 3 times. This sounds somewhat inefficient. Could one device a check inside the algoritm that stops once the largest area is found the first time?</p>
<p>A little white-board scetching tells me that once you start subdividing around the second tree, if an area contains the first tree than you can immediately stop because if there is an interesting area there, then it has allready been found. This should trivially extend to N trees.</p>
<p>Anyone have a comment on my reasoning here?</p>
<p>&#8211;DA</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: ArthurG</title>
		<link>http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1012</link>
		<dc:creator>ArthurG</dc:creator>
		<pubDate>Mon, 16 Jun 2008 16:23:56 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1012</guid>
		<description>Here&#039;s the formatted code.
&lt;pre&gt;&lt;code&gt;
function [bigArea, boundBox] = main(trees)
% find largest field; short but uses O(n^4) memory
%% find bigArea
[bigArea, boundBox] = deal(struct(&#039;x&#039;,[],&#039;y&#039;,[],&#039;width&#039;,[],&#039;height&#039;,[]));
boundBox.x = min(trees.x);
boundBox.y = min(trees.y);
boundBox.width = max(trees.x) - boundBox.x;
boundBox.height = max(trees.y) - boundBox.y;
%% find area of every possible field
% Consider every possible combination of X and Y coordinates
n = numel(trees.x);
% Construct an [n x n] array of all possible field widths
delX = bsxfun(@minus, trees.x, shiftdim(trees.x, -1));
% Construct an [n x n] array of all possible field heights
delY = bsxfun(@minus, trees.y, shiftdim(trees.y, -1));
% Construct an [n x n x n x n] array of all possible field areas
area = bsxfun(@times, delX, shiftdim(delY, -2));
% Sort the areas, largest to smallest
[areaSort, iSort] = sort(area(:), &#039;descend&#039;);
% Look for the largest area that contains no trees
for i=iSort&#039;
    % Convert the sorted index to subscripts
    % (subscripts correspond to indices in tree.x and tree.y)
    [x1,x2,y1,y2] = ind2sub([n,n,n,n], i);
    if ~any(trees.x &gt; min(trees.x([x1 x2])) &amp; ...
            trees.x &lt; max(trees.x([x1 x2])) &amp; ...
            trees.y &gt; min(trees.y([y1 y2])) &amp; ...
            trees.y &lt; max(trees.y([y1 y2])) )
        break % this area has no trees
    end
end
%% Record results
bigArea.x = min(trees.x([x1 x2]));
bigArea.y = min(trees.y([y1 y2]));
bigArea.width = abs(diff(trees.x([x1 x2])));
bigArea.height = abs(diff(trees.y([y1 y2])));
end % function main

&lt;/code&gt;&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Here&#8217;s the formatted code.</p>
<pre><code>
function [bigArea, boundBox] = main(trees)
% find largest field; short but uses O(n^4) memory
%% find bigArea
[bigArea, boundBox] = deal(struct('x',[],'y',[],'width',[],'height',[]));
boundBox.x = min(trees.x);
boundBox.y = min(trees.y);
boundBox.width = max(trees.x) - boundBox.x;
boundBox.height = max(trees.y) - boundBox.y;
%% find area of every possible field
% Consider every possible combination of X and Y coordinates
n = numel(trees.x);
% Construct an [n x n] array of all possible field widths
delX = bsxfun(@minus, trees.x, shiftdim(trees.x, -1));
% Construct an [n x n] array of all possible field heights
delY = bsxfun(@minus, trees.y, shiftdim(trees.y, -1));
% Construct an [n x n x n x n] array of all possible field areas
area = bsxfun(@times, delX, shiftdim(delY, -2));
% Sort the areas, largest to smallest
[areaSort, iSort] = sort(area(:), 'descend');
% Look for the largest area that contains no trees
for i=iSort'
    % Convert the sorted index to subscripts
    % (subscripts correspond to indices in tree.x and tree.y)
    [x1,x2,y1,y2] = ind2sub([n,n,n,n], i);
    if ~any(trees.x > min(trees.x([x1 x2])) &#038; ...
            trees.x < max(trees.x([x1 x2])) &#038; ...
            trees.y > min(trees.y([y1 y2])) &#038; ...
            trees.y < max(trees.y([y1 y2])) )
        break % this area has no trees
    end
end
%% Record results
bigArea.x = min(trees.x([x1 x2]));
bigArea.y = min(trees.y([y1 y2]));
bigArea.width = abs(diff(trees.x([x1 x2])));
bigArea.height = abs(diff(trees.y([y1 y2])));
end % function main

</code></code></pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Doug</title>
		<link>http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1011</link>
		<dc:creator>Doug</dc:creator>
		<pubDate>Mon, 16 Jun 2008 14:00:57 +0000</pubDate>
		<guid isPermaLink="false">http://blogs.mathworks.com/videos/2008/06/16/puzzler-difficult-algorithm-development-challenge/#comment-1011</guid>
		<description>&lt;pre&gt;&lt;code&gt;
function [bigArea, boundBox] = main(trees)

boundBox      = findBoundBox(trees.x, trees.y);
includedTrees = findIncludedTrees(boundBox, trees);
areaList      = findArea(boundBox, includedTrees);

% find biggest area
[v,i] = max([areaList(:).width] .* [areaList(:).height]);
numel(areaList)
bigArea = areaList(i);

function boundBox = findBoundBox(x,y)

left   = min(x);
right  = max(x);
bottom = min(y);
top    = max(y);

boundBox.x = left;
boundBox.y = bottom;
boundBox.width  = right - left;
boundBox.height =   top - bottom;

function includedTrees = findIncludedTrees(boundBox, trees)

goodX = (trees.x &gt; boundBox.x                  ) &amp; ...
        (trees.x &lt; boundBox.x + boundBox.width );

goodY = (trees.y &gt; boundBox.y                  ) &amp; ...
        (trees.y &lt; boundBox.y + boundBox.height);

goodIndex = goodX &amp; goodY;

includedTrees.x = trees.x(goodIndex);
includedTrees.y = trees.y(goodIndex);

function areaList = findArea(boundBox, includedTrees)

areaList = [];

if isempty(includedTrees.x) %No obstructions
    areaList = boundBox; %send back the boundingbox
    return
end

% Must be an obscuring tree
for i = 1 : numel(includedTrees.x) %for each tree, break into four parts

    subAreas = findSubAreas(boundBox, includedTrees.x(i), includedTrees.y(i));

    for j = 1 : 4 %loop through each of the four areas as a smaller problem
        subAreaIncludedTrees = findIncludedTrees(subAreas(j), includedTrees);
        newAreaListItems     = findArea(subAreas(j), subAreaIncludedTrees);
        areaList             = [areaList newAreaListItems];
    end
end

function subAreas = findSubAreas(boundBox, treeX, treeY)

    subAreas(1)        = boundBox; %left
    subAreas(1).width  = treeX - boundBox.x;
    %no change.x

    subAreas(2)        = boundBox; %right
    subAreas(2).width  = boundBox.x + boundBox.width - treeX;
    subAreas(2).x      = treeX;

    subAreas(3)        = boundBox; %top
    subAreas(3).height = boundBox.y + boundBox.height - treeY;
    subAreas(3).y      = treeY;

    %no change.y
    subAreas(4)        = boundBox; %bottom
    subAreas(4).height = treeY - boundBox.y;
&lt;/code&gt;&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<pre><code>
function [bigArea, boundBox] = main(trees)

boundBox      = findBoundBox(trees.x, trees.y);
includedTrees = findIncludedTrees(boundBox, trees);
areaList      = findArea(boundBox, includedTrees);

% find biggest area
[v,i] = max([areaList(:).width] .* [areaList(:).height]);
numel(areaList)
bigArea = areaList(i);

function boundBox = findBoundBox(x,y)

left   = min(x);
right  = max(x);
bottom = min(y);
top    = max(y);

boundBox.x = left;
boundBox.y = bottom;
boundBox.width  = right - left;
boundBox.height =   top - bottom;

function includedTrees = findIncludedTrees(boundBox, trees)

goodX = (trees.x > boundBox.x                  ) &#038; ...
        (trees.x < boundBox.x + boundBox.width );

goodY = (trees.y > boundBox.y                  ) &#038; ...
        (trees.y < boundBox.y + boundBox.height);

goodIndex = goodX & goodY;

includedTrees.x = trees.x(goodIndex);
includedTrees.y = trees.y(goodIndex);

function areaList = findArea(boundBox, includedTrees)

areaList = [];

if isempty(includedTrees.x) %No obstructions
    areaList = boundBox; %send back the boundingbox
    return
end

% Must be an obscuring tree
for i = 1 : numel(includedTrees.x) %for each tree, break into four parts

    subAreas = findSubAreas(boundBox, includedTrees.x(i), includedTrees.y(i));

    for j = 1 : 4 %loop through each of the four areas as a smaller problem
        subAreaIncludedTrees = findIncludedTrees(subAreas(j), includedTrees);
        newAreaListItems     = findArea(subAreas(j), subAreaIncludedTrees);
        areaList             = [areaList newAreaListItems];
    end
end

function subAreas = findSubAreas(boundBox, treeX, treeY)

    subAreas(1)        = boundBox; %left
    subAreas(1).width  = treeX - boundBox.x;
    %no change.x

    subAreas(2)        = boundBox; %right
    subAreas(2).width  = boundBox.x + boundBox.width - treeX;
    subAreas(2).x      = treeX;

    subAreas(3)        = boundBox; %top
    subAreas(3).height = boundBox.y + boundBox.height - treeY;
    subAreas(3).y      = treeY;

    %no change.y
    subAreas(4)        = boundBox; %bottom
    subAreas(4).height = treeY - boundBox.y;
</code></code></pre>
]]></content:encoded>
	</item>
</channel>
</rss>

