source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/opt/yalmip/modules/parametric/mpt_parbb.m @ 37

Last change on this file since 37 was 37, checked in by (none), 14 years ago

Added original make3d

File size: 5.1 KB
Line 
1function model = mpt_parbb(Matrices,options)
2
3% For simple development, the code is currently implemented in high-level
4% YALMIP and MPT code. Hence, a substantial part of the computation time is
5% stupid over-head.
6
7[Matrices.lb,Matrices.ub] = mpt_detect_and_improve_bounds(Matrices,Matrices.lb,Matrices.ub,Matrices.binary_var_index,options);
8
9U = sdpvar(Matrices.nu,1);
10x = sdpvar(Matrices.nx,1);
11F = set(Matrices.G*U < Matrices.W + Matrices.E*x);
12F = F + set(Matrices.lb < [U;x] < Matrices.ub);
13F = F + set(binary(U(Matrices.binary_var_index)));
14F = F + set(Matrices.Aeq*U + Matrices.Beq*x == Matrices.beq);
15h = Matrices.H*U + Matrices.F*x;
16
17Universe = polytope(set(Matrices.lb(end-Matrices.nx+1:end) <= x <= Matrices.ub(end-Matrices.nx+1:end)));
18
19model = parametric_bb(F,h,options,x,Universe);
20
21function sol = parametric_bb(F,obj,ops,x,Universe)
22
23% F   : All constraints
24% obj : Objective
25% x   : parametric variables
26% y   : all binary variables
27
28if isempty(ops)
29    ops = sdpsettings;
30end
31ops.mp.algorithm = 1;
32ops.cachesolvers = 0;
33ops.mp.presolve=1;
34ops.solver = '';
35
36% Expand nonlinear operators only once
37F = expandmodel(F,obj);
38ops.expand = 0;
39
40% Gather all binary variables
41y = unique([depends(F) depends(obj)]);
42n = length(y)-length(x);
43y = intersect(y,[yalmip('binvariables') depends(F(find(is(F,'binary'))))]);
44y = recover(y);
45
46% Make sure binary relaxations satisfy 0-1 constraints
47F = F + set(0 <= y <= 1);
48
49% recursive, starting in maximum universe
50sol = sub_bb(F,obj,ops,x,y,Universe);
51
52% Nice, however, we have introduced variables along the process, so the
53% parametric solutions contain variables we don't care about
54for i = 1:length(sol)
55    for j = 1:length(sol{i}.Fi)
56        sol{i}.Fi{j} = sol{i}.Fi{j}(1:n,:);
57        sol{i}.Gi{j} = sol{i}.Gi{j}(1:n,:);
58    end
59end
60
61function sol = sub_bb(F,obj,ops,x,y,Universe)
62
63sol = {};
64
65% Find a feasible point in this region. Note that it may be the case that a
66% point is feasible, but the feasible space is flat. This will cause the
67% mplp solver to return an empty solution, and we have to pick a new
68% binary solution.
69
70localsol = {[]};
71intsol.problem = 0;
72
73if 1%while intsol.problem == 0
74    localsol = {[]};
75    while isempty(localsol{1}) & (intsol.problem == 0)
76        ops.verbose = ops.verbose-1;
77        intsol = solvesdp(F,obj,sdpsettings(ops,'solver','glpk'));
78        ops.verbose = ops.verbose+1;
79        if intsol.problem == 0
80            y_feasible = round(double(y));
81            ops.relax = 1;
82            localsol = solvemp(F+set(y == y_feasible),obj,ops,x);
83            ops.relax = 0;
84            if isempty(localsol{1})
85                F = F + not_equal(y,y_feasible);
86            end
87            F = F + not_equal(y,y_feasible);
88
89        end
90    end
91    if ~isempty(localsol{1})
92
93        % YALMIP syntax...
94        if isa(localsol,'cell')
95            localsol = localsol{1};
96        end
97
98        % Now we want to find solutions with other binary combinations, in
99        % order to find the best one. Cut away the current bionary using
100        % overloaded not equal
101        F = F + not_equal(y,y_feasible);
102
103        % Could be that the binary was feasible, but the feasible space in the
104        % other variables is empty/lower-dimensional
105        if ~isempty(localsol)
106            % Dig into this solution. Try to find another feasible binary
107            % combination, with a better cost, in each of the regions
108            for i = 1:length(localsol.Pn)
109                G = F;
110                % Better cost
111                G = G + set(obj <= localsol.Bi{i}*x + localsol.Ci{i});
112                % In this region
113                [H,K] = double(localsol.Pn(i));
114                G = G + set(H*x <= K);
115                % Recurse
116                diggsol{i} = sub_bb(G,obj,ops,x,y,localsol.Pn(i));
117            end
118
119            % Create all neighbour regions, and compute solutions in them too
120            flipped = regiondiff(union(Universe),union(localsol.Pn));
121            flipsol={};
122            for i = 1:length(flipped)
123                [H,K] = double(flipped(i));
124                flipsol{i} = sub_bb(F+ set(H*x <= K),obj,ops,x,y,flipped(i));
125            end
126
127            % Just place all solutions in one big cell. We should do some
128            % intersect and compare already here, but I am lazy now.
129            sol = appendlists(sol,localsol,diggsol,flipsol);
130        end
131    end
132end
133
134function sol = appendlists(sol,localsol,diggsol,flipsol)
135
136sol{end+1} = localsol;
137for i = 1:length(diggsol)
138    if ~isempty(diggsol{i})
139        if isa(diggsol{i},'cell')
140            for j = 1:length(diggsol{i})
141                sol{end+1} = diggsol{i}{j};
142            end
143        else
144            sol{end+1} = diggsol{i};
145        end
146    end
147end
148for i = 1:length(flipsol)
149    if ~isempty(flipsol{i})
150        if isa(flipsol{i},'cell')
151            for j = 1:length(flipsol{i})
152                sol{end+1} = flipsol{i}{j};
153            end
154        else
155            sol{end+1} = flipsol{i};
156        end
157    end
158end
159
160
161function F = not_equal(X,Y)
162zv = find((Y == 0));
163ov = find((Y == 1));
164lhs = 0;
165if ~isempty(zv)
166    lhs = lhs + sum(extsubsref(X,zv));
167end
168if ~isempty(ov)
169    lhs = lhs + sum(1-extsubsref(X,ov));
170end
171F = set(lhs >=1);
Note: See TracBrowser for help on using the repository browser.