Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
6d492447
Kaydet (Commit)
6d492447
authored
Ock 20, 2012
tarafından
Andre Fischer
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
118160: Use CoinMP as replacement for lp_solve.
Original author: Niklas Nebel
üst
47dfa3a7
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
108 additions
and
72 deletions
+108
-72
makefile.mk
sccomp/source/solver/makefile.mk
+1
-1
solver.cxx
sccomp/source/solver/solver.cxx
+107
-71
No files found.
sccomp/source/solver/makefile.mk
Dosyayı görüntüle @
6d492447
...
@@ -52,7 +52,7 @@ SHL1STDLIBS= $(COMPHELPERLIB) \
...
@@ -52,7 +52,7 @@ SHL1STDLIBS= $(COMPHELPERLIB) \
$(CPPULIB)
\
$(CPPULIB)
\
$(SALLIB)
\
$(SALLIB)
\
$(TOOLSLIB)
\
$(TOOLSLIB)
\
$(LPSOLVELIB)
CoinMP.lib
SHL1DEPN
=
makefile.mk
SHL1DEPN
=
makefile.mk
SHL1DEF
=
$(MISC)$/$(SHL1TARGET)
.def
SHL1DEF
=
$(MISC)$/$(SHL1TARGET)
.def
...
...
sccomp/source/solver/solver.cxx
Dosyayı görüntüle @
6d492447
...
@@ -21,12 +21,7 @@
...
@@ -21,12 +21,7 @@
#undef LANGUAGE_NONE
#include <coinmp/CoinMP.h>
#define WINAPI __stdcall
#define LoadInverseLib FALSE
#define LoadLanguageLib FALSE
#include <lpsolve/lp_lib.h>
#undef LANGUAGE_NONE
#include "solver.hxx"
#include "solver.hxx"
#include "solver.hrc"
#include "solver.hrc"
...
@@ -310,12 +305,6 @@ void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException)
...
@@ -310,12 +305,6 @@ void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException)
maStatus
=
OUString
();
maStatus
=
OUString
();
mbSuccess
=
false
;
mbSuccess
=
false
;
if
(
mnEpsilonLevel
<
EPS_TIGHT
||
mnEpsilonLevel
>
EPS_BAGGY
)
{
maStatus
=
lcl_GetResourceString
(
RID_ERROR_EPSILONLEVEL
);
return
;
}
xModel
->
lockControllers
();
xModel
->
lockControllers
();
// collect variables in vector (?)
// collect variables in vector (?)
...
@@ -394,29 +383,32 @@ void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException)
...
@@ -394,29 +383,32 @@ void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException)
return
;
return
;
//
//
// build
lp_solve model
// build
parameter arrays for CoinMP
//
//
lprec
*
lp
=
make_lp
(
0
,
nVariables
);
if
(
!
lp
)
return
;
set_outputfile
(
lp
,
const_cast
<
char
*>
(
""
)
);
// no output
// set objective function
// set objective function
const
std
::
vector
<
double
>&
rObjCoeff
=
aCellsHash
[
maObjective
];
const
std
::
vector
<
double
>&
rObjCoeff
=
aCellsHash
[
maObjective
];
REAL
*
pObjVal
=
new
REAL
[
nVariables
+
1
];
double
*
pObjectCoeffs
=
new
double
[
nVariables
];
pObjVal
[
0
]
=
0.0
;
// ignored
for
(
nVar
=
0
;
nVar
<
nVariables
;
nVar
++
)
for
(
nVar
=
0
;
nVar
<
nVariables
;
nVar
++
)
pObjVal
[
nVar
+
1
]
=
rObjCoeff
[
nVar
+
1
];
pObjectCoeffs
[
nVar
]
=
rObjCoeff
[
nVar
+
1
];
set_obj_fn
(
lp
,
pObjVal
);
double
nObjectConst
=
rObjCoeff
[
0
];
// constant term of objective
delete
[]
pObjVal
;
set_rh
(
lp
,
0
,
rObjCoeff
[
0
]
);
// constant term of objective
// add rows
// add rows
set_add_rowmode
(
lp
,
TRUE
);
size_t
nRows
=
maConstraints
.
getLength
();
size_t
nCompSize
=
nVariables
*
nRows
;
double
*
pCompMatrix
=
new
double
[
nCompSize
];
// first collect all coefficients, row-wise
for
(
size_t
i
=
0
;
i
<
nCompSize
;
i
++
)
pCompMatrix
[
i
]
=
0.0
;
double
*
pRHS
=
new
double
[
nRows
];
char
*
pRowType
=
new
char
[
nRows
];
for
(
size_t
i
=
0
;
i
<
nRows
;
i
++
)
{
pRHS
[
i
]
=
0.0
;
pRowType
[
i
]
=
'N'
;
}
for
(
sal_Int32
nConstrPos
=
0
;
nConstrPos
<
maConstraints
.
getLength
();
++
nConstrPos
)
for
(
sal_Int32
nConstrPos
=
0
;
nConstrPos
<
maConstraints
.
getLength
();
++
nConstrPos
)
{
{
...
@@ -438,10 +430,9 @@ void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException)
...
@@ -438,10 +430,9 @@ void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException)
table
::
CellAddress
aLeftAddr
=
maConstraints
[
nConstrPos
].
Left
;
table
::
CellAddress
aLeftAddr
=
maConstraints
[
nConstrPos
].
Left
;
const
std
::
vector
<
double
>&
rLeftCoeff
=
aCellsHash
[
aLeftAddr
];
const
std
::
vector
<
double
>&
rLeftCoeff
=
aCellsHash
[
aLeftAddr
];
REAL
*
pValues
=
new
REAL
[
nVariables
+
1
];
double
*
pValues
=
&
pCompMatrix
[
nConstrPos
*
nVariables
];
pValues
[
0
]
=
0.0
;
// ignored?
for
(
nVar
=
0
;
nVar
<
nVariables
;
nVar
++
)
for
(
nVar
=
0
;
nVar
<
nVariables
;
nVar
++
)
pValues
[
nVar
+
1
]
=
rLeftCoeff
[
nVar
+
1
];
pValues
[
nVar
]
=
rLeftCoeff
[
nVar
+
1
];
// if left hand cell has a constant term, put into rhs value
// if left hand cell has a constant term, put into rhs value
double
fRightValue
=
-
rLeftCoeff
[
0
];
double
fRightValue
=
-
rLeftCoeff
[
0
];
...
@@ -451,41 +442,68 @@ void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException)
...
@@ -451,41 +442,68 @@ void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException)
const
std
::
vector
<
double
>&
rRightCoeff
=
aCellsHash
[
aRightAddr
];
const
std
::
vector
<
double
>&
rRightCoeff
=
aCellsHash
[
aRightAddr
];
// modify pValues with rhs coefficients
// modify pValues with rhs coefficients
for
(
nVar
=
0
;
nVar
<
nVariables
;
nVar
++
)
for
(
nVar
=
0
;
nVar
<
nVariables
;
nVar
++
)
pValues
[
nVar
+
1
]
-=
rRightCoeff
[
nVar
+
1
];
pValues
[
nVar
]
-=
rRightCoeff
[
nVar
+
1
];
fRightValue
+=
rRightCoeff
[
0
];
// constant term
fRightValue
+=
rRightCoeff
[
0
];
// constant term
}
}
else
else
fRightValue
+=
fDirectValue
;
fRightValue
+=
fDirectValue
;
int
nConstrType
=
LE
;
switch
(
eOp
)
switch
(
eOp
)
{
{
case
sheet
:
:
SolverConstraintOperator_LESS_EQUAL
:
nConstrType
=
LE
;
break
;
case
sheet
:
:
SolverConstraintOperator_LESS_EQUAL
:
pRowType
[
nConstrPos
]
=
'L'
;
break
;
case
sheet
:
:
SolverConstraintOperator_GREATER_EQUAL
:
nConstrType
=
GE
;
break
;
case
sheet
:
:
SolverConstraintOperator_GREATER_EQUAL
:
pRowType
[
nConstrPos
]
=
'G'
;
break
;
case
sheet
:
:
SolverConstraintOperator_EQUAL
:
nConstrType
=
EQ
;
break
;
case
sheet
:
:
SolverConstraintOperator_EQUAL
:
pRowType
[
nConstrPos
]
=
'E'
;
break
;
default
:
default
:
OSL_ENSURE
(
false
,
"unexpected enum type"
);
OSL_ENSURE
(
false
,
"unexpected enum type"
);
}
}
add_constraint
(
lp
,
pValues
,
nConstrType
,
fRightValue
);
pRHS
[
nConstrPos
]
=
fRightValue
;
delete
[]
pValues
;
}
}
}
}
set_add_rowmode
(
lp
,
FALSE
);
// Find non-zero coefficients, column-wise
int
*
pMatrixBegin
=
new
int
[
nVariables
+
1
];
int
*
pMatrixCount
=
new
int
[
nVariables
];
double
*
pMatrix
=
new
double
[
nCompSize
];
// not always completely used
int
*
pMatrixIndex
=
new
int
[
nCompSize
];
int
nMatrixPos
=
0
;
for
(
nVar
=
0
;
nVar
<
nVariables
;
nVar
++
)
{
int
nBegin
=
nMatrixPos
;
for
(
size_t
nRow
=
0
;
nRow
<
nRows
;
nRow
++
)
{
double
fCoeff
=
pCompMatrix
[
nRow
*
nVariables
+
nVar
];
// row-wise
if
(
fCoeff
!=
0.0
)
{
pMatrix
[
nMatrixPos
]
=
fCoeff
;
pMatrixIndex
[
nMatrixPos
]
=
nRow
;
++
nMatrixPos
;
}
}
pMatrixBegin
[
nVar
]
=
nBegin
;
pMatrixCount
[
nVar
]
=
nMatrixPos
-
nBegin
;
}
pMatrixBegin
[
nVariables
]
=
nMatrixPos
;
delete
[]
pCompMatrix
;
pCompMatrix
=
NULL
;
// apply settings to all variables
// apply settings to all variables
double
*
pLowerBounds
=
new
double
[
nVariables
];
double
*
pUpperBounds
=
new
double
[
nVariables
];
for
(
nVar
=
0
;
nVar
<
nVariables
;
nVar
++
)
for
(
nVar
=
0
;
nVar
<
nVariables
;
nVar
++
)
{
{
if
(
!
mbNonNegative
)
pLowerBounds
[
nVar
]
=
mbNonNegative
?
0.0
:
-
DBL_MAX
;
set_unbounded
(
lp
,
nVar
+
1
);
// allow negative (default is non-negative)
pUpperBounds
[
nVar
]
=
DBL_MAX
;
//! collect bounds from constraints?
if
(
mbInteger
)
// bounds could possibly be further restricted from single-cell constraints
set_int
(
lp
,
nVar
+
1
,
TRUE
);
}
}
char
*
pColType
=
new
char
[
nVariables
];
for
(
nVar
=
0
;
nVar
<
nVariables
;
nVar
++
)
pColType
[
nVar
]
=
mbInteger
?
'I'
:
'C'
;
// apply single-var integer constraints
// apply single-var integer constraints
for
(
sal_Int32
nConstrPos
=
0
;
nConstrPos
<
maConstraints
.
getLength
();
++
nConstrPos
)
for
(
sal_Int32
nConstrPos
=
0
;
nConstrPos
<
maConstraints
.
getLength
();
++
nConstrPos
)
...
@@ -500,51 +518,69 @@ void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException)
...
@@ -500,51 +518,69 @@ void SAL_CALL SolverComponent::solve() throw(uno::RuntimeException)
if
(
AddressEqual
(
aVariableCells
[
nVar
],
aLeftAddr
)
)
if
(
AddressEqual
(
aVariableCells
[
nVar
],
aLeftAddr
)
)
{
{
if
(
eOp
==
sheet
::
SolverConstraintOperator_INTEGER
)
if
(
eOp
==
sheet
::
SolverConstraintOperator_INTEGER
)
set_int
(
lp
,
nVar
+
1
,
TRUE
)
;
pColType
[
nVar
]
=
'I'
;
else
else
set_binary
(
lp
,
nVar
+
1
,
TRUE
);
{
pColType
[
nVar
]
=
'B'
;
pLowerBounds
[
nVar
]
=
0.0
;
pUpperBounds
[
nVar
]
=
1.0
;
}
}
}
}
}
}
}
if
(
mbMaximize
)
int
nObjectSense
=
mbMaximize
?
SOLV_OBJSENS_MAX
:
SOLV_OBJSENS_MIN
;
set_maxim
(
lp
);
else
HPROB
hProb
=
CoinCreateProblem
(
""
);
set_minim
(
lp
);
int
nResult
=
CoinLoadProblem
(
hProb
,
nVariables
,
nRows
,
nMatrixPos
,
0
,
nObjectSense
,
nObjectConst
,
pObjectCoeffs
,
pLowerBounds
,
pUpperBounds
,
pRowType
,
pRHS
,
NULL
,
pMatrixBegin
,
pMatrixCount
,
pMatrixIndex
,
pMatrix
,
NULL
,
NULL
,
NULL
);
nResult
=
CoinLoadInteger
(
hProb
,
pColType
);
if
(
!
mbLimitBBDepth
)
delete
[]
pColType
;
set_bb_depthlimit
(
lp
,
0
);
delete
[]
pMatrixIndex
;
delete
[]
pMatrix
;
delete
[]
pMatrixCount
;
delete
[]
pMatrixBegin
;
delete
[]
pUpperBounds
;
delete
[]
pLowerBounds
;
delete
[]
pRowType
;
delete
[]
pRHS
;
delete
[]
pObjectCoeffs
;
set_epslevel
(
lp
,
mnEpsilonLevel
);
CoinSetRealOption
(
hProb
,
COIN_REAL_MAXSECONDS
,
mnTimeout
);
set_timeout
(
lp
,
mnTimeout
);
CoinSetRealOption
(
hProb
,
COIN_REAL_MIPMAXSEC
,
mnTimeout
);
// TODO: handle (or remove) settings: epsilon, B&B depth
// solve model
// solve model
int
nResult
=
::
solve
(
lp
);
nResult
=
CoinCheckProblem
(
hProb
);
nResult
=
CoinOptimizeProblem
(
hProb
,
0
);
mbSuccess
=
(
nResult
==
OPTIMAL
);
mbSuccess
=
(
nResult
==
SOLV_CALL_SUCCESS
);
if
(
mbSuccess
)
if
(
mbSuccess
)
{
{
// get solution
// get solution
maSolution
.
realloc
(
nVariables
);
maSolution
.
realloc
(
nVariables
);
CoinGetSolutionValues
(
hProb
,
maSolution
.
getArray
(),
NULL
,
NULL
,
NULL
);
REAL
*
pResultVar
=
NULL
;
mfResultValue
=
CoinGetObjectValue
(
hProb
);
get_ptr_variables
(
lp
,
&
pResultVar
);
for
(
nVar
=
0
;
nVar
<
nVariables
;
nVar
++
)
maSolution
[
nVar
]
=
pResultVar
[
nVar
];
mfResultValue
=
get_objective
(
lp
);
}
}
else
if
(
nResult
==
INFEASIBLE
)
else
maStatus
=
lcl_GetResourceString
(
RID_ERROR_INFEASIBLE
);
{
else
if
(
nResult
==
UNBOUNDED
)
int
nSolutionStatus
=
CoinGetSolutionStatus
(
hProb
);
maStatus
=
lcl_GetResourceString
(
RID_ERROR_UNBOUNDED
);
if
(
nSolutionStatus
==
1
)
else
if
(
nResult
==
TIMEOUT
||
nResult
==
SUBOPTIMAL
)
maStatus
=
lcl_GetResourceString
(
RID_ERROR_INFEASIBLE
);
maStatus
=
lcl_GetResourceString
(
RID_ERROR_TIMEOUT
);
else
if
(
nSolutionStatus
==
2
)
// SUBOPTIMAL is assumed to be caused by a timeout, and reported as an error
maStatus
=
lcl_GetResourceString
(
RID_ERROR_UNBOUNDED
);
// TODO: detect timeout condition and report as RID_ERROR_TIMEOUT
delete_lp
(
lp
);
// (currently reported as infeasible)
}
CoinUnloadProblem
(
hProb
);
}
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment