Finish 2010-05-05 12:00:00 UTC

Pori a71

by Abhisek Ukil

Status: Passed
Results: 14080260 (cyc: 23, node: 3537)
CPU Time: 77.109
Score: 28199.4
Submitted at: 2010-05-02 12:11:04 UTC
Scored at: 2010-05-02 12:12:34 UTC

Current Rank: 2156th (Highest: 1st )
Basis for: Out for a Bit (diff)
Basis for: Solvers Engage (diff)
Basis for: PoriCat1 (diff)
...and 2 others.

Comments
Alan Chalker
10 May 2010
This entry was submitted during the Daylight phase and was eligible for the Sunday Push prize
Alan Chalker
11 May 2010
This was the 118th entry to take the overall contest scoring lead. It improved upon entry #1842 by 0.002% (0.6 points). It stayed in the lead for 7 mins, 34 secs before being replaced by entry #1849.
Alan Chalker
11 May 2010
This entry gets a result of 19652659 on the test suite (5572399 more than the contest suite). It has a ranking of 2135 compared to all other entries run against the test suite according to the data set provided by Jan Keller.
Please login or create a profile.
Code
function aA = solver_top2(s,L)
e=round(s^2/L);
if (e>=8 && e<=25) || (e>=100) || (e>=39 && e<=46) || (e>=59 && e<66)
    aA = solver1(s,L);
else
    aA = IiI(s,L);
end
end

function aA = IiI(imageSize, queryLimit)

SplitThresh = [10 240]; % hesitate to scan the region known to be black or white
% as the other solver


llll = queryLimit;
iIlIdx = ones(imageSize, 'uint32');
iIlDims = zeros(4, llll, 'single');
iIlSize = zeros(llll, 1, 'single');
iIlSum = zeros(llll, 1, 'single');
iIlMean = zeros(llll, 1, 'single');
aA = zeros(imageSize, 'single');
M = false(imageSize);
nnr = 0;
lllli = ceil(imageSize / floor(sqrt(queryLimit/4.05)));
for x = 1:lllli:imageSize
    X = x:min(x+lllli-1, imageSize);
    for y = 1:lllli:imageSize
        Y = y:min(y+lllli-1, imageSize);
        M = false(imageSize);
        M(Y,X) = true;
        nnr = nnr + 1;
        iIlSum(nnr) = queryImage(M);
        iIlDims(:,nnr) = [Y([1 end])'; X([1 end])'];
        iIlSize(nnr) = numel(Y) * numel(X);
        m = iIlSum(nnr) / iIlSize(nnr);
        iIlMean(nnr) = m;
        aA(Y,X) = m;
        iIlIdx(Y,X) = nnr;
        queryLimit = queryLimit - 1;
    end
end
dy = abs(diff(aA, 1, 1));
dy = [dy(1,:); max(dy(1:end-1,:), dy(2:end,:)); dy(end,:)];
dx = abs(diff(aA, 1, 2));
dx = [dx(:,1) max(dx(:,1:end-1), dx(:,2:end)) dx(:,end)];
D = [accumarray(iIlIdx(:), dx(:), [nnr 1], @max) accumarray(iIlIdx(:), dy(:), [nnr 1], @max)];
d = 1;


a=iIlDims(1,1:nnr)==iIlDims(2,1:nnr);
D(a,2)=300;
a=iIlDims(3,1:nnr)==iIlDims(4,1:nnr);
D(a,1)=300;

