Пример #1
0
        /*************************************************************************
        Having feasible current point XC and possibly infeasible candidate   point
        XN,  this  function  performs  longest  step  from  XC to XN which retains
        feasibility. In case XN is found to be infeasible, at least one constraint
        is activated.

        For example, if we have:
          XC=0.5
          XN=1.2
          x>=0, x<=1
        then this function will move us to X=1.0 and activate constraint "x<=1".

        INPUT PARAMETERS:
            State   -   MinQP state.
            XC      -   current point, must be feasible with respect to
                        all constraints
            XN      -   candidate point, can be infeasible with respect to some
                        constraints. Must be located in the subspace of current
                        active set, i.e. it is feasible with respect to already
                        active constraints.
            Buf     -   temporary buffer, automatically resized if needed

        OUTPUT PARAMETERS:
            State   -   this function changes following fields of State:
                        * State.ActiveSet
                        * State.ActiveC     -   active linear constraints
            XC      -   new position

        RESULT:
            >0, in case at least one inactive non-candidate constraint was activated
            =0, in case only "candidate" constraints were activated
            <0, in case no constraints were activated by the step


          -- ALGLIB --
             Copyright 29.02.2012 by Bochkanov Sergey
        *************************************************************************/
        private static int boundedstepandactivation(sactivesets.sactiveset sas,
            double[] xn,
            int n,
            ref double[] buf)
        {
            int result = 0;
            double stpmax = 0;
            int cidx = 0;
            double cval = 0;
            bool needact = new bool();
            double v = 0;
            int i_ = 0;

            apserv.rvectorsetlengthatleast(ref buf, n);
            for(i_=0; i_<=n-1;i_++)
            {
                buf[i_] = xn[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                buf[i_] = buf[i_] - sas.xc[i_];
            }
            sactivesets.sasexploredirection(sas, buf, ref stpmax, ref cidx, ref cval);
            needact = (double)(stpmax)<=(double)(1);
            v = Math.Min(stpmax, 1.0);
            for(i_=0; i_<=n-1;i_++)
            {
                buf[i_] = v*buf[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                buf[i_] = buf[i_] + sas.xc[i_];
            }
            result = sactivesets.sasmoveto(sas, buf, needact, cidx, cval);
            return result;
        }
Пример #2
0
        /*************************************************************************
        Optimum of A subject to:
        a) active boundary constraints (given by ActiveSet[] and corresponding
           elements of XC)
        b) active linear constraints (given by C, R, LagrangeC)

        INPUT PARAMETERS:
            A       -   main quadratic term of the model;
                        although structure may  store  linear  and  rank-K  terms,
                        these terms are ignored and rewritten  by  this  function.
            ANorm   -   estimate of ||A|| (2-norm is used)
            B       -   array[N], linear term of the model
            XN      -   possibly preallocated buffer
            Tmp     -   temporary buffer (automatically resized)
            Tmp1    -   temporary buffer (automatically resized)

        OUTPUT PARAMETERS:
            A       -   modified quadratic model (this function changes rank-K
                        term and linear term of the model)
            LagrangeC-  current estimate of the Lagrange coefficients
            XN      -   solution

        RESULT:
            True on success, False on failure (non-SPD model)

          -- ALGLIB --
             Copyright 20.06.2012 by Bochkanov Sergey
        *************************************************************************/
        private static bool constrainedoptimum(sactivesets.sactiveset sas,
            cqmodels.convexquadraticmodel a,
            double anorm,
            double[] b,
            ref double[] xn,
            int n,
            ref double[] tmp,
            ref bool[] tmpb,
            ref double[] lagrangec)
        {
            bool result = new bool();
            int itidx = 0;
            int i = 0;
            double v = 0;
            double feaserrold = 0;
            double feaserrnew = 0;
            double theta = 0;
            int i_ = 0;

            
            //
            // Rebuild basis accroding to current active set.
            // We call SASRebuildBasis() to make sure that fields of SAS
            // store up to date values.
            //
            sactivesets.sasrebuildbasis(sas);
            
            //
            // Allocate temporaries.
            //
            apserv.rvectorsetlengthatleast(ref tmp, Math.Max(n, sas.basissize));
            apserv.bvectorsetlengthatleast(ref tmpb, n);
            apserv.rvectorsetlengthatleast(ref lagrangec, sas.basissize);
            
            //
            // Prepare model
            //
            for(i=0; i<=sas.basissize-1; i++)
            {
                tmp[i] = sas.pbasis[i,n];
            }
            theta = 100.0*anorm;
            for(i=0; i<=n-1; i++)
            {
                if( sas.activeset[i]>0 )
                {
                    tmpb[i] = true;
                }
                else
                {
                    tmpb[i] = false;
                }
            }
            cqmodels.cqmsetactiveset(a, sas.xc, tmpb);
            cqmodels.cqmsetq(a, sas.pbasis, tmp, sas.basissize, theta);
            
            //
            // Iterate until optimal values of Lagrange multipliers are found
            //
            for(i=0; i<=sas.basissize-1; i++)
            {
                lagrangec[i] = 0;
            }
            feaserrnew = math.maxrealnumber;
            result = true;
            for(itidx=1; itidx<=maxlagrangeits; itidx++)
            {
                
                //
                // Generate right part B using linear term and current
                // estimate of the Lagrange multipliers.
                //
                for(i_=0; i_<=n-1;i_++)
                {
                    tmp[i_] = b[i_];
                }
                for(i=0; i<=sas.basissize-1; i++)
                {
                    v = lagrangec[i];
                    for(i_=0; i_<=n-1;i_++)
                    {
                        tmp[i_] = tmp[i_] - v*sas.pbasis[i,i_];
                    }
                }
                cqmodels.cqmsetb(a, tmp);
                
                //
                // Solve
                //
                result = cqmodels.cqmconstrainedoptimum(a, ref xn);
                if( !result )
                {
                    return result;
                }
                
                //
                // Compare feasibility errors.
                // Terminate if error decreased too slowly.
                //
                feaserrold = feaserrnew;
                feaserrnew = 0;
                for(i=0; i<=sas.basissize-1; i++)
                {
                    v = 0.0;
                    for(i_=0; i_<=n-1;i_++)
                    {
                        v += sas.pbasis[i,i_]*xn[i_];
                    }
                    feaserrnew = feaserrnew+math.sqr(v-sas.pbasis[i,n]);
                }
                feaserrnew = Math.Sqrt(feaserrnew);
                if( (double)(feaserrnew)>=(double)(0.2*feaserrold) )
                {
                    break;
                }
                
                //
                // Update Lagrange multipliers
                //
                for(i=0; i<=sas.basissize-1; i++)
                {
                    v = 0.0;
                    for(i_=0; i_<=n-1;i_++)
                    {
                        v += sas.pbasis[i,i_]*xn[i_];
                    }
                    lagrangec[i] = lagrangec[i]-theta*(v-sas.pbasis[i,n]);
                }
            }
            return result;
        }
Пример #3
0
        /*************************************************************************
        This function accepts quadratic model of the form

            f(x) = 0.5*x'*A*x + b'*x + penaltyfactor*0.5*(C*x-b)'*(C*x-b)
            
        and list of possible steps along direction D. It chooses  best  step  (one
        which achieves minimum value of the target  function)  and  moves  current
        point (given by SAS object) to the new location. Step is  bounded  subject
        to boundary constraints.

        Candidate steps are divided into two groups:
        * "default" step, which is always performed when no candidate steps LONGER
          THAN THE DEFAULT  ONE  is  given.  This  candidate  MUST  reduce  target
          function value; it is  responsibility  of  caller  to   provide  default
          candidate which reduces target function.
        * "additional candidates", which may be shorter or longer than the default
          step. Candidates which are shorter that the default  step  are  ignored;
          candidates which are longer than the "default" step are tested.
          
        The idea is that we ALWAYS try "default" step, and it is responsibility of
        the caller to provide us with something which is worth trying.  This  step
        may activate some constraint - that's why we  stopped  at  "default"  step
        size. However, we may also try longer steps which may activate  additional
        constraints and further reduce function value.

        INPUT PARAMETERS:
            SState  -   structure which stores model
            SAS     -   active set structure which stores current point in SAS.XC
            D       -   direction for step
            Stp     -   step length for "default" candidate
            NeedAct -   whether   default  candidate  activates  some  constraint;
                        if NeedAct  is True,  constraint  given  by  CIdc/CVal  is
                        GUARANTEED to be activated in the final point.
            CIdx    -   if NeedAct is True, stores index of the constraint to activate
            CVal    -   if NeedAct is True, stores constrained value;
                        SAS.XC[CIdx] is forced to be equal to CVal.
            AddSteps-   array[AddStepsCnt] of additional steps:
                        * AddSteps[]<=Stp are ignored
                        * AddSteps[]>Stp are tried
            Activated-  possibly preallocated buffer; previously allocated memory
                        will be reused.
            Tmp0    -  possibly preallocated buffer; previously allocated memory
                        will be reused.
            
        OUTPUT PARAMETERS:
            SAS     -   SAS.XC is set to new point;  if  there  was  a  constraint
                        specified  by  NeedAct/CIdx/CVal,  it  will  be  activated
                        (other constraints may be activated too, but this  one  is
                        guaranteed to be active in the final point).
            Activated-  elements of this array are set to True, if I-th constraint
                        as inactive at previous point, but become  active  in  the
                        new one.
                        Situations when we deactivate xi>=0 and activate xi<=1 are
                        considered as activation of previously inactive constraint
                    
          -- ALGLIB --
             Copyright 14.05.2014 by Bochkanov Sergey
        *************************************************************************/
        private static void findbeststepandmove(qqpbuffers sstate,
            sactivesets.sactiveset sas,
            double[] d,
            double stp,
            bool needact,
            int cidx,
            double cval,
            double[] addsteps,
            int addstepscnt,
            ref bool[] activated,
            ref double[] tmp0)
        {
            int n = 0;
            int i = 0;
            int k = 0;
            double v = 0;
            double stpbest = 0;
            double fbest = 0;
            double fcand = 0;

            n = sstate.n;
            apserv.rvectorsetlengthatleast(ref tmp0, n);
            apserv.bvectorsetlengthatleast(ref activated, n);
            
            //
            // Calculate initial step, store to Tmp0
            //
            // NOTE: Tmp0 is guaranteed to be feasible w.r.t. boundary constraints
            //
            for(i=0; i<=n-1; i++)
            {
                v = sas.xc[i]+stp*d[i];
                if( sstate.havebndl[i] && (double)(v)<(double)(sstate.bndl[i]) )
                {
                    v = sstate.bndl[i];
                }
                if( sstate.havebndu[i] && (double)(v)>(double)(sstate.bndu[i]) )
                {
                    v = sstate.bndu[i];
                }
                tmp0[i] = v;
            }
            if( needact )
            {
                tmp0[cidx] = cval;
            }
            
            //
            // Try additional steps, if AddStepsCnt>0
            //
            if( addstepscnt>0 )
            {
                
                //
                // Find best step
                //
                stpbest = stp;
                fbest = projectedtargetfunction(sstate, sas.xc, d, stpbest, ref tmp0);
                for(k=0; k<=addstepscnt-1; k++)
                {
                    if( (double)(addsteps[k])>(double)(stp) )
                    {
                        fcand = projectedtargetfunction(sstate, sas.xc, d, addsteps[k], ref tmp0);
                        if( (double)(fcand)<(double)(fbest) )
                        {
                            fbest = fcand;
                            stpbest = addsteps[k];
                        }
                    }
                }
                
                //
                // Prepare best step
                //
                // NOTE: because only AddSteps[]>Stp were checked,
                //       this step will activate constraint CIdx.
                //
                for(i=0; i<=n-1; i++)
                {
                    v = sas.xc[i]+stpbest*d[i];
                    if( sstate.havebndl[i] && (double)(v)<(double)(sstate.bndl[i]) )
                    {
                        v = sstate.bndl[i];
                    }
                    if( sstate.havebndu[i] && (double)(v)>(double)(sstate.bndu[i]) )
                    {
                        v = sstate.bndu[i];
                    }
                    tmp0[i] = v;
                }
                if( needact )
                {
                    tmp0[cidx] = cval;
                }
            }
            
            //
            // Fill Activated array by information about activated constraints.
            // Perform step
            //
            for(i=0; i<=n-1; i++)
            {
                activated[i] = false;
                v = tmp0[i];
                if( (double)(v)==(double)(sas.xc[i]) )
                {
                    continue;
                }
                if( sstate.havebndl[i] && (double)(v)==(double)(sstate.bndl[i]) )
                {
                    activated[i] = true;
                }
                if( sstate.havebndu[i] && (double)(v)==(double)(sstate.bndu[i]) )
                {
                    activated[i] = true;
                }
            }
            sactivesets.sasmoveto(sas, tmp0, needact, cidx, cval);
        }