2 #include "linespace.hh"
5 #include "unionfind.hh"
7 const Real COLFUDGE
=1e-3;
8 //#define COLFUDGE 1e-3
10 Spacing_problem::contains(const PCol
*w
)
12 for (int i
=0; i
< cols
.sz(); i
++)
19 Spacing_problem::col_id(const PCol
*w
)const
21 for (int i
=0; i
< cols
.sz(); i
++)
28 Spacing_problem::OK() const
30 Union_find
connected(cols
.sz());
32 for (int i
=0; i
< ideals
.sz(); i
++) {
33 assert(ideals
[i
]->hooke
> 0);
34 int l
= col_id(ideals
[i
]->left
);
35 int r
= col_id(ideals
[i
]->right
);
36 connected
.connect(l
,r
);
39 for (int i
= 0; i
< cols
.sz(); i
++) {
40 assert( connected
.equiv(0,i
));
45 Spacing_problem::check_constraints(Vector v
) const
48 // mtor << "checking solution " << v << '\n';
49 for (int i
=0; i
< dim
; i
++) {
51 if (cols
[i
].fixed
&& ABS(cols
[i
].fixpos
- v(i
)) > COLFUDGE
) {
57 Real mindist
=cols
[i
-1].minright()
61 Real dif
=v(i
) - v(i
-1)- mindist
;
62 bool b
= (dif
> - COLFUDGE
);
70 mtor
<< "dif= "<<dif
<<" fudge= " << COLFUDGE
<< " dif >fudge= "<<
73 /* fucks up for unknown reasons */
83 Spacing_problem::check_feasible() const
85 Vector
sol(try_initial_solution());
86 return check_constraints(sol
);
89 // generate a solution which obeys the min distances and fixed positions
91 Spacing_problem::try_initial_solution() const
95 for (int i
=0; i
< dim
; i
++) {
97 initsol(i
)=cols
[i
].fixpos
;
99 Real mindist
=cols
[i
-1].minright()
101 assert(mindist
>= 0.0);
102 initsol(i
)=initsol(i
-1)+mindist
;
106 // assert(initsol(i) > initsol(i-1));
113 Spacing_problem::find_initial_solution() const
115 Vector
v(try_initial_solution());
116 assert(check_constraints(v
));
119 // generate the matrices
121 Spacing_problem::make_matrices(Matrix
&quad
, Vector
&lin
) const
125 for (int j
=0; j
< ideals
.sz(); j
++){
126 Idealspacing
const*i
=ideals
[j
];
127 int l
= col_id(i
->left
);
128 int r
= col_id(i
->right
);
130 quad(r
,r
) += i
->hooke
;
131 quad(r
,l
) -= i
->hooke
;
132 quad(l
,r
) -= i
->hooke
;
133 quad(l
,l
) += i
->hooke
;
135 lin(r
) -= i
->space
*i
->hooke
;
136 lin(l
) += i
->space
*i
->hooke
;
140 // put the constraints into the LP problem
142 Spacing_problem::make_constraints(Optimisation_problem
& lp
) const
144 for (int j
=0; j
< cols
.sz(); j
++) {
145 Colinfo
*c
=&(cols
[j
]);
149 lp
.add_fixed_var(j
,c
->fixpos
);
159 lp
.add_inequality_cons(c1
, cols
[j
-1].minright() +
164 lp
.add_inequality_cons(c2
,
165 cols
[j
+1].minleft() +
172 Spacing_problem::solve() const
175 assert(check_feasible());
178 /* optimalisatiefunctie */
179 Optimisation_problem
lp(cols
.sz());
180 make_matrices(lp
.quad
,lp
.lin
);
181 make_constraints(lp
);
182 Vector start
=find_initial_solution();
183 Vector
sol(lp
.solve(start
));
184 if (!check_constraints(sol
)) {
185 error( "solution doesn't solve. Sorry");
189 svec
<Real
> posns(sol
);
190 posns
.add(lp
.eval(sol
));
195 add one column to the problem.
198 Spacing_problem::add_column(const PCol
*col
, bool fixed
, Real fixpos
)
208 Spacing_problem::add_ideal(const Idealspacing
*i
)
210 const PCol
*l
=i
->left
;
211 const PCol
*r
= i
->right
;
213 if (!contains(l
) || !contains(r
)) {
220 Spacing_problem::print_ideal(const Idealspacing
*id
)const
222 int l
= col_id(id
->left
);
223 int r
= col_id(id
->right
);
225 mtor
<< "idealspacing { between " << l
<<","<<r
<<'\n';
226 mtor
<< "distance "<<id
->space
<< " strength " << id
->hooke
<< "}\n";
230 Spacing_problem::print() const
232 for (int i
=0; i
< cols
.sz(); i
++) {
233 mtor
<< "col " << i
<<' ';
236 for (int i
=0; i
< ideals
.sz(); i
++) {
237 print_ideal(ideals
[i
]);
242 Colinfo::print() const
246 mtor
<< "fixed at " << fixpos
<<", ";
247 mtor
<< "[" << minleft() << ", " << minright() << "]";