while queryLimit
    D_ = D;
    D_(D_==300) = -1;
    D_ = D_ .* iIlSize(1:nnr,[1 1]);
    % Choose the iIl
    D__=D_;
    D__(iIlMean(1:nnr)<=SplitThresh(1)|iIlMean(1:nnr)>=SplitThresh(2),:)=-1;
    [ds ns] = sort(D__(:), 'descend');
    if ds(1)<=0
        [ds ns] = sort(D_(:), 'descend');
    end
    n=ns(1);
    vert = n > nnr;
    n = n - vert * nnr;
    dims = iIlDims(:,n);
    
    if vert
        % Divide vertically
        % Top
        Y = dims(1):dims(1)+floor((dims(2)-dims(1))/2);
        X = dims(3):dims(4);
        % Bottom
        Y1 = Y(end)+1:dims(2);
        X1 = X;
    else
        % Divide horizontally
        % Left
        Y = dims(1):dims(2);
        X = dims(3):dims(3)+floor((dims(4)-dims(3))/2);
        % Right
        Y1 = Y;
        X1 = X(end)+1:dims(4);
    end
    % Compute new block
    M = false(imageSize);
    M(Y,X) = true;
    nnr = nnr + 1;
    iIlSum(nnr) = queryImage(M);
    iIlDims(:,nnr) = [Y([1 end])'; X([1 end])'];
    iIlSize(nnr) = numel(Y) * numel(X);
    iIlIdx(Y,X) = nnr;
    iIlMean(nnr) = iIlSum(nnr)/iIlSize(nnr);
    % Update old block
    iIlSize(n) = iIlSize(n) - iIlSize(nnr);
    iIlSum(n) = iIlSum(n) - iIlSum(nnr);
    iIlDims(:,n) = [Y1([1 end])'; X1([1 end])'];
    iIlMean(n) = iIlSum(n)/iIlSize(n);
    % Update the image
    aA(Y,X) = iIlSum(nnr) / iIlSize(nnr);
    aA(Y1,X1) = iIlSum(n) / iIlSize(n);
    % Compute iIls' update scores
    Y = max(dims(1)-1, 1):min(dims(2)+1, imageSize);
    X = max(dims(3)-1, 1):min(dims(4)+1, imageSize);
    D_ = aA(Y,X);
    dy = abs(diff(D_, 1, 1));
    dy = [dy(1,:); max(dy(1:end-1,:), dy(2:end,:)); dy(end,:)];
    dx = abs(diff(D_, 1, 2));
    dx = [dx(:,1) max(dx(:,1:end-1), dx(:,2:end)) dx(:,end)];
    D_ = iIlIdx(Y,X);
    D_ = [accumarray(D_(:), dx(:), [nnr 1], @max) accumarray(D_(:), dy(:), [nnr 1], @max)];
    D([n nnr],:) = 0;
    if (vert || sum(D_(1:nnr))/length(D_(1:nnr))< (sum(D_(nnr+1:end))/length(D_(nnr+1:end)))*1.4)
        D([n nnr],vert+1) = 300;
    end
    
    for tt=[n nnr]
        if iIlDims(1,tt)==iIlDims(2,tt)
            D(tt,2)=300;
        end
        if iIlDims(3,tt)==iIlDims(4,tt)
            D(tt,1)=300;
        end
    end
    
    D = max(D, D_);
    queryLimit = queryLimit - 1;
end

