Finish 2012-04-11 12:00:00 UTC

edgggggggggge2

by Werner

Status: Failed
Results: Failed (filefilt): Error using filefilt (line 122) The function PAUSE has been disabled.

Based on: edgggggggggge (diff)
Basis for: edgggggggggge3 (diff)

Comments
Please login or create a profile.
Code
function [board orientation score] = solver(tiles, boardSize)
    ntiles = size(tiles, 1);
    nrows = boardSize(1);
    ncols = boardSize(2);
    nfields = nrows * ncols;
    maxroute=min(ntiles,nfields);
    
    %routes{1}=[];
    %routesrc{1}=[];
    
    cropable=false;
    
    if ntiles<nfields
        cropable=true;
        
        rectangles=[repmat(1:nrows,1,ncols);repmat(1:ncols,1,nrows)];
        rectangles_area = prod(rectangles);
        rectangles_area(rectangles_area<ntiles)=inf;
        [a b] = min(rectangles_area-ntiles+2*sum(rectangles));
        
        cropsize=rectangles(:,b)';
        cnrows=cropsize(1);
        cncols=cropsize(2);
    end
      
    
    
    
    
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %snake:
    route = nan(boardSize);
    route(1:maxroute)=1:maxroute;
    routes{1}=route;
    routesname{1}='snake';
    
    if cropable
        route = nan(boardSize);
        croproute = nan(cropsize);
        croproute(1:maxroute)=1:maxroute;
        route(1:cnrows,1:cncols)=croproute;
        routes{end+1}=route;
        routesname{end+1}='snake crop';
    end
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %fill diag:
    route = nan(boardSize);
    helpmat = repmat(1:ncols,nrows,1)+repmat((1:nrows)',1,ncols);
    [a b] =sort(helpmat(:));
    route(b(1:maxroute))=1:maxroute;
    routes{end+1}=route;
    routesname{end+1}='diag';
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %spiral 1 inner to outer:
    route = spiralix(boardSize);
    route(route>maxroute)=nan;
    routes{end+1}=route;
    routesname{end+1}='spiral 1 inner to outer';
%     
%     
%     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     %spiral 2 inner to outer:
     route = spiralix2(boardSize);
     route(route>maxroute)=nan;
     routes{end+1}=route;
     routesname{end+1}='spiral 2 inner to outer';
     

         %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %spiral 1 outer to inner:
    route = spiralix(boardSize);
    route = -route + nfields + 1; 
    route(route>maxroute)=nan;
    routes{end+1}=route;
    routesname{end+1}='spiral 1 outer to inner';
%     
%     
%     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     %spiral 2 outer to inner:
     route = spiralix2(boardSize);
     route = -route + nfields + 1; 
     route(route>maxroute)=nan;
     routes{end+1}=route;
     routesname{end+1}='spiral 2 outer to inner';

     
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %corner and edge:
    if nrows > 1 & ncols > 1
        for i=1:numel(routes)
            route = routes{i};
            edgelen=2*nrows+2*ncols-4;
            route = route+edgelen;
            
            helpmat = repmat(1:ncols,nrows,1)+repmat((1:nrows)',1,ncols);
            helpmat(2:end-1,2:end-1)=nan;
            [a b] =sort(helpmat(:));
            route(b(1:edgelen))=(1:edgelen)+4;
            route(1,1) = 1;
            route(1,end)=2;
            route(end,1)=3;
            route(end,end)=4;
            [a b] =sort(route(:));
            route(b(1:maxroute))=1:maxroute;
            routes{end+1}=route;
            routesname{end+1}=[routesname{i} '+ edge'];
        end
    end
    %route
    %route(1:maxroute)=1:maxroute;
    %routes{1}=route;
    %end    
    %if cropable
    %    route = nan(boardSize);
    %    croproute = nan(cropsize);
    %    croproute(1:maxroute)=1:maxroute;
    %    route(1:cnrows,1:cncols)=croproute;
    %    routes{end+1}=route;
    %end
    
    
    
    
    
    
    for i=1:numel(routes)
        route=routes{i};
        [~,ind]=sort(route(:));
        [r c] = ind2sub(boardSize,ind(1:maxroute));
        routesrc{i}=[r c];
    end
 % visualizeroutes(routes)
    
%     
%     if ntiles<nrows*ncols
%         rectangles=[repmat(1:nrows,1,ncols);repmat(1:ncols,1,nrows)];
%         rectangles_area = prod(rectangles);
%         rectangles_area(rectangles_area<ntiles)=inf;
%         [a b] = min(rectangles_area-ntiles+2*sum(rectangles));
%         
%         cropsize=rectangles(:,b)';
%         cnrows=cropsize(1);
%         cncols=cropsize(2);
%     end
%     
%     
%     m_route=1;
%     
%     
%     nfields = nrows * ncols;
%    % tiles = [tiles; zeros(nfields-ntiles, 4)];
%     rv = (1:boardSize(1))';
%     cv = (1:boardSize(2))';
%     
%     switch m_route;
%         case 1; % corners...edges...mid
%             route = [1,1];
%             if cnrows > 1; route = [route; nrows, 1]; end;
%             if cncols > 1; route = [route; 1, ncols]; end;
%             if cnrows > 1 && ncols > 1; route = [route; nrows, ncols]; end;
%             if cncols > 2;
%                 route = [route; ones(cncols-2, 1), cv(2:end-1, 1)];
%                 if cnrows > 1; route = [route; nrows * ones(ncols-2, 1),cv(2:end-1, 1)]; end
%             end
%             if nrows > 2;
%                 route = [route; rv(2:end-1, 1), ones(nrows-2, 1)];
%                 if ncols > 1; route = [route; rv(2:end-1, 1), ncols * ones(nrows-2, 1)]; end
%             end
%             if nrows > 2 && ncols > 2;
%                 aidr = rv(2:end-1, ones(1, boardSize(2)-2));
%                 
%                 aidc = cv(2:end-1, ones(1, boardSize(1)-2))';
%                 route = [route; aidr(:), aidc(:)];
%             end
%         case 2; % column by column
%             aidr = rv(:, ones(1, boardSize(2)));
%             aidc = cv(:, ones(1, boardSize(1)))';
%             route = [aidr(:), aidc(:)];
%         case 3; % column by column
%             aidr = rv(:, ones(1, boardSize(2)))';
%             aidc = cv(:, ones(1, boardSize(1)));
%             route = [aidr(:), aidc(:)];
%         case 4;
%             route = zeros(0,2);
%             for i = 1:nrows+ncols-1;
%                 route = [route; (i:-1:1)', (1:i)'];
%             end
%             route = route(route(:,1) <= nrows & route(:,2) <= ncols, :);
%             
%         otherwise;
%             assert(false, 'r0ldrlcpmwhib2gfmhuwz72tjfdt30zokmo33vh9');
%     end
%     
%     
%     
%     route=route(1:min(ntiles,nrows*ncols),:);

nroutes = numel(routesrc);
for j = 1:4
for i=1:nroutes
    [b o] = solver_quick(tiles, boardSize, routesrc{i});
    s = overallScore(b,o,tiles);
    bcell{i} = b;
    ocell{i} = o;
    svec(i) = s;
end
end
svec';
[trash,mo] = min(svec(:));
%board = b(:,:,mo);
%orientation = o(:,mo);
routesname{mo}
[board,orientation]=localopt(bcell{mo}, ocell{mo},tiles);
%board = bcell{mo};
%orientation = ocell{mo};


    
%   [board orientation] = solver_quick(tiles, boardSize, routesrc{end});
 %  [board,orientation] = localopt(board, orientation,tiles);
end


function score = overallScore(board, orientation, tiles)
cs = [1 2 3 4; 2 3 4 1; 3 4 1 2; 4 1 2 3];
[nrow ncol] = size(board);

tile = zeros(nrow*4,ncol);
tmp = tiles.';
for y = 1:nrow
    for x = 1:ncol
        if board(y,x)
            tile((y-1)*4+1:y*4,x)=tmp(cs(orientation(board(y,x)),:),board(y,x));
        end
    end
end
%internal = sum(sum(abs(tile(5:4:end,1:end)-tile(3:4:end-4,1:end))))+sum(sum(abs(tile(2:4:end,1:end-1)-tile(4:4:end,2:end))));
%external = sum(tile(4:4:end,1))+sum(tile(2:4:end,end))+sum(tile(end-1,1:end))+sum(tile(1,1:end));
out_tiles = 1:size(tiles,1);
in_tiles = board(board>0);
out_tiles(in_tiles) = [];
%notplayed = sum(sum(tiles(out_tiles,:)));
%score = internal + external + notplayed;
score = sum(sum(abs(tile(5:4:end,1:end)-tile(3:4:end-4,1:end))))+ ...
    sum(sum(abs(tile(2:4:end,1:end-1)-tile(4:4:end,2:end))))+ ...
    sum(tile(4:4:end,1))+sum(tile(2:4:end,end))+sum(tile(end-1,1:end))+ ...
    sum(tile(1,1:end))+sum(sum(tiles(out_tiles,:)));
end

function [board orientation score] = solver_quick(tiles, boardSize, route)
       
    board = zeros(boardSize);
    orientation = ones(size(tiles,1), 1);
    score = sum(tiles(:));
    
    nrows = boardSize(1);
    ncols = boardSize(2);
    
    ntiles = size(tiles, 1);
    tiles = [tiles; tiles(:,[2:4,1]); tiles(:,[3:4,1:2]); tiles(:,[4,1:3])];
    tiles_sum = sum(tiles,2);
    
    env = nan(nrows+2,ncols+2);
    eev = nan(nrows+2,ncols+2);
    esv = nan(nrows+2,ncols+2);
    ewv = nan(nrows+2,ncols+2);
    
    env(2,:) = 0;
    eev(:,end-1) = 0;
    esv(end-1,:) = 0;
    ewv(:,2) = 0;

    mask2=ntiles*(0:3);
          
    for i=1:numel(route)/2
        r=route(i,1);
        c=route(i,2);
        
        v=[env(r+1,c+1) eev(r+1,c+1) esv(r+1,c+1) ewv(r+1,c+1)];
        mask = ~isnan(v);
        
        tilecosts = sum(abs(bsxfun(@minus, tiles(:,mask), v(mask))), 2);
        [~, tileix] = min(tilecosts-(tiles_sum).*1e-6);
        
        board(r,c) = tileix;
        
        env(r+2,c+1) = tiles(tileix,3);
        eev(r+1,c) = tiles(tileix,4);
        esv(r,c+1) = tiles(tileix,1);
        ewv(r+1,c+2) = tiles(tileix,2);
        
        ix = mod(tileix-1, ntiles)+1;
        o = ceil(tileix/ntiles);
        orientation(ix) = o;
        tiles(ix,:) = nan;
        tiles(ix+mask2(2),:) = nan;
        tiles(ix+mask2(3),:) = nan;
        tiles(ix+mask2(4),:) = nan;
    end
    
    board(board ~= 0) = mod(board(board ~= 0)-1, ntiles)+1;
end




function [board,orientation,gain]=localopt(board, orientation,tiles)
gain=0;
cs = [1 2 3 4;2 3 4 1;3 4 1 2;4 1 2 3];
[r,c]=size(board);
n = size(tiles,1);
didx = [3;4;1;2];
uidx = [1;2;3;4];
lidx = [4;1;2;3];
ridx = [2;3;4;1];
bp = board>0;
bt = board(bp);
te = [zeros(1,4);tiles];
oe = [1;orientation];
ub = [zeros(1,c);board(1:end-1,:)];
db = [board(2:end,:);zeros(1,c)];
lb = [zeros(r,1) board(:,1:end-1)];
rb = [board(:,2:end) zeros(r,1)];
ut = ub(bp)+1;
dt = db(bp)+1;
lt = lb(bp)+1;
rt = rb(bp)+1;
uv = te(ut(:)+(didx(oe(ut))-1)*(n+1));
dv = te(dt(:)+(uidx(oe(dt))-1)*(n+1));
lv = te(lt(:)+(ridx(oe(lt))-1)*(n+1));
rv = te(rt(:)+(lidx(oe(rt))-1)*(n+1));
bt=bt(:);
bv = tiles(bt(:,ones(1,4))+(cs(orientation(bt),:)-1)*n);
% bv = tiles(bt,:);
nv = [uv rv dv lv];
pv = sum(abs(bv-nv),2);
[mpv,id]=max(pv);
while mpv
    bid=bt(id);
    bid1=bid+1;
    pv(id)=0;
    obid = orientation(bid);
    bx = tiles(bid,:);
    p0 = sum(abs(bx(cs)-nv(id+zeros(4,1),:)),2);
    [pmin,ido]=min(p0);
    gain=gain+(p0(obid)-pmin);
    if p0(obid)>pmin
        bv(id,:)=bx(cs(ido,:));
        orientation(bid)=ido;
        oe(bid1)=ido;
        u1=ut==bid1;
        d1=dt==bid1;
        l1=lt==bid1;
        r1=rt==bid1;
        uv(u1)=tiles(bid,didx(ido));
        nv(u1,1)=uv(u1);
        dv(d1)=tiles(bid,uidx(ido));
        nv(d1,3)=dv(d1);
        lv(l1)=tiles(bid,ridx(ido));
        nv(l1,4)=lv(l1);
        rv(r1)=tiles(bid,lidx(ido));
        nv(r1,2)=rv(r1);
        L=u1|d1|l1|r1;
        pv(L) = sum(abs(bv(L,:)-nv(L,:)),2);
    end
    [mpv,id]=max(pv);
end
pv = sum(abs(bv-nv),2);
[mpv,id]=max(pv);
N=numel(pv);
tv = tiles(bt,:);
k=0;
while mpv>0
    bid = bt(id);
    bid1=bid+1;
    nvid = zeros(1,16);
    nvid(:) = nv(id+zeros(4,1),:);
    u1=ut==bid1;
    d1=dt==bid1;
    l1=lt==bid1;
    r1=rt==bid1;
    L=~(u1|d1|l1|r1);
    L(id)=false;
    qv = Inf(N,4);
    qv(L,:) = reshape(sum(reshape(abs(tv(L,cs)-nvid(ones(sum(L),1),:)),[],4),2),[],4);
    [iv,to] = min(qv(:));
    jd = mod(to-1,N)+1;
    bjd = bt(jd);
    bjd1=bjd+1;
    % objd = orientation(bjd);
    jo = ceil(to/N);
    nvjd = nv(jd+zeros(4,1),:);
    bvid = zeros(4);
    bvid(:) = tiles(bid,cs);
    [jv,io]=min(sum(abs(bvid - nvjd),2));
    jpv = sum(abs(bv(jd,:) - nv(jd,:)));
    if iv+jv < mpv+jpv
        bt(jd) = bid;
        bt(id) = bjd;
        orientation(bid) = io;
        orientation(bjd) = jo;
        board(bp)=bt;
        bv(id,:) = tv(jd,cs(jo,:));
        bv(jd,:) = tv(id,cs(io,:));
        bx = tv(id,:);
        tv(id,:) = tv(jd,:);
        tv(jd,:) = bx;
        uv(u1)=tiles(bjd,didx(jo));
        nv(u1,1)=uv(u1);
        dv(d1)=tiles(bjd,uidx(jo));
        nv(d1,3)=dv(d1);
        lv(l1)=tiles(bjd,ridx(jo));
        nv(l1,4)=lv(l1);
        rv(r1)=tiles(bjd,lidx(jo));
        nv(r1,2)=rv(r1);
        u2=ut==bjd1;
        d2=dt==bjd1;
        l2=lt==bjd1;
        r2=rt==bjd1;
        uv(u2)=tiles(bid,didx(io));
        nv(u2,1)=uv(u2);
        dv(d2)=tiles(bid,uidx(io));
        nv(d2,3)=dv(d2);
        lv(l2)=tiles(bid,ridx(io));
        nv(l2,4)=lv(l2);
        rv(r2)=tiles(bid,lidx(io));
        nv(r2,2)=rv(r2);
        L=u1|d1|l1|r1|u2|d2|l2|r2;
        pv(L) = sum(abs(bv(L,:)-nv(L,:)),2);
        uid = ut==bid1;
        ujd = ut==bjd1;
        ut(uid) = bjd1;
        ut(ujd) = bid1;
        did = dt==bid1;
        djd = dt==bjd1;
        dt(did) = bjd1;
        dt(djd) = bid1;
        lid = lt==bid1;
        ljd = lt==bjd1;
        lt(lid) = bjd1;
        lt(ljd) = bid1;
        rid = rt==bid1;
        rjd = rt==bjd1;
        rt(rid) = bjd1;
        rt(rjd) = bid1;
        k=k+1;
    end
    pv(id)=0;
    pv(jd)=0;
    [mpv,id]=max(pv);
end
end


function visualizeroutes(routes)
    %figure
    for i=1:numel(routes)
        imagesc(routes{i});
        pause(3)
    end
end




function ix = spiralix(boardsize)
    ix = nan(boardsize);

    dir = [1 0];
    
    pos = [1 1];
    
    
    x=prod(boardsize);
    
    while sum(sum(isnan(ix)))>0
        if any(pos<1) || any(boardsize-pos<0) || ~isnan(ix(pos(1),pos(2)))
            pos=pos-dir;
            dir=spiralnextdir(dir);
            pos=pos+dir;
        end
        if ~any(pos<0) && ~any(boardsize-pos<0) && isnan(ix(pos(1),pos(2)))
            ix(pos(1),pos(2))=x;
            x=x-1;
            pos=pos+dir;
        end
    end    
end

function direction  = spiralnextdir(direction)
    if direction ==[1 0],direction=[0 1];return;end
    if direction ==[0 1],direction=[-1 0];return;end
    if direction ==[-1 0],direction=[0 -1];return;end
    if direction ==[0 -1],direction=[1 0];return;end
end


function ix = spiralix2(boardsize)
    bsr = boardsize(1);
    bsc = boardsize(2);
    maxbs = max(boardsize);
    ix_big = spiralix([maxbs maxbs]);
    ix1 = ix_big((1:bsr)+round((maxbs-bsr)./2),(1:bsc)+round((maxbs-bsc)./2));
    
    [a b] = sort(ix1(:));
    ix=ix1;
    ix(b)=1:numel(b);
end