3
FieldVector FieldLP::subvector(FieldVector const &v, set<int> const &b)
5
FieldVector ret(v.getField(),b.size());
7
for(set<int>::const_iterator i=b.begin();i!=b.end();i++,I++)
14
FieldMatrix FieldLP::submatrix(FieldMatrix const &m, set<int> const &b)
16
FieldMatrix ret(m.getField(),b.size(),m.getWidth());
18
for(set<int>::const_iterator i=b.begin();i!=b.end();i++,I++)
24
FieldVector FieldLP::edgeDirection(int i)const
26
set<int> basis2=basis;
27
assert(basis2.count(i));
29
FieldMatrix A2=submatrix(A,basis2);
30
FieldMatrix ker=A2.reduceAndComputeKernel();
31
assert(ker.getHeight()==1);
33
if(dot(A[i],e).sign()<0)return e;
34
return theField.zHomomorphism(-1)*e;
37
bool FieldLP::isImprovingDirection(int i)const
39
return dot(edgeDirection(i),w).sign()>0;
42
FieldElement FieldLP::improvement(int i, int &newBasisMember)const
44
FieldVector e=edgeDirection(i);
45
FieldElement ew=dot(e,w);
46
FieldElement ret(theField);
49
for(int s=0;s<A.getHeight();s++)//This is _the_ line where an anticycling rule is implemented
50
// for(int s=A.getHeight()-1;s>=0;s--)//This is _the_ line where an anticycling rule is implemented
52
FieldElement denominator=dot(A[s],e);
53
if(denominator.sign()>0)
55
FieldElement imp=(b[s]-dot(A[s],x))*denominator.inverse()*ew;
56
if(first){ret=imp;newBasisMember=s;first=false;}
57
if((imp-ret).sign()<=0){newBasisMember=s;ret=imp;}
65
FieldElement impBest(theField);
67
int bestNewElement=-1;
68
for(set<int>::const_iterator i=basis.begin();i!=basis.end();i++)
70
// AsciiPrinter P(Stderr);
71
// edgeDirection(*i).print(P);
72
if(isImprovingDirection(*i))
74
//fprintf(Stderr,"IMPROVING DIRECTION\n");
76
FieldElement imp=improvement(*i,newBasisElement);
77
//P.printFieldElement(imp);
79
if(newBasisElement==-1)return -1; //UNBOUNDED
80
if((imp-impBest).sign()>=0)//needed for perturbation
84
bestNewElement=newBasisElement;
91
set<int> basis2=basis;
92
//fprintf(Stderr,"REMOVING %i INSERTING %i\n",bestIndex,bestNewElement);
93
basis2.erase(bestIndex);
94
basis2.insert(bestNewElement);
95
setCurrentBasis(basis2);
99
FieldLP::FieldLP(FieldMatrix const &A_, FieldVector const &b_):
102
theField(A_.getField()),
104
w(A.getField(),A_.getWidth())
106
// if(A.getHeight()!=b.size())fprintf(Stderr,"%i %i",A.getHeight(),b.size());
107
assert(A.getHeight()==b.size());
111
void FieldLP::setObjectiveFunction(FieldVector const &w_)
114
assert(A.getWidth()==w.size());
118
FieldVector FieldLP::basisToPoint(set<int> const &basis)const
120
AsciiPrinter P(Stdout);
121
// FieldMatrix AT=A.transposed();
122
// AT.printMatrix(P);
123
FieldMatrix A2(A.getField(),basis.size(),A.getWidth());
124
FieldVector b2(A.getField(),basis.size());
126
for(set<int>::const_iterator i=basis.begin();i!=basis.end();i++,I++)
133
FieldMatrix s=A2.solver();
134
//fprintf(Stderr,"%i %i\n",s.getWidth(),b2.size()+A.getHeight());
136
//concatenation(b2,FieldVector(b2.getField(),A.getWidth())).print(P);
137
FieldVector r=s.canonicalize(concatenation(b2,FieldVector(b2.getField(),A.getWidth())));
140
assert(r.subvector(0,basis.size()).isZero());
142
return r.subvector(basis.size(),r.size());
146
void FieldLP::setCurrentBasis(set<int> const &basis_)
149
x=basisToPoint(basis);
153
void FieldLP::print(Printer &P)const
155
P.printString("LPprogram\n");
156
P.printString("A:\n");
158
P.printString("w:\n");
160
P.printString("b:\n");
162
P.printString("current basis:\n");
163
for(set<int>::const_iterator i=basis.begin();i!=basis.end();i++)P.printInteger(*i);
164
P.printString("x:\n");
168
FieldMatrix FieldLP::computeLinealitySpace()
171
return temp.reduceAndComputeKernel();
175
FieldLP FieldLP::buildLPForFeasibilityCheck()
177
assert(computeLinealitySpace().getHeight()==0);
180
FieldMatrix temp=A.flipped().transposed();//important that inequalities which do not appear in basis set are
184
while(temp.nextPivot(i,j))
186
S.insert(A.getHeight()-1-j);//perturbed furthest
187
//fprintf(Stderr,"INSERTING %i\n",A.getHeight()-1-j);
190
FieldMatrix AS=submatrix(A,S);
191
FieldMatrix ASSolver=AS.solver();
192
FieldVector xs2=ASSolver.canonicalize(concatenation(subvector(b,S),FieldVector(b.getField(),A.getWidth()))).subvector(S.size(),S.size()+A.getWidth());
196
set<int> inequalitiesWithSlack;
197
for(int i=0;i<A.getHeight();i++)
200
if((dot(A[i],xs2)-b[i]).sign()>0)
202
inequalitiesWithSlack.insert(i);
203
//fprintf(Stderr,"adding slack variable\n");
206
FieldMatrix newA=combineOnTop(
212
inequalitiesWithSlack.size()
217
inequalitiesWithSlack.size(),
218
A.getWidth()+inequalitiesWithSlack.size()
221
FieldVector newW(theField,inequalitiesWithSlack.size()+A.getWidth());
223
for(set<int>::const_iterator i=inequalitiesWithSlack.begin();i!=inequalitiesWithSlack.end();i++,I++)
225
newA[*i][I+A.getWidth()]=theField.zHomomorphism(-1);
226
// int sign=dot(A[*i],xs2).sign();
227
newA[I+A.getHeight()][I+A.getWidth()]=theField.zHomomorphism(-1);//(sign>0)?-1:1);
228
newW[I+A.getWidth()]=theField.zHomomorphism(-1);//(sign>0)?-1:1);
232
// for(int i=0;i<A.getHeight();i++)newBasis.insert(i);
233
for(set<int>::const_iterator i=S.begin();i!=S.end();i++)newBasis.insert(*i);
234
for(set<int>::const_iterator i=inequalitiesWithSlack.begin();i!=inequalitiesWithSlack.end();i++)newBasis.insert(*i);
236
FieldLP ret(newA,concatenation(b,FieldVector(theField,inequalitiesWithSlack.size())));
237
ret.setObjectiveFunction(newW);
238
ret.setCurrentBasis(newBasis);
244
bool FieldLP::findFeasibleBasis()
246
FieldLP A2=buildLPForFeasibilityCheck();
248
AsciiPrinter Q(Stdout);
256
fprintf(Stderr,status?"LP is unbounded.\n":"Optimal solution found.\n");
260
for(set<int>::const_iterator i=A2.basis.begin();i!=A2.basis.end();i++)
266
if(newBasis.size()!=A.getWidth())return false;
267
setCurrentBasis(newBasis);
272
FieldLP FieldLP::withNoLineality()
280
while(temp.nextPivot(i,j))S.insert(j);
282
// FieldMatrix(theField,A.getHeight(),S.size());
283
FieldLP ret(submatrix(A.transposed(),S).transposed(),b);
285
//fprintf(Stderr,"New height=%i New width=%i\n",ret.A.getHeight(),ret.A.getWidth());
287
// AsciiPrinter P(Stderr);
290
if(w.size())ret.setObjectiveFunction(subvector(w,S));