u = 10;
if lllli > 9
    Areas = [iIlSum zeros(nnr,2) iIlDims'];
    aA = kippen(aA,nnr,Areas);
    u = 8;
end

h = [0.2 0.65 0.20];
for a = 1:u
    aA = conv2(h', h, aA([1 1:end end],[1 1:end end]), 'valid');
    add = (iIlSum(1:nnr) - accumarray(iIlIdx(:), aA(:), [nnr 1])) ./ iIlSize(1:nnr);
    aA = min(max(aA + add(iIlIdx), 0), 255);
end
aA = double(aA);
iIlSum = double(iIlSum);
iIlSize = double(iIlSize);
%aA = bilateralFilter(aA, 7, 15);
lI1=3; sigmaRange=17+(lllli-8.8)*0.5;

downsampledeeeeEE = floor( ( imageSize - 1 ) / lI1 ) + 7;
downsampledeeeeEe = floor( ( imageSize - 1 ) / lI1 ) + 7;
downsampledDepth = floor( 255 / sigmaRange ) + 7;
[ jj, ii ] = meshgrid( 0 : imageSize - 1, 0 : imageSize - 1 );
[gridX, gridY, gridZ] = meshgrid( -1 : 1, -1 : 1, -1 : 1 );
gridRSquared = ( gridX .* gridX + gridY .* gridY + gridZ .* gridZ );
kernel = exp( -0.5 * gridRSquared );

for k = 1:2
    di = round( ii / lI1 ) + 4;
    dj = round( jj / lI1 ) + 4;
    dz = round( aA / sigmaRange ) + 4;
    gridData = accumarray({di(:), dj(:), dz(:)}, aA(:), [downsampledeeeeEE downsampledeeeeEe downsampledDepth]);
    gridWeights = accumarray({di(:), dj(:), dz(:)}, 1, [downsampledeeeeEE downsampledeeeeEe downsampledDepth]);
    %gridRSquared = ( gridX .* gridX + gridY .* gridY  + gridZ .* gridZ );
    %kernel = exp( -0.5 * gridRSquared );
    blurredGridData = convn( gridData, kernel, 'same' );
    blurredGridWeights = convn( gridWeights, kernel, 'same' );
    blurredGridWeights( blurredGridWeights == 0 ) = -2; % avoid divide by 0, won't read there anyway
    normalizedBlurredGrid = blurredGridData ./ blurredGridWeights;
    normalizedBlurredGrid( blurredGridWeights < -1 ) = 0; % put 0s where it's undefined
    di = ( ii / lI1 ) + 4;
    dj = ( jj / lI1 ) + 4;
    dz = aA / sigmaRange + 4;
    aA = interpn( normalizedBlurredGrid, di, dj, dz ,'*linear');
    add = (iIlSum(1:nnr) - accumarray(iIlIdx(:), aA(:), [nnr 1])) ./ iIlSize(1:nnr);
    aA = aA + add(iIlIdx);
    aA = min(max(aA, 0), 255);
end

aA = round(aA);
end

function Aest = solver1(imageSize, queryLimit)

Areas = zeros(queryLimit,9);
% Stores Sum, Size and Target, U, D, L, R, Region, Mean.
% I assume all areas will be rectangular so cheaper to store edges
% than a map (or both? Which is cheaper to regenerate mask?)
% Rectangular assumption means I can't split as evenly as if I
% allow eg at 3x2 to be split into two L-shaped regions.

SplitThresh = [40 210];
% Controls willingness to split areas that are already identified
% as black or white.  128 means split any, think reasonable range
% is 32-64?  Should really be adaptive.  However 64 (in 039)
% did not help, so in 040 just try 100 => 129.



% First fun a simple scan of squareish areas using currently 50% of scans.
% Started with 10% but that proved too low, 50% may be too high.

ToDivide = floor( sqrt( queryLimit * 0.5 ) );
Step = imageSize / ToDivide;       % Seems to be an eps problem.
Step = Step + 10*eps(Step);
Map = zeros(ToDivide);

NextFree = 0;
Top = 0;
for i = 1:ToDivide      % Better to reverse order and linear index.
    Left = 0;
    for j = 1:ToDivide
        NextFree = NextFree+1;
        Areas(NextFree, 4) = floor(Top)+1;
        Areas(NextFree, 5) = floor(Top+Step);
        Areas(NextFree, 6) = floor(Left)+1;
        Left = Left + Step;
        Areas(NextFree, 7) = floor(Left);
        Mask = false(imageSize);
        % Faster to clear just previous or all?
        Mask(Areas(NextFree,4):Areas(NextFree,5),Areas(NextFree,6):Areas(NextFree,7)) = true;
        Areas(NextFree, 1) = queryImage(Mask);
        Areas(NextFree, 2) = (Areas(NextFree, 5)-Areas(NextFree, 4)+1) * ...
            (Areas(NextFree, 7)-Areas(NextFree, 6)+1);
        Areas(NextFree, 8) = i+j*ToDivide-ToDivide;
        Areas(NextFree, 9) = Areas(NextFree, 1) / Areas(NextFree, 2);
        % Convenience and visualisation
        Map(i,j) = Areas(NextFree, 9);
    end
    Top = Top + Step;
end
EndOfMap = NextFree;

% I want contrast measures for UD and LR.  Best to augment the map with a
% reflection so I don't underestimate edge contrast?

EdgedMap = zeros(ToDivide+2);
EdgedMap(2:ToDivide+1,2:ToDivide+1) = Map;
EdgedMap(:,1) = EdgedMap(:,3);
EdgedMap(1,:) = EdgedMap(3,:);
EdgedMap(:,end) = EdgedMap(:,end-2);
EdgedMap(end,:) = EdgedMap(end-2,:);

ContrastLR = abs(EdgedMap(2:end-1,2:end-1)-EdgedMap(2:end-1,1:end-2)) +  ...
    abs(EdgedMap(2:end-1,2:end-1)-EdgedMap(2:end-1,3:end  ));
ContrastUD = abs(EdgedMap(2:end-1,2:end-1)-EdgedMap(1:end-2,2:end-1)) +  ...
    abs(EdgedMap(2:end-1,2:end-1)-EdgedMap(3:end  ,2:end-1));
%    ContrastLR = ContrastLR + 0.2 * ContrastUD;
%    ContrastUD = ContrastUD + 0.2 * ContrastLR;   % Achieves nothing at present
Contrast   = ContrastLR+ContrastUD;

EdgedCon = zeros(ToDivide+2);
EdgedCon(2:ToDivide+1,2:ToDivide+1) = Contrast;
EdgedCon(:,1) = EdgedCon(:,2);
EdgedCon(1,:) = EdgedCon(2,:);
EdgedCon(:,end) = EdgedCon(:,end-1);
EdgedCon(end,:) = EdgedCon(end-1,:);

Contrast = 0.6 * EdgedCon(2:end-1,2:end-1) + 0.14 * ( ...
    EdgedCon(1:end-2,2:end-1) + ...
    EdgedCon(3:end  ,2:end-1) + ...
    EdgedCon(2:end-1,1:end-2) + ...
    EdgedCon(2:end-1,3:end  ) );
% This makes contrast different from unsmoothed LR and UD.
% Don't think that matters, purposes are different.

% for h = 1:length(Contrast)^2
%     Areas(h,10) = Contrast(Areas(h,8));
% end

% So now I have an initial partition and an idea of the contrast I can
% expect in each area.  I can now revert to my old scheme of looking for
% the most attractive areas to split, BUT can measure attractiveness
% separately for LR / UD


for Query = EndOfMap+1:queryLimit
    
    % Split the most valuable candidate to split based on size x contrast.
    % Direction of contrast is basically a tiebreak for squareish cells,
    % long cells will usually split on long edge.  Balance needs tuning.
    % Don't want to split very black or very white areas as won't learn much;
    % currently a crude threshold, should integrate more tightly.
    % Threshold may leave no legal choice, hence while loop 8-/
    
    %     NextFree = NextFree + 1;
    %     [~,i] = max(Areas(:,2).*Areas(:,10).*(Areas(:,9) > SplitThresh(1) & Areas(:,9) <SplitThresh(2)));
    %     ToSplit = i;            % Paranoid area test, prob not needed
    
    
    NextFree = NextFree + 1;
    BestYet = -1;
    while BestYet == -1
        for i = 1:NextFree-1
            if ( ((Areas(i,2)-1) * Contrast(Areas(i,8)) > BestYet) && ...
                    Areas(i,9) > SplitThresh(1) && Areas(i,9) <SplitThresh(2))
                ToSplit = i;            % Paranoid area test, prob not needed
                BestYet = (Areas(i,2)-1) * Contrast(Areas(i,8));
                
            end
        end
    end
    i = ToSplit;
    SplitUD = ContrastUD(Areas(i,8)) * (Areas(i,5)-Areas(i,4)) > ...
        ContrastLR(Areas(i,8)) * (Areas(i,7)-Areas(i,6));
    % Perform the split
    Areas(NextFree,:) = Areas(ToSplit,:);
    Height = Areas(ToSplit,5)-Areas(ToSplit,4) + 1;
    Width  = Areas(ToSplit,7)-Areas(ToSplit,6) + 1;
    % Aim for now is to keep areas squareish
    if SplitUD && Height > 1
        % Could track past successes to make this adaptive.
        % More generally, square may not always be best.
        Del = floor((Height-1)/2);
        Areas(NextFree,4) = Areas(ToSplit,4) + Del + 1;
        Areas(ToSplit,5)  = Areas(ToSplit,4) + Del;
        Areas(ToSplit,2)  = Width * (Del+1);
        Areas(NextFree,2) = Width * floor(Height/2);
    else
        Del = floor((Width-1)/2);
        Areas(NextFree,6) = Areas(ToSplit,6) + Del + 1;
        Areas(ToSplit,7)  = Areas(ToSplit,6) + Del;
        Areas(ToSplit,2)  = Height * (Del+1);
        Areas(NextFree,2) = Height * floor(Width/2);
    end
    
    % Construct mask and get the score
    
    Mask = false(imageSize);       % Clear previous; faster to just clear area?
    Mask(Areas(ToSplit,4):Areas(ToSplit,5),Areas(ToSplit,6):Areas(ToSplit,7)) = true;
    Areas(ToSplit,1) = queryImage(Mask);
    
    % Update the two regions -- don't bother with column 3 any more.
    
    Areas(NextFree,1) = Areas(NextFree,1) - Areas(ToSplit,1);
    Areas(NextFree,9) = Areas(NextFree,1) / Areas(NextFree,2);
    Areas(ToSplit,9)  = Areas(ToSplit,1)  / Areas(ToSplit,2);
    
end

% We now have a long list of rectangular areas, so walk through list
% reconstructing image from them.
% For now ignore smoothing and just use averages.
% Could maintain image during the above loop but I think multiple updates
% are probably wasteful unless partial images are going to guide search.

regionIdx = ones(imageSize, 'uint32');

% Aest = zeros(imageSize);        % Is this needed?
for i = 1:queryLimit
    Aest(Areas(i,4):Areas(i,5),Areas(i,6):Areas(i,7)) = ...
        Areas(i,1) / Areas(i,2);
    regionIdx(Areas(i,4):Areas(i,5),Areas(i,6):Areas(i,7))=i;
end
nnr=queryLimit;

Aest = kippen(Aest,nnr,Areas);

h = [0.20 0.65 0.2];
for a = 1:9
    Aest = conv2(h', h, Aest([1 1:end end],[1 1:end end]), 'valid');
    add = (Areas(:,1) - accumarray(regionIdx(:), Aest(:), [nnr 1])) ./ Areas(:,2);
    Aest = min(max(Aest + add(regionIdx), 0), 255);
end

lI1=7+(Step-5.8); sigmaRange=17+(Step-5.8);

downsampledeeeeEE = floor( ( imageSize - 1 ) / lI1 ) + 7;
downsampledeeeeEe = floor( ( imageSize - 1 ) / lI1 ) + 7;
downsampledDepth = floor( 255 / sigmaRange ) + 7;
[ jj, ii ] = meshgrid( 0 : imageSize - 1, 0 : imageSize - 1 );
[gridX, gridY, gridZ] = meshgrid( -1 : 1, -1 : 1, -1 : 1 );
gridRSquared = ( gridX .* gridX + gridY .* gridY + gridZ .* gridZ );
kernel = exp( -2 * gridRSquared );

for k = 1:2
    di = round( ii / lI1 ) + 4;
    dj = round( jj / lI1 ) + 4;
    dz = round( Aest / sigmaRange ) + 4;
    gridData = accumarray({di(:), dj(:), dz(:)}, Aest(:), [downsampledeeeeEE downsampledeeeeEe downsampledDepth]);
    gridWeights = accumarray({di(:), dj(:), dz(:)}, 1, [downsampledeeeeEE downsampledeeeeEe downsampledDepth]);
    blurredGridData = convn( gridData, kernel, 'same' );
    blurredGridWeights = convn( gridWeights, kernel, 'same' );
    blurredGridWeights( blurredGridWeights == 0 ) = -2; % avoid divide by 0, won't read there anyway
    normalizedBlurredGrid = blurredGridData ./ blurredGridWeights;
    normalizedBlurredGrid( blurredGridWeights < -1 ) = 0; % put 0s where it's undefined
    di = ( ii / lI1 ) + 4;
    dj = ( jj / lI1 ) + 4;
    dz = Aest / sigmaRange + 4;
    Aest = interpn( normalizedBlurredGrid, di, dj, dz ,'*linear');
    add = (Areas(:,1) - accumarray(regionIdx(:), Aest(:), [nnr 1])) ./ Areas(:,2);
    Aest = min(max(Aest + add(regionIdx), 0), 255);
end

Aest = round(Aest);

end

function Aest = kippen(Aest,nnr,Areas)
n = size(Aest,1);

AcorrX = zeros(n);
AcorrY = AcorrX ;
A = Aest;

for idx = 1:nnr
    x1 = Areas(idx,4);
    x2 = Areas(idx,5);
    dx = x2-x1+1;
    y1 = Areas(idx,6);
    y2 = Areas(idx,7);
    dy = y2-y1+1;
    sz = dx*dy;
    total = Areas(idx,1);
    
    if sz <= 1
        continue
    end
    
    m = total / sz;
    
    dmx = 0;
    dmy = 0;
    if dx > 1
        if x1 > 1 && x2 < n
            dm1 = m - sum(A(x1-1,y1:y2))/dy;
            dm2 = sum(A(x2+1,y1:y2))/dy-m;
            dmx = (dm1 < 0 && dm2 < 0) * max(dm1,dm2) + (dm1 > 0 && dm2 > 0)*min(dm1,dm2);
        elseif x1 == 1 && x2 < n
            dmx = sum(A(x2+1,y1:y2))/ dy-m;
        elseif x1 > 1 && x2 == n
            dmx = m - sum(A(x1-1,y1:y2))/dy;
        end
        
        if dmx ~= 0
            x = (0:dx-1)'/(dx-1);
            AcorrX(x1:x2,y1:y2) = repmat(dmx*x - 0.5*dmx,1,dy);
        end
    end
    
    if dy > 1
        if y1 > 1 && y2 < n
            dm1 = m - sum(A(x1:x2,y1-1))/dx;
            dm2 = sum(A(x1:x2,y2+1))/dx - m;
            dmy = (dm1< 0 && dm2 < 0)* max(dm1,dm2) + (dm1 > 0 && dm2 > 0)*min(dm1,dm2);
        elseif y1 == 1 && y2 < n
            dmy = sum(A(x1:x2,y2+1))/dx - m;
        elseif y1 > 1 && y2 == n
            dmy = m - sum(A(x1:x2,y1-1))/dx;
        end
        
        if dmy ~= 0
            y = (0:dy-1)/(dy-1);
            AcorrY(x1:x2,y1:y2) = repmat(dmy*y - 0.5*dmy,dx,1);
        end
    end
end
Aest = Aest + AcorrX + AcorrY;
end