1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the class library                   */
4    	/*       SoPlex --- the Sequential object-oriented simPlex.                  */
5    	/*                                                                           */
6    	/*  Copyright (c) 1996-2023 Zuse Institute Berlin (ZIB)                      */
7    	/*                                                                           */
8    	/*  Licensed under the Apache License, Version 2.0 (the "License");          */
9    	/*  you may not use this file except in compliance with the License.         */
10   	/*  You may obtain a copy of the License at                                  */
11   	/*                                                                           */
12   	/*      http://www.apache.org/licenses/LICENSE-2.0                           */
13   	/*                                                                           */
14   	/*  Unless required by applicable law or agreed to in writing, software      */
15   	/*  distributed under the License is distributed on an "AS IS" BASIS,        */
16   	/*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17   	/*  See the License for the specific language governing permissions and      */
18   	/*  limitations under the License.                                           */
19   	/*                                                                           */
20   	/*  You should have received a copy of the Apache-2.0 license                */
21   	/*  along with SoPlex; see the file LICENSE. If not email to soplex@zib.de.  */
22   	/*                                                                           */
23   	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24   	
25   	
26   	/**@file  spxweightst.h
27   	 * @brief Weighted start basis.
28   	 */
29   	#ifndef _SPXWEIGHTST_H_
30   	#define _SPXWEIGHTST_H_
31   	
32   	
33   	#include <assert.h>
34   	
35   	#include "soplex/spxdefines.h"
36   	#include "soplex/spxstarter.h"
37   	#include "soplex/dataarray.h"
38   	
39   	namespace soplex
40   	{
41   	
42   	/**@brief   Weighted start basis.
43   	   @ingroup Algo
44   	
45   	   Class SPxWeightST is an implementation of a SPxStarter for generating a
46   	   Simplex starting basis. Using method #setupWeights() it sets up arrays
47   	   #weight and #coWeight, or equivalently #rowWeight and #colWeight.
48   	   (#rowWeight and #colWeight are just pointers initialized to #weight and
49   	   #coWeight according to the representation of SoPlex \p base passed to
50   	   method #generate().)
51   	
52   	   The weight values are then used to setup a starting basis for the LP:
53   	   vectors with low values are likely to become dual (i.e. basic for a column
54   	   basis) and such with high values are likely to become primal (i.e. nonbasic
55   	   for a column basis).
56   	
57   	   However, if a variable having an upper and lower bound is to become primal,
58   	   there is still a choice for setting it either to its upper or lower bound.
59   	   Members #rowRight and #colUp are used to determine where to set a primal
60   	   variable. If #rowRight[i] is set to a nonzero value, the right-hand side
61   	   inequality is set tightly for the \p i 'th to become primal. Analogously, If
62   	   #colUp[j] is nonzero, the \p j 'th variable will be set to its upper bound
63   	   if it becomes primal.
64   	*/
65   	template <class R>
66   	class SPxWeightST : public SPxStarter<R>
67   	{
68   	private:
69   	
70   	   //-----------------------------------
71   	   /**@name Private data */
72   	   ///@{
73   	   ///
74   	   DataArray < int > forbidden;
75   	   ///
76   	   Array < R >* weight;
77   	   ///
78   	   Array < R >* coWeight;
79   	   ///@}
80   	
81   	   //-----------------------------------
82   	   /**@name Private helpers */
83   	   ///@{
84   	   ///
85   	   void setPrimalStatus(typename SPxBasisBase<R>::Desc&, const SPxSolverBase<R>&, const SPxId&);
86   	   ///@}
87   	
88   	protected:
89   	
90   	   //-----------------------------------
91   	   /**@name Protected data */
92   	   ///@{
93   	   /// weight value for LP rows.
94   	   Array < R > rowWeight;
95   	   /// weight value for LP columns.
96   	   Array < R > colWeight;
97   	   /// set variable to rhs?.
98   	   DataArray < bool > rowRight;
99   	   /// set primal variable to upper bound.
100  	   DataArray < bool > colUp;
101  	   ///@}
102  	
103  	   //-----------------------------------
104  	   /**@name Protected helpers */
105  	   ///@{
106  	   /// sets up variable weights.
107  	   /** This method is called in order to setup the weights for all
108  	       variables. It has been declared \c virtual in order to allow for
109  	       derived classes to compute other weight values.
110  	   */
111  	   virtual void setupWeights(SPxSolverBase<R>& base);
112  	   ///@}
113  	
114  	public:
115  	
116  	   //-----------------------------------
117  	   /**@name Construction / destruction */
118  	   ///@{
119  	   /// default constructor.
120  	   SPxWeightST()
121  	      : SPxStarter<R>("Weight")
122  	   {
123  	      weight = 0;
124  	      coWeight = 0;
125  	      assert(isConsistent());
126  	   }
127  	   /// copy constructor
128  	   SPxWeightST(const SPxWeightST& old)
129  	      : SPxStarter<R>(old)
130  	      , forbidden(old.forbidden)
131  	      , rowWeight(old.rowWeight)
132  	      , colWeight(old.colWeight)
133  	      , rowRight(old.rowRight)
134  	      , colUp(old.colUp)
135  	   {
136  	      if(old.weight == &old.colWeight)
137  	      {
138  	         weight   = &colWeight;
139  	         coWeight = &rowWeight;
140  	      }
141  	      else if(old.weight == &old.rowWeight)
142  	      {
143  	         weight   = &rowWeight;
144  	         coWeight = &colWeight;
145  	      }
146  	      else  // old.weight and old.coWeight are not set correctly, do nothing.
147  	      {
148  	         weight = 0;
149  	         coWeight = 0;
150  	      }
151  	
152  	      assert(isConsistent());
153  	   }
154  	   /// assignment operator
155  	   SPxWeightST& operator=(const SPxWeightST& rhs)
156  	   {
157  	      if(this != &rhs)
158  	      {
159  	         SPxStarter<R>::operator=(rhs);
160  	         forbidden = rhs.forbidden;
161  	         rowWeight = rhs.rowWeight;
162  	         colWeight = rhs.colWeight;
163  	         rowRight = rhs.rowRight;
164  	         colUp = rhs.colUp;
165  	
166  	         if(rhs.weight == &rhs.colWeight)
167  	         {
168  	            weight   = &colWeight;
169  	            coWeight = &rowWeight;
170  	         }
171  	         else if(rhs.weight == &rhs.rowWeight)
172  	         {
173  	            weight   = &rowWeight;
174  	            coWeight = &colWeight;
175  	         }
176  	         else  // old.weight and old.coWeight are not set correctly, do nothing.
177  	         {}
178  	
179  	         assert(isConsistent());
180  	      }
181  	
182  	      return *this;
183  	   }
184  	   /// destructor.
185  	   virtual ~SPxWeightST()
186  	   {
187  	      weight   = 0;
188  	      coWeight = 0;
189  	   }
190  	   /// clone function for polymorphism
191  	   inline virtual SPxStarter<R>* clone() const
192  	   {
193  	      return new SPxWeightST(*this);
194  	   }
195  	   ///@}
196  	
197  	   //-----------------------------------
198  	   /**@name Generation of a start basis */
199  	   ///@{
200  	   /// generates start basis for loaded basis.
201  	   void generate(SPxSolverBase<R>& base);
202  	   ///@}
203  	
204  	   //-----------------------------------
205  	   /**@name Debugging */
206  	   ///@{
207  	   /// consistency check.
208  	   virtual bool isConsistent() const;
209  	   ///@}
210  	
211  	};
212  	
213  	} // namespace soplex
214  	
215  	// For general templated functions
216  	#include "spxweightst.hpp"
217  	
218  	#endif // _SPXWEIGHTST_H_
219