示例#1
0
        private double BalancedEstCompInteriorLength_Basic(CRegion crg, CRegion lscrg, int intEstSteps)
        {
            // if lscrg.GetCphCount() <= 2, the domain only have two polygons
            // A value will be divided by (lscrg.GetCphCount() - 2). To avoid being divided by 0, we directly return 0.
            if (lscrg.GetCphCount() <= 2 || crg.GetCphCount() <= 1)
            {
                return(0);
            }

            int intOverestimationCount = Math.Min(intEstSteps, crg.GetCphCount() - 2);

            var    EstimateLt = EstimateInteriorLength(crg, lscrg);
            double dblSum     = crg.dblInteriorSegLength / (crg.GetCphCount() - 1); //n-s= crg.GetCphCount()-1

            for (int i = 0; i < intOverestimationCount; i++)
            {
                dblSum += crg.dblInteriorSegLength / (crg.GetCphCount() - (i + 2));  //overestimation; n-s= crg.GetCphCount()-(i+2)
            }
            for (int i = 0; i < EstimateLt.Count - intOverestimationCount; i++)
            {
                dblSum += (EstimateLt[i] / (i + 1));  //normal estimation; n-s = i+1= crg.GetCphCount()-1
            }

            double dblEstComp = dblSum / (lscrg.dblInteriorSegLength / (lscrg.GetCphCount() - 1)) / (lscrg.GetCphCount() - 2);

            if (dblEstComp == 0)
            {
                throw new ArgumentException("impossible!");
            }

            return(dblEstComp);
        }
示例#2
0
        /// <summary>
        /// from time t to n-1
        /// </summary>
        /// <param name="crg"></param>
        /// <returns></returns>
        private IEnumerable <double> EstimateMinComp_EdgeNumber(CRegion crg, CRegion lscrg)
        {
            var intEdgeCountSS = new SortedSet <int>(new CIntCompare());

            foreach (var pCorrCphs in crg.AdjCorrCphsSD.Keys)
            {
                intEdgeCountSS.Add(pCorrCphs.intSharedCEdgeCount);
            }

            IEnumerator <int> intEdgeCountSSEt = intEdgeCountSS.GetEnumerator();
            int intEdgeCountAtmost             = crg.intExteriorEdgeCount + 2 * crg.intInteriorEdgeCount;
            int intEstCount = crg.GetCphCount();

            while (intEstCount > 1)
            {
                intEdgeCountSSEt.MoveNext();

                //if intEstCount == lscrg.GetCphCount(), we are estimating from the start map (t==1)
                //we define that the estimation value of the start map is 0, therefore we skip intEstCount == lscrg.GetCphCount()
                if (intEstCount < lscrg.GetCphCount())
                {
                    int intAverageEdgeCount = Convert.ToInt32(
                        Math.Floor(Convert.ToDouble(intEdgeCountAtmost) / Convert.ToDouble(intEstCount)));
                    yield return(CGeoFunc.CalCompRegularPolygon(intAverageEdgeCount));
                }

                intEdgeCountAtmost -= (2 * intEdgeCountSSEt.Current);
                intEstCount--;
            }
        }
示例#3
0
        public static int CmpCrg_CphGIDTypeIndex(CRegion crg1, CRegion crg2)
        {
            int intResult = crg1.GetCphCount().CompareTo(crg2.GetCphCount());

            if (intResult == 0)
            {
                intResult = crg1.intSumCphGID.CompareTo(crg2.intSumCphGID);
            }

            if (intResult == 0)
            {
                intResult = crg1.intSumTypeIndex.CompareTo(crg2.intSumTypeIndex);
            }

            if (intResult == 0)
            {
                //this will compare the GID of every CPatch in the two SortedDictionary
                intResult = CCmpMethods.CmpWithSameElements(crg1.GetCphCol(), crg2.GetCphCol(), cph => cph);
            }

            if (intResult == 0)
            {
                intResult = CCmpMethods.CmpWithSameElements(crg1.GetCphTypeIndexCol(), crg2.GetCphTypeIndexCol(),
                                                            intTypeIndex => intTypeIndex);
            }
            return(intResult);
        }
示例#4
0
        /// <summary>
        /// currently doesn't work
        /// </summary>
        /// <param name="crg"></param>
        /// <param name="intTimeNum"></param>
        /// <returns></returns>
        /// <remarks>we need to improve this estimation to make sure this is an upper bound.
        /// We don't need to compute one step further because the estimation based on edge number will "never" be 0</remarks>
        ///
        private double BalancedEstMinComp_Combine(CRegion crg, CRegion lscrg, CRegion sscrg)
        {
            if (crg.GetCphCount() == 1)
            {
                return(0);
            }

            var EstEdgeNumberEt = EstimateMinComp_EdgeNumber(crg, lscrg).GetEnumerator();
            //we need to improve this estimation to make sure this is an upper bound
            var EstEdgeLengthEt = EstimateMinComp_EdgeLength(crg, lscrg).GetEnumerator();

            double dblSumCompValue = 0;

            while (EstEdgeNumberEt.MoveNext() && EstEdgeLengthEt.MoveNext())
            {
                if (EstEdgeNumberEt.Current < EstEdgeLengthEt.Current)
                {
                    CRegion._lngEstCountEdgeNumber++;
                }
                else if (EstEdgeNumberEt.Current > EstEdgeLengthEt.Current)
                {
                    CRegion._lngEstCountEdgeLength++;
                }
                else
                {
                    CRegion._lngEstCountEqual++;
                }

                dblSumCompValue += (1 - Math.Min(EstEdgeNumberEt.Current, EstEdgeLengthEt.Current));
            }

            return(dblSumCompValue / (lscrg.GetCphCount() - 1));
        }
示例#5
0
        private double BalancedEstMinComp_EdgeLength(CRegion crg, CRegion lscrg, CRegion sscrg)
        {
            if (crg.GetCphCount() == 1)
            {
                return(0);
            }

            return(EstimatedComp_Common(EstimateMinComp_EdgeLength(crg, lscrg), crg, lscrg, sscrg));
        }
示例#6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="crg">crg.GetCphCount() > 1</param>
        /// <param name="lscrg">lscrg.GetCphCount() > 2</param>
        /// <param name="sscrg"></param>
        /// <returns></returns>
        private double BalancedEstMinComp_EdgeNumber(CRegion crg, CRegion lscrg, CRegion sscrg)
        {
            // if lscrg.GetCphCount() <= 2, the domain only have two polygons
            // A value will be divided by (lscrg.GetCphCount() - 2). To avoid being divided by 0, we directly return 0.
            if (lscrg.GetCphCount() <= 2)
            {
                return(0);
            }

            return(EstimatedComp_Common(EstimateMinComp_EdgeNumber(crg, lscrg), crg, lscrg, sscrg));
        }
示例#7
0
        /// <summary>
        /// Estimate Interior Lengths for the future steps, without current step
        /// </summary>
        /// <param name="crg"></param>
        /// <param name="lscrg"></param>
        /// <returns></returns>
        /// <remarks>from time n-1 to t+1</remarks>
        private List <double> EstimateInteriorLength(CRegion crg, CRegion lscrg)
        {
            var dblSegLengthSS = new SortedSet <double>(new CCmpDbl());

            foreach (var pCorrCphs in crg.AdjCorrCphsSD.Keys)
            {
                dblSegLengthSS.Add(pCorrCphs.dblSharedSegLength);
            }
            IEnumerator <double> dblSegLengthSSEt = dblSegLengthSS.GetEnumerator();


            int intEstCount = crg.GetCphCount();

            //if intEstCount == lscrg.GetCphCount(), we are estimating from the start map (t==1)
            //we define that the estimation value of the start map is 0, therefore we skip intEstCount == lscrg.GetCphCount()
            if (crg.GetCphCount() == lscrg.GetCphCount())
            {
                intEstCount--;
            }

            //from time n-1 to t+1
            //we compute from the last step (only one interior boundary) to the current step (many interior boundaries).
            double dblInteriorLength   = 0;
            var    dblInteriorLengthLt = new List <double>(intEstCount - 1);

            for (int i = 0; i < intEstCount - 2; i++)
            {
                dblSegLengthSSEt.MoveNext();
                dblInteriorLength += dblSegLengthSSEt.Current;

                dblInteriorLengthLt.Add(dblInteriorLength);
            }

            return(dblInteriorLengthLt);

            //for (int i = 0; i < dblInteriorLengthLt.Count; i++)
            //{
            //    yield return dblInteriorLengthLt[dblInteriorLengthLt.Count - i - 1];
            //}
        }
示例#8
0
        private void AddVirtualItem(List <List <object> > pobjDataLtLt, CRegion LSCrg, string strAreaAggregation, int intCount)
        {
            List <object> objDataLt = new List <object>(14);

            objDataLt.Add(LSCrg.ID);
            objDataLt.Add(LSCrg.GetCphCount());
            objDataLt.Add(LSCrg.GetAdjCount());
            objDataLt.Add(strAreaAggregation);
            for (int i = 4; i < intCount; i++)
            {
                objDataLt.Add(-1);
            }
            pobjDataLtLt.Add(objDataLt);
        }
示例#9
0
        private IEnumerable <double> EstimateMinComp_EdgeLength(CRegion crg, CRegion lscrg)
        {
            throw new ArgumentException("We need to update the cost functions!");

            //double dblEstComp
            var EstimateEt  = EstimateInteriorLength(crg, lscrg).GetEnumerator();
            int intEstCount = crg.GetCphCount() - 1;

            while (EstimateEt.MoveNext())
            {
                double dblEdgeLength = crg.dblExteriorSegLength + 2 * EstimateEt.Current;
                yield return(EstimateCompEdgeLengthOneCrgInstance(intEstCount--, crg.dblArea, dblEdgeLength));
            }
        }
示例#10
0
        private double EstimatedComp_Common(IEnumerable <double> EstimateEb, CRegion crg, CRegion lscrg, CRegion sscrg)
        {
            var EstimateEt = EstimateEb.GetEnumerator();

            //we include current step so that we can make the ration type/comp
            double dblSumCompValue = 0;  //for the current crg, whose dblMinComp is known

            while (EstimateEt.MoveNext())
            {
                dblSumCompValue += (1 - EstimateEt.Current);
            }

            return(dblSumCompValue / (lscrg.GetCphCount() - 2));
        }
示例#11
0
        private double BalancedEstType(CRegion crg, int intFinalTypeIndex, double[,] padblTD, int intEstSteps)
        {
            int    intOverestimationCount = Math.Min(intEstSteps, crg.GetCphCount());
            var    pCphTypeIndexEt        = crg.CphTypeIndexSD_Area_CphGID.GetEnumerator();
            double dblCostEst             = 0;

            for (int i = 0; i < intOverestimationCount; i++)
            {
                pCphTypeIndexEt.MoveNext();

                dblCostEst += pCphTypeIndexEt.Current.Key.dblArea *
                              padblTD[pCphTypeIndexEt.Current.Value, intFinalTypeIndex] * intEstSteps; //overestimation
            }

            for (int i = intOverestimationCount; i < crg.GetCphCount(); i++)
            {
                pCphTypeIndexEt.MoveNext();
                dblCostEst += pCphTypeIndexEt.Current.Key.dblArea *
                              padblTD[pCphTypeIndexEt.Current.Value, intFinalTypeIndex]; //estimation
            }

            return(dblCostEst);
        }
示例#12
0
        public static int CmpCrg_nmID(CRegion crg1, CRegion crg2)
        {
            int intResult = crg1.GetCphCount().CompareTo(crg2.GetCphCount());

            if (intResult == 0)
            {
                intResult = crg1.GetAdjCount().CompareTo(crg2.GetAdjCount());
            }

            if (intResult == 0)
            {
                intResult = crg1.ID.CompareTo(crg2.ID);
            }

            if (intResult == 0)
            {
                throw new ArgumentOutOfRangeException("this should not happen!");
            }

            return(intResult);
        }
示例#13
0
        private CRegion ComputeAccordEstSteps(CRegion LSCrg, CRegion SSCrg, string strAreaAggregation,
                                              SortedDictionary <CCorrCphs, CCorrCphs> ExistingCorrCphsSD, int intEstSteps, CStrObjLtDt StrObjLtDt,
                                              double[,] padblTD, int intQuitCount = 200000)
        {
            int intRegionID = LSCrg.ID;  //all the regions generated in this function will have the same intRegionID

            ComputeEstCost(LSCrg, SSCrg, LSCrg, padblTD, intEstSteps);

            //LSCrg.InitialEstimatedCost(SSCrg, padblTD, intEstSteps);
            //LSCrg.SetCoreCph(intSSTypeIndex);

            //a region represents a node in graph, ExistingCrgSD stores all the nodes
            //we use this dictionary to make sure that if the two patches have the same cpgs, then they have the same GID
            var ExistingCphSDLt = new List <SortedDictionary <CPatch, CPatch> >(LSCrg.GetCphCount() + 1);

            for (int i = 0; i < ExistingCphSDLt.Capacity; i++)
            {
                var Element = new SortedDictionary <CPatch, CPatch>(CPatch.pCmpCPatch_CpgGID);
                ExistingCphSDLt.Add(Element);
            }

            var ExistingCrgSDLt = new List <SortedDictionary <CRegion, CRegion> >(LSCrg.GetCphCount() + 1);

            for (int i = 0; i < ExistingCrgSDLt.Capacity; i++)
            {
                //we don't compare exact cost first because of there may be rounding problems
                var Element = new SortedDictionary <CRegion, CRegion>(CRegion.pCmpCrg_CphGIDTypeIndex);
                ExistingCrgSDLt.Add(Element);
            }
            ExistingCrgSDLt[LSCrg.GetCphCount()].Add(LSCrg, LSCrg);

            var FinalOneCphCrg = new CRegion(intRegionID);
            var Q        = new SortedSet <CRegion>(CRegion.pCmpCrg_Cost_CphGIDTypeIndex);
            int intCount = 0;

            CRegion._intNodeCount = 1;
            CRegion._intEdgeCount = 0;
            Q.Add(LSCrg);
            while (true)
            {
                intCount++;
                var u = Q.Min;
                if (Q.Remove(u) == false)
                {
                    throw new ArgumentException
                              ("cannot move an element in this queue! A solution might be to make dblVerySmall smaller!");
                }
                u.cenumColor = CEnumColor.black;

                //List<CRegion> crgcol = new List<CRegion>();
                //crgcol.Add(u);

                //OutputMap(crgcol, this._TypePVDt, u.d, intCount, pParameterInitialize);

                //MessageBox.Show("click for next!");

                //if (CConstants.strShapeConstraint == "MaximizeMinComp_EdgeNumber" ||
                //    CConstants.strShapeConstraint == "MinimizeInteriorBoundaries")
                //{
                //    Console.WriteLine("Crg:  ID  " + u.ID + ";      GID:" + u.GID + ";      CphNum:" +  u.GetCphCount() +
                //        ";      d:" + u.d / u.dblArea + ";      ExactCost:" + u.dblCostExact / u.dblArea +
                //        ";      Compactness:" + u.dblCostExactComp + ";      Type:" + u.dblCostExactType / u.dblArea);
                //}
                //else if (CConstants.strShapeConstraint == "NonShape")
                //{
                //    Console.WriteLine("Crg:  ID  " + u.ID + ";      GID:" + u.GID + ";      CphNum:" + u.GetCphCount() +
                //        ";      d:" + u.d + ";      ExactCost:" + u.dblCostExactType);
                //}

                //at the beginning, resultcrg.d is double.MaxValue.
                //Later, when we first encounter that there is only one CPatch in LSCrg,
                //resultcrg.d will be changed to the real cost
                //u.d contains estimation, and resultcrg.d doesn't contains.
                //if u.d > resultcrg.d, then resultcrg.d must already be the smallest cost
                if (u.GetCphCount() == 1)
                {
                    if (u.GetSoloCphTypeIndex() == SSCrg.GetSoloCphTypeIndex())
                    {
                        //Console.WriteLine("The number of nodes we can forget:   " + intCount);
                        //Console.WriteLine("The nodes in the stack:   " + Q.Count);

                        //int intCrgCount = 0;
                        //foreach (var item in ExistingCrgSDLt)
                        //{
                        //    intCrgCount += item.Count;
                        //}

                        FinalOneCphCrg = u;
                        break;
                    }
                    else
                    {
                        throw new ArgumentException("this is impossible!");
                        //continue;
                    }
                }


                foreach (var newcrg in AggregateAndUpdateQ(u, LSCrg, SSCrg, Q, strAreaAggregation,
                                                           ExistingCrgSDLt, ExistingCphSDLt, ExistingCorrCphsSD, _adblTD, intEstSteps))
                {
                    //int intExploredRegionLast = CRegion._intStaticGID - CRegion._intStartStaticGIDLast;
                    //we don't need to +1 because +1 is already included in _intStaticGID

                    if (CRegion._intNodeCount > intQuitCount)
                    {
                        //if we have visited 2000000 regions but haven't found an optimum aggregation sequence,
                        //then we return null and overestimate in the heuristic function
                        return(new CRegion(-2));
                    }
                }
            }

            RecordResultForCrg(StrObjLtDt, LSCrg, FinalOneCphCrg, SSCrg.GetSoloCphTypeIndex());
            return(FinalOneCphCrg);
        }
示例#14
0
        public CRegion AStar(CRegion LSCrg, CRegion SSCrg, CStrObjLtDt StrObjLtDt, string strAreaAggregation,
                             double[,] padblTD, int intQuitCount = 200000, Process proc = null)
        {
            long lngStartMemory = GC.GetTotalMemory(true);


            var pStopwatchOverHead = new Stopwatch();

            pStopwatchOverHead.Start();


            var ExistingCorrCphsSD0 = LSCrg.SetInitialAdjacency();  //also count the number of edges

            AddLineToStrObjLtDt(StrObjLtDt, LSCrg);


            Console.WriteLine();
            Console.WriteLine("Crg:  ID  " + LSCrg.ID + ";    n  " + LSCrg.GetCphCount() + ";    m  " +
                              LSCrg.AdjCorrCphsSD.Count + "   " + intQuitCount + "   " +
                              CConstants.strShapeConstraint + "   " + strAreaAggregation);


            long lngTimeOverHead = pStopwatchOverHead.ElapsedMilliseconds;

            pStopwatchOverHead.Stop();

            Stopwatch pStopwatchLast  = new Stopwatch();
            bool      blnRecordTime_F = false;
            long      lngTime_F       = 0; //running time of the first trying
            long      lngTime_L       = 0; //running time of last trying
            long      lngTimeAll      = lngTimeOverHead;
            var       resultcrg       = new CRegion(-2);
            int       intEstSteps     = 0;
            int       intRound        = _intRound;

            do
            {
                intEstSteps = Convert.ToInt32(Math.Pow(2, intRound)) - 1;
                try
                {
                    //CRegion._intStartStaticGIDLast = CRegion._intStaticGID;
                    pStopwatchLast.Restart();
                    var ExistingCorrCphsSD = new SortedDictionary <CCorrCphs, CCorrCphs>
                                                 (ExistingCorrCphsSD0, ExistingCorrCphsSD0.Comparer);
                    LSCrg.cenumColor = CEnumColor.white;

                    resultcrg = ComputeAccordEstSteps(LSCrg, SSCrg, strAreaAggregation, ExistingCorrCphsSD,
                                                      intEstSteps, StrObjLtDt, padblTD, intQuitCount);
                }
                catch (System.OutOfMemoryException ex)
                {
                    Console.WriteLine(ex.Message);
                }

                if (blnRecordTime_F == false)
                {
                    lngTime_F       = pStopwatchLast.ElapsedMilliseconds + lngTimeOverHead;
                    blnRecordTime_F = true;
                }
                lngTime_L   = pStopwatchLast.ElapsedMilliseconds + lngTimeOverHead;
                lngTimeAll += pStopwatchLast.ElapsedMilliseconds;

                if (resultcrg.ID != -2)
                {
                    break;
                }
                if (intEstSteps > 50)
                {
                    intEstSteps = 64;
                    throw new ArgumentException("We cannot solve the problem! Impossible!");
                }

                intRound++;
            } while (true);
            StrObjLtDt.SetLastObj("EstSteps", intEstSteps);
            Console.WriteLine("d: " + resultcrg.d
                              + "            Type: " + resultcrg.dblCostExactType
                              + "            Compactness: " + resultcrg.dblCostExactComp);

            //we don't need to +1 because +1 is already included in _intStaticGID
            //int intExploredRegionAll = CRegion._intStaticGID - CRegion._intStartStaticGIDLast;
            //double dblConsumedMemoryInMB = CHelpFunc.GetConsumedMemoryInMB(false);

            StrObjLtDt.SetLastObj("#Edges", CRegion._intEdgeCount);
            StrObjLtDt.SetLastObj("Time_F(ms)", lngTime_F);
            StrObjLtDt.SetLastObj("Time_L(ms)", lngTime_L);
            StrObjLtDt.SetLastObj("Time(ms)", lngTimeAll);
            StrObjLtDt.SetLastObj("Memory(MB)", CHelpFunc.GetConsumedMemoryInMB(false, lngStartMemory));

            Console.WriteLine("EstSteps:" + intEstSteps + "      We have visited " +
                              CRegion._intNodeCount + " Nodes and " + CRegion._intEdgeCount + " Edges.");

            return(resultcrg);
        }
        // Step 4 *****************************************************************************************************
        // Step 4 *****************************************************************************************************
        internal static void PopulateByRow(IMPModeler model, out IIntVar[][][] var2, out IIntVar[][][][] var3,
                                           out IIntVar[][][][][] var4, out IRange[][] rng,
                                           CRegion lscrg, CRegion sscrg, double[,] adblTD, string strAreaAggregation)
        {
            var aCph        = lscrg.GetCphCol().ToArray();
            int intCpgCount = lscrg.GetCphCount();
            //double dblILPSmallValue = 0.000000001;
            //double dblILPSmallValue = 0;

            var x = new IIntVar[intCpgCount][][];

            for (int i = 0; i < intCpgCount; i++)
            {
                x[i] = new IIntVar[intCpgCount][];
                for (int j = 0; j < intCpgCount; j++)
                {
                    x[i][j] = model.BoolVarArray(intCpgCount);
                }
            }

            //cost in terms of type change
            var y = Generate4DNumVar(model, intCpgCount - 1, intCpgCount, intCpgCount, intCpgCount);

            //cost in terms of compactness (length of interior boundaries)
            var z = Generate4DNumVar(model, intCpgCount - 2, intCpgCount, intCpgCount, intCpgCount);


            var c = Generate4DNumVar(model, intCpgCount - 2, intCpgCount, intCpgCount, intCpgCount);

            var3    = new IIntVar[1][][][];
            var4    = new IIntVar[3][][][][];
            var3[0] = x;
            var4[0] = y;
            var4[1] = z;
            var4[2] = c;


            //model.AddEq(x[2][0][3], 1.0, "X1");
            //model.AddEq(x[2][1][3], 1.0, "X2");
            //model.AddEq(x[2][2][2], 1.0, "X3");
            //model.AddEq(x[2][3][3], 1.0, "X4");

            //add minimizations
            ILinearNumExpr pTypeCostExpr = model.LinearNumExpr();

            //ILinearNumExpr pTypeCostAssitantExpr = model.LinearNumExpr();
            for (int i = 0; i < intCpgCount - 1; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    for (int k = 0; k < intCpgCount; k++)
                    {
                        for (int l = 0; l < intCpgCount; l++)
                        {
                            double dblCoe = aCph[j].dblArea * adblTD[aCph[k].intTypeIndex, aCph[l].intTypeIndex];
                            pTypeCostExpr.AddTerm(y[i][j][k][l], dblCoe);
                            //pTypeCostAssitantExpr.AddTerm(y[i][j][k][l], dblILPSmallValueMinimization);
                        }
                    }
                }
            }


            //this is actually for t=1, whose compactness is known
            double         dblCompCostFirstPart    = 0;
            ILinearNumExpr pCompCostSecondPartExpr = model.LinearNumExpr();
            var            pAdjCorrCphsSD          = lscrg.AdjCorrCphsSD;
            double         dblConst = Convert.ToDouble(intCpgCount - 1) / Convert.ToDouble(intCpgCount - 2);

            for (int i = 0; i < intCpgCount - 2; i++)   //i represents indices
            {
                double dblNminusT = intCpgCount - i - 2;
                //double dblTemp = (intCpgCount - i) * dblConst;
                dblCompCostFirstPart += 1 / dblNminusT;
                double dblSecondPartDenominator = lscrg.dblInteriorSegLength * dblNminusT * 2;

                //we don't need to divide the value by 2 because every boundary is only counted once
                foreach (var pCorrCphs in pAdjCorrCphsSD.Keys)
                {
                    for (int l = 0; l < intCpgCount; l++)
                    {
                        pCompCostSecondPartExpr.AddTerm(pCorrCphs.dblSharedSegLength / dblSecondPartDenominator,
                                                        z[i][pCorrCphs.FrCph.ID][pCorrCphs.ToCph.ID][l]);
                        pCompCostSecondPartExpr.AddTerm(pCorrCphs.dblSharedSegLength / dblSecondPartDenominator,
                                                        z[i][pCorrCphs.ToCph.ID][pCorrCphs.FrCph.ID][l]);
                    }
                }
                //var pSecondPartExpr =  model.Prod(pCompCostSecondPartExpr, 1 / dblSecondPartDenominator);
            }

            if (intCpgCount == 1)
            {
                model.AddMinimize(pTypeCostExpr);  //we just use an empty expression
            }
            else
            {
                //Our Model***************************************
                var Ftp = model.Prod(pTypeCostExpr, 1 / lscrg.dblArea);
                var Fcp = model.Prod(dblConst, model.Sum(dblCompCostFirstPart, model.Negative(pCompCostSecondPartExpr)));
                //model.AddMinimize(model.Prod(model.Sum(Ftp, Fcp), 0.5));
                model.AddMinimize(model.Sum(
                                      model.Prod(1 - CAreaAgg_Base.dblLamda, Ftp), model.Prod(CAreaAgg_Base.dblLamda, Fcp)));
                //model.AddMinimize(Fcp);
                //model.AddMaximize(Fcp);
                //model.AddObjective()
            }

            //for showing slacks
            var IRangeLt = new List <IRange>();

            //a polygon $p$ is assigned to exactly one polygon at a step $t$
            for (int i = 0; i < intCpgCount; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    ILinearNumExpr pOneCenterExpr = model.LinearNumExpr();
                    for (int l = 0; l < intCpgCount; l++)
                    {
                        pOneCenterExpr.AddTerm(x[i][j][l], 1.0);
                    }
                    model.AddEq(pOneCenterExpr, 1.0, "AssignToOnlyOneCenter");
                }
            }

            //polygon $r$, which is assigned by other polygons, must be a center
            for (int i = 0; i < intCpgCount; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    for (int l = 0; l < intCpgCount; l++)
                    {
                        model.AddLe(x[i][j][l], x[i][l][l], "AssignedIsCenter__" + i + "__" + j + "__" + l);
                    }
                }
            }

            //only one patch is aggregated into another patch at each step
            for (int i = 0; i < intCpgCount; i++)   //i represents indices
            {
                ILinearNumExpr pOneAggregationExpr = model.LinearNumExpr();
                for (int j = 0; j < intCpgCount; j++)
                {
                    pOneAggregationExpr.AddTerm(x[i][j][j], 1.0);
                }
                model.AddEq(pOneAggregationExpr, intCpgCount - i, "CountCenters");
            }

            //a center can disappear, but will never reappear afterwards
            for (int i = 0; i < intCpgCount - 1; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    model.AddGe(x[i][j][j], x[i + 1][j][j], "SteadyCenters");
                }
            }


            //to make sure that the final aggregated polygon has the same color as the target polygon
            ILinearNumExpr pFinalStateExpr  = model.LinearNumExpr();
            int            intTypeIndexGoal = sscrg.GetSoloCphTypeIndex();

            for (int i = 0; i < intCpgCount; i++)
            {
                if (aCph[i].intTypeIndex == intTypeIndexGoal)
                {
                    pFinalStateExpr.AddTerm(x[intCpgCount - 1][i][i], 1.0);
                }
            }
            model.AddEq(pFinalStateExpr, 1.0, "EnsureTarget");


            //to restrict *y*
            for (int i = 0; i < intCpgCount - 1; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    for (int k = 0; k < intCpgCount; k++)
                    {
                        //IRangeLt.Add(model.AddLe(model.Sum(y[i][j][k][k], x[i][j][k], x[i + 1][j][k]), 2.0 , "RestrictY"));

                        for (int l = 0; l < intCpgCount; l++)
                        {
                            var LieYRight = model.LinearIntExpr(-1);
                            LieYRight.AddTerm(x[i][j][k], 1);
                            LieYRight.AddTerm(x[i + 1][j][l], 1);

                            model.AddGe(y[i][j][k][l], LieYRight, "RestrictY1");
                            model.AddLe(y[i][j][k][l], x[i][j][k], "RestrictY2");
                            model.AddLe(y[i][j][k][l], x[i + 1][j][l], "RestrictY3");
                        }
                    }
                }
            }

            //to restrict *z*
            for (int i = 0; i < intCpgCount - 2; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    //for (int k = j; k < intCpgCount; k++)  // pay attention
                    for (int k = 0; k < intCpgCount; k++)
                    {
                        for (int l = 0; l < intCpgCount; l++)
                        {
                            var LieZRight = model.LinearIntExpr(-1);
                            LieZRight.AddTerm(x[i + 1][j][l], 1);
                            LieZRight.AddTerm(x[i + 1][k][l], 1);

                            model.AddGe(z[i][j][k][l], LieZRight, "RestrictZ1");
                            model.AddLe(z[i][j][k][l], x[i + 1][j][l], "RestrictZ2");
                            model.AddLe(z[i][j][k][l], x[i + 1][k][l], "RestrictZ3");
                        }
                    }
                }
            }

            //to restrict *c*
            double dblCpgCountReciprocal = 1 / Convert.ToDouble(intCpgCount);

            for (int i = 0; i < intCpgCount - 2; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    //for (int k = j; k < intCpgCount; k++)  // pay attention
                    for (int k = 0; k < intCpgCount; k++)
                    {
                        for (int l = 0; l < intCpgCount; l++)
                        {
                            if (k == l)
                            {
                                continue;
                            }

                            model.AddLe(c[i][j][k][l], x[i][j][k], "RestrictC1");

                            var pLieContiguityExpr = model.LinearIntExpr();
                            //pContiguityExpr.AddTerm(x[i][j][k], 1.0);  //including polygon j itself
                            foreach (var pAdjacentCph in aCph[j].AdjacentCphSS)
                            {
                                pLieContiguityExpr.AddTerm(x[i][pAdjacentCph.ID][l], 1);
                            }
                            model.AddLe(c[i][j][k][l], pLieContiguityExpr, "Contiguity");


                            foreach (var pAdjacentCph in aCph[j].AdjacentCphSS)
                            {
                                var pContiguityExpr2 = model.LinearNumExpr(-1);
                                pContiguityExpr2.AddTerm(x[i][j][k], 1);
                                pContiguityExpr2.AddTerm(x[i][pAdjacentCph.ID][l], 1);

                                model.AddGe(c[i][j][k][l], pContiguityExpr2, "Contiguity2");
                            }

                            var pContiguityExprRight3 = model.LinearIntExpr();
                            for (int m = 0; m < intCpgCount; m++)
                            {
                                pContiguityExprRight3.AddTerm(c[i][m][k][l], 1);
                            }
                            model.AddLe(y[i][k][k][l], pContiguityExprRight3, "Contiguity3");
                        }
                    }
                }
            }


            //If two polygons have been aggregated into one polygon, then they will
            //be aggregated together in later steps. Our sixth constraint achieve this by requiring
            for (int i = 0; i < intCpgCount - 3; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    for (int k = 0; k < intCpgCount; k++)
                    {
                        var pAssignTogetherExprPre   = model.LinearIntExpr();
                        var pAssignTogetherExprAfter = model.LinearIntExpr();
                        for (int l = 0; l < intCpgCount; l++)
                        {
                            pAssignTogetherExprPre.AddTerm(z[i][j][k][l], 1);
                            pAssignTogetherExprAfter.AddTerm(z[i + 1][j][k][l], 1);
                        }
                        model.AddLe(pAssignTogetherExprPre, pAssignTogetherExprAfter, "AssignTogether");
                    }
                }
            }

            var2 = new IIntVar[1][][];
            if (strAreaAggregation == _strSmallest)
            {
                IIntVar[][] w = new IIntVar[intCpgCount - 1][];
                for (int i = 0; i < intCpgCount - 1; i++)
                {
                    w[i] = model.BoolVarArray(intCpgCount);
                }
                var2[0] = w;

                //there is only one smallest patch will be involved in each aggregation step
                for (int i = 0; i < intCpgCount - 1; i++)   //i represents indices
                {
                    var pOneSmallestExpr = model.LinearIntExpr();
                    for (int j = 0; j < intCpgCount; j++)
                    {
                        pOneSmallestExpr.AddTerm(w[i][j], 1);
                    }

                    model.AddEq(pOneSmallestExpr, 1.0, "OneSmallest");
                }

                //forces that the aggregation must involve the smallest patch.
                for (int i = 0; i < intCpgCount - 1; i++)   //i represents indices
                {
                    for (int j = 0; j < intCpgCount; j++)
                    {
                        var pInvolveSmallestExpr = model.LinearIntExpr();
                        for (int k = 0; k < intCpgCount; k++)
                        {
                            if (j == k) //o != r
                            {
                                continue;
                            }
                            pInvolveSmallestExpr.AddTerm(y[i][j][j][k], 1);
                            pInvolveSmallestExpr.AddTerm(y[i][k][k][j], 1);
                        }
                        model.AddLe(w[i][j], pInvolveSmallestExpr, "InvolveSmallest");
                    }
                }

                //To guarantee that patch $o$ is involved in aggregation is indeed the smallest patch
                double dblM = 1.1 * lscrg.dblArea;        //a very large value
                for (int i = 0; i < intCpgCount - 1; i++) //i represents indices
                {
                    var aAreaExpr = ComputeAreaExpr(model, x[i], aCph);
                    for (int j = 0; j < intCpgCount; j++)
                    {
                        for (int k = 0; k < intCpgCount; k++)
                        {
                            if (j == k) //o != r
                            {
                                continue;
                            }

                            var pSumExpr  = model.Sum(2.0, model.Negative(model.Sum(w[i][j], x[i][k][k]))); //(2-w_{t,o}-x_{t,r,r})
                            var pProdExpr = model.Prod(pSumExpr, dblM);                                     //M(2-w_{t,o}-x_{t,r,r})

                            //A_{t,o}-A_{t,r}<= M(2-w_{t,o}-x_{t,r,r})
                            model.AddLe(model
                                        .Sum(aAreaExpr[j], model.Negative(aAreaExpr[k])), pProdExpr, "IndeedSmallest");
                        }
                    }
                }
            }


            //***************compare with number of constraints counted manually************
            rng    = new IRange[1][];
            rng[0] = new IRange[IRangeLt.Count];
            for (int i = 0; i < IRangeLt.Count; i++)
            {
                rng[0][i] = IRangeLt[i];
            }
        }
        private CRegion Compute(CRegion lscrg, CRegion sscrg, int intFinalTypeIndex, string strAreaAggregation,
                                SortedDictionary <CCorrCphs, CCorrCphs> ExistingCorrCphsSD, CStrObjLtDt StrObjLtDt, double[,] padblTD)
        {
            CRegion._intNodeCount = 1;
            CRegion._intEdgeCount = 0;
            var currentCrg = lscrg;

            //after an aggregation, we whould have the largest compactness
            //it's urgent to remove the smallest one
            while (currentCrg.GetCphCount() > 1)
            {
                var smallestcph = currentCrg.GetSmallestCph();


                var       CphRecordsEb       = currentCrg.GetNeighborCphRecords(smallestcph);
                double    dblMinCost         = double.MaxValue;
                CCorrCphs minunitingCorrCphs = null;
                CPatch    minunitedcph       = null;
                CPatch    minactivecph       = null;
                CPatch    minpassivecph      = null;

                foreach (var cphrecord in CphRecordsEb)
                {
                    var    neighborcph     = cphrecord.Cph;
                    var    unitingCorrCphs = cphrecord.CorrCphs;
                    var    unitedcph       = smallestcph.Unite(neighborcph, unitingCorrCphs.dblSharedSegLength);
                    CPatch activecph       = neighborcph;
                    CPatch passivecph      = smallestcph;
                    if (padblTD[currentCrg.GetCphTypeIndex(smallestcph), intFinalTypeIndex] <
                        padblTD[currentCrg.GetCphTypeIndex(neighborcph), intFinalTypeIndex])
                    {
                        activecph  = smallestcph;
                        passivecph = neighborcph;
                    }

                    double dblCostType = padblTD[currentCrg.GetCphTypeIndex(activecph), currentCrg.GetCphTypeIndex(passivecph)]
                                         * passivecph.dblArea / lscrg.dblArea;

                    double dblCostShape = 0;
                    if (CConstants.strShapeConstraint == "MaxAvgC_EdgeNo" ||
                        CConstants.strShapeConstraint == "MaxAvgC_Comb")
                    {
                        if (lscrg.GetCphCount() - 2 > 0)
                        {
                            double dblNewSumComp = currentCrg.dblSumComp - cphrecord.CorrCphs.FrCph.dblComp -
                                                   cphrecord.CorrCphs.ToCph.dblComp + unitedcph.dblComp;
                            double dblNewAvgComp = dblNewSumComp / (currentCrg.GetCphCount() - 1);
                            dblCostShape = (1 - dblNewAvgComp) / (lscrg.GetCphCount() - 2);
                        }
                    }
                    else if (CConstants.strShapeConstraint == "MinIntBound")
                    {
                        if (lscrg.GetCphCount() - 2 > 0)
                        {
                            double dblNewLength = currentCrg.dblInteriorSegLength - cphrecord.CorrCphs.dblSharedSegLength;
                            dblCostShape = dblNewLength * (lscrg.GetCphCount() - 1) / (lscrg.GetCphCount() - 2)
                                           / (currentCrg.GetCphCount() - 1) / lscrg.dblInteriorSegLength;
                        }
                    }
                    else
                    {
                        //CConstants.strShapeConstraint == "MaxMinC_EdgeNo" ||
                        //CConstants.strShapeConstraint == "MaxMinC_Comb" ||
                        throw new ArgumentException("We didn't consider the case!");
                    }

                    double dblCost = (1 - CAreaAgg_Base.dblLamda) * dblCostType + CAreaAgg_Base.dblLamda * dblCostShape;

                    if (dblCost < dblMinCost)
                    {
                        dblMinCost         = dblCost;
                        minunitingCorrCphs = unitingCorrCphs;
                        minunitedcph       = unitedcph;
                        minactivecph       = activecph;
                        minpassivecph      = passivecph;
                    }
                }

                var newAdjCorrCphsSD = CRegion.ComputeNewAdjCorrCphsSDAndUpdateExistingCorrCphsSD
                                           (currentCrg.AdjCorrCphsSD, minunitingCorrCphs, minunitedcph, ExistingCorrCphsSD);
                var newcrg = currentCrg.GenerateCrgChildAndComputeExactCost(lscrg, newAdjCorrCphsSD,
                                                                            minactivecph, minpassivecph, minunitedcph, minunitingCorrCphs, padblTD);

                newcrg.d = newcrg.dblCostExact;

                CRegion._intNodeCount++;
                CRegion._intEdgeCount++;
                currentCrg = newcrg;
            }

            RecordResultForCrg(StrObjLtDt, lscrg, currentCrg, intFinalTypeIndex);

            return(currentCrg);
        }
示例#17
0
        /// <summary>
        /// from time t to n-1
        /// </summary>
        /// <param name="crg"></param>
        /// <returns></returns>
        private IEnumerable <double> EstimateAvgComp_EdgeNumber(CRegion crg, CRegion lscrg, int intEstSteps)
        {
            double dblSumComp   = 0;
            var    dblCompSS    = new SortedSet <CValPair <double, int> >();
            int    intCompCount = 0;

            foreach (var cph in crg.GetCphCol())
            {
                dblSumComp += cph.dblComp;
                dblCompSS.Add(new CValPair <double, int>(cph.dblComp, intCompCount++));
            }

            var intEdgeCountSS = new SortedSet <int>(new CIntCompare());

            foreach (var pCorrCphs in crg.AdjCorrCphsSD.Keys)
            {
                intEdgeCountSS.Add(pCorrCphs.intSharedCEdgeCount);
            }

            int intEdgeCountRemain = crg.intExteriorEdgeCount + crg.intInteriorEdgeCount;
            int intCphCount        = crg.GetCphCount();

            IEnumerator <int> intEdgeCountSSEt = intEdgeCountSS.GetEnumerator();
            int intEstCount = 0;

            while (intCphCount > 1)
            {
                //if intEstCount == lscrg.GetCphCount(), we are estimating from the start map (t==1)
                //we define that the estimation value of the start map is 0, therefore we skip intEstCount == lscrg.GetCphCount()
                if (intCphCount < lscrg.GetCphCount())
                {
                    if (intEstCount < intEstSteps)
                    {
                        yield return(0);  //overestimation

                        intEstCount++;
                    }
                    else
                    {
                        double dblAvgComp = dblSumComp / intCphCount;
                        yield return(dblAvgComp);  //normal estimation
                    }
                }

                //remove the two smallest compactnesses
                for (int i = 0; i < 2; i++)
                {
                    dblSumComp -= dblCompSS.Min().val1;
                    if (dblCompSS.Remove(dblCompSS.Min()) == false)
                    {
                        throw new ArgumentException("failed to remove the smallest element!");
                    }
                }

                intEdgeCountSSEt.MoveNext();
                intEdgeCountRemain -= intEdgeCountSSEt.Current;

                //double dblNewComp = 0;
                //if (intEstCount < intEstSteps)
                //{
                //    dblNewComp = 0;  //overestimation
                //    intEstCount++;
                //}
                //else
                //{
                //    dblNewComp = CGeoFunc.CalCompRegularPolygon(intEdgeCountRemain); //normal estimation
                //}

                double dblNewComp = CGeoFunc.CalCompRegularPolygon(intEdgeCountRemain); //normal estimation

                dblCompSS.Add(new CValPair <double, int>(dblNewComp, intCompCount++));
                dblSumComp += dblNewComp;
                intCphCount--;
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="LSCrg"></param>
        /// <param name="SSCrg"></param>
        /// <param name="StrObjLtDt"></param>
        /// <param name="adblTD"></param>
        /// <param name="EstStepsCostVPDt">Results from A*</param>
        /// <param name="strAreaAggregation"></param>
        /// <returns></returns>
        public CRegion Greedy(CRegion LSCrg, CRegion SSCrg, CStrObjLtDt StrObjLtDt, double[,] adblTD,
                              Dictionary <int, CValPair <int, double> > EstStepsCostVPDt, string strAreaAggregation)
        {
            long lngStartMemory     = GC.GetTotalMemory(true);
            var  pStopwatchOverHead = Stopwatch.StartNew();

            var ExistingCorrCphsSD0 = LSCrg.SetInitialAdjacency();  //also count the number of edges

            AddLineToStrObjLtDt(StrObjLtDt, LSCrg);


            Console.WriteLine();
            Console.WriteLine("Crg:  ID  " + LSCrg.ID + ";    n  " + LSCrg.GetCphCount() + ";    m  " +
                              LSCrg.AdjCorrCphsSD.Count + "   " + CConstants.strShapeConstraint + "   " + strAreaAggregation);


            long lngTimeOverHead = pStopwatchOverHead.ElapsedMilliseconds;

            pStopwatchOverHead.Stop();

            var  pStopwatchLast = new Stopwatch();
            long lngTime        = 0;

            CRegion resultcrg = new CRegion(-2);

            try
            {
                pStopwatchLast.Restart();
                var ExistingCorrCphsSD = new SortedDictionary <CCorrCphs, CCorrCphs>
                                             (ExistingCorrCphsSD0, ExistingCorrCphsSD0.Comparer);
                LSCrg.cenumColor = CEnumColor.white;

                resultcrg = Compute(LSCrg, SSCrg, SSCrg.GetSoloCphTypeIndex(),
                                    strAreaAggregation, ExistingCorrCphsSD, StrObjLtDt, adblTD);
            }
            catch (System.OutOfMemoryException ex)
            {
                Console.WriteLine(ex.Message);
            }
            lngTime = pStopwatchLast.ElapsedMilliseconds + lngTimeOverHead;


            Console.WriteLine("d: " + resultcrg.d
                              + "            Type: " + resultcrg.dblCostExactType
                              + "            Compactness: " + resultcrg.dblCostExactComp);

            EstStepsCostVPDt.TryGetValue(LSCrg.ID, out CValPair <int, double> outEstStepsCostVP);
            if (outEstStepsCostVP.val1 == 0 &&
                CCmpMethods.CmpDbl_CoordVerySmall(outEstStepsCostVP.val2, resultcrg.d) == 0)
            {
                StrObjLtDt.SetLastObj("EstSteps/Gap%", 0); //optimal solutions
            }
            else
            {
                StrObjLtDt.SetLastObj("EstSteps/Gap%", 100); //not sure, at least feasible solutions
            }
            //we don't need to +1 because +1 is already included in _intStaticGID
            //int intExploredRegionAll = CRegion._intStaticGID - CRegion._intStartStaticGIDLast;
            StrObjLtDt.SetLastObj("#Edges", CRegion._intEdgeCount);
            StrObjLtDt.SetLastObj("Time_F(ms)", lngTime);
            StrObjLtDt.SetLastObj("Time_L(ms)", lngTime);
            StrObjLtDt.SetLastObj("Time(ms)", lngTime);
            StrObjLtDt.SetLastObj("Memory(MB)", CHelpFunc.GetConsumedMemoryInMB(false, lngStartMemory));

            Console.WriteLine("We have visited " +
                              CRegion._intNodeCount + " Nodes and " + CRegion._intEdgeCount + " Edges.");

            return(resultcrg);
        }
        public CRegion ILP(CRegion LSCrg, CRegion SSCrg, CStrObjLtDt StrObjLtDt,
                           double[,] adblTD, string strAreaAggregation,
                           ref SortedSet <CRegion> CrgOOMSetSS, ref SortedSet <CRegion> CrgOOMSolveSS, ref SortedSet <CRegion> CrgOOTSetSS, ref SortedSet <CRegion> CrgOOTSolveSS,
                           ref SortedSet <CRegion> CrgCplexError3019SS, ref SortedSet <CRegion> CrgOtherErrorsSS, ref string strOtherErrors)
        {
            long lngStartMemory = GC.GetTotalMemory(true);

            var pStopwatch = Stopwatch.StartNew();

            LSCrg.SetInitialAdjacency();  //also count the number of edges
            AddLineToStrObjLtDt(StrObjLtDt, LSCrg);

            //must be below LSCrg.SetInitialAdjacency();
            System.Console.WriteLine();
            System.Console.WriteLine();
            System.Console.WriteLine("Crg:  ID  " + LSCrg.ID + ";    n  " + LSCrg.GetCphCount() + ";    m  " +
                                     LSCrg.AdjCorrCphsSD.Count + "  " + _ParameterInitialize.strAreaAggregation + "================================="
                                     + LSCrg.ID + "  " + _ParameterInitialize.strAreaAggregation + " " + this.dblTimeLimit + " s " + "==============================");



            //double dblMemoryInMB2 = CHelpFunc.GetConsumedMemoryInMB(true);
            var cplex = new Cplex();
            //double dblMemoryInMB3 = CHelpFunc.GetConsumedMemoryInMB(true);

            var  crg        = new CRegion(-1);
            bool blnSolved  = false;
            bool blnSetting = false;

            try
            {
                //Step 3
                //Cplex cplex = new Cplex();
                IIntVar[][][]     var2;
                IIntVar[][][][]   var3;
                IIntVar[][][][][] var4;
                IRange[][]        rng;

                PopulateByRow(cplex, out var2, out var3, out var4, out rng, LSCrg, SSCrg, adblTD, strAreaAggregation);
                //double dblMemoryInMB4 = CHelpFunc.GetConsumedMemoryInMB(true);
                // Step 11
                //cplex.ExportModel("lpex1.lp");

                // Step 9
                double dblRemainTimeLim = this.dblTimeLimit - Convert.ToDouble(pStopwatch.ElapsedMilliseconds) / 1000;
                if (dblRemainTimeLim > 0)
                {
                    blnSetting = true;

                    cplex.SetParam(Cplex.DoubleParam.TiLim, dblRemainTimeLim);

                    //avoid that optimal solutions from CPELX are not optimal
                    //see https://www-01.ibm.com/support/docview.wss?uid=swg1RS02094
                    cplex.SetParam(Cplex.IntParam.AuxRootThreads, -1);
                    cplex.SetParam(Cplex.IntParam.Reduce, 0);  //really work for me
                    cplex.SetParam(Cplex.DoubleParam.CutLo, 0);

                    if (cplex.Solve())
                    {
                        //***********Gap for ILP************

                        #region Display x, y, z, and s
                        //for (int i = 0; i < var3[0].GetLength(0); i++)
                        //{

                        //    Console.WriteLine("Variable x; Time: " + (i + 1).ToString());

                        //    foreach (var x1 in var3[0][i])
                        //    {
                        //        //CPatch



                        //        double[] x = cplex.GetValues(x1);


                        //        foreach (var x0 in x)
                        //        {
                        //            int intWrite = 0;  //avoid some values like 0.999999997 or 2E-09
                        //            if (x0>0.5)
                        //            {
                        //                intWrite = 1;
                        //            }
                        //            Console.Write(intWrite + "     ");
                        //        }
                        //        Console.WriteLine();

                        //    }
                        //    Console.WriteLine();
                        //}

                        #region Display y and z
                        //if (var4[0] != null)
                        //{
                        //    Console.WriteLine("");
                        //    //Console.WriteLine("Variable y:");
                        //    for (int i = 0; i < var4[0].GetLength(0); i++)
                        //    {
                        //        Console.WriteLine("Variable y; Time: " + (i + 1).ToString());
                        //        foreach (var y2 in var4[0][i])
                        //        {
                        //            foreach (var y1 in y2)
                        //            {

                        //                double[] y = cplex.GetValues(y1);


                        //                foreach (var y0 in y)
                        //                {
                        //                    Console.Write(y0 + "     ");
                        //                }
                        //                Console.WriteLine();
                        //            }

                        //            Console.WriteLine();
                        //        }
                        //        //Console.WriteLine();
                        //    }
                        //}

                        //if (var4[1] != null)
                        //{
                        //    Console.WriteLine("");
                        //    //Console.WriteLine("Variable z:");
                        //    for (int i = 0; i < var4[1].GetLength(0); i++)
                        //    {
                        //        Console.WriteLine("Variable z; Time: " + (i + 1).ToString());
                        //        foreach (var z2 in var4[1][i])
                        //        {
                        //            foreach (var z1 in z2)
                        //            {

                        //                double[] z = cplex.GetValues(z1);


                        //                foreach (var z0 in z)
                        //                {
                        //                    Console.Write(z0 + "     ");
                        //                }
                        //                Console.WriteLine();

                        //            }
                        //            Console.WriteLine();
                        //        }
                        //        //Console.WriteLine();
                        //    }
                        //}
                        #endregion


                        //if (_ParameterInitialize.strAreaAggregation == _strSmallest)
                        //{
                        //    Console.WriteLine("");
                        //    Console.WriteLine("Variable s:");
                        //    if (var2[0] != null)
                        //    {
                        //        for (int i = 0; i < var2[0].GetLength(0); i++)
                        //        {


                        //            double[] s = cplex.GetValues(var2[0][i]);


                        //            foreach (var s0 in s)
                        //            {
                        //                Console.Write(s0 + "     ");
                        //            }
                        //            Console.WriteLine();

                        //        }
                        //    }
                        //}
                        #endregion

                        #region Display other results
                        //double[] dj = cplex.GetReducedCosts(var3[0][0][0]);
                        //double[] dj2 = cplex.GetReducedCosts((var3);
                        //double[] pi = cplex.GetDuals(rng[0]);
                        //double[] slack = cplex.GetSlacks(rng[0]);
                        //Console.WriteLine("");
                        //cplex.Output().WriteLine("Solution status = "
                        //+ cplex.GetStatus());
                        //cplex.Output().WriteLine("Solution value = "
                        //+ cplex.ObjValue);
                        //objDataLt[13] = cplex.ObjValue;
                        //int nvars = x.Length;
                        //for (int j = 0; j < nvars; ++j)
                        //{
                        //    cplex.Output().WriteLine("Variable :"
                        //    + j
                        //    + " Value = "
                        //    + x[j]
                        //    + " Reduced cost = "
                        //    + dj[j]);
                        //}
                        //int ncons = slack.Length;
                        //for (int i = 0; i < ncons; ++i)
                        //{
                        //    cplex.Output().WriteLine("Constraint:"
                        //    + i
                        //    + " Slack = "
                        //    + slack[i]
                        //    //+ " Pi = "
                        //    //+ pi[i]
                        //    );
                        //}
                        #endregion
                    }

                    Console.WriteLine("");
                    var strStatus = cplex.GetStatus().ToString();
                    Console.WriteLine("Solution status = " + strStatus);

                    if (strStatus == "Optimal")
                    {
                        blnSolved = true;
                        StrObjLtDt.SetLastObj("EstSteps/Gap%", 0.ToString("F4"));  //keep 4 decimal digits
                        StrObjLtDt.SetLastObj("Cost", cplex.ObjValue);
                        Console.WriteLine("Solution value = " + cplex.ObjValue);
                    }
                    else if (strStatus == "Feasible")
                    {
                        //|best integer-best bound(node)|  / 1e-10 + |best integer|
                        //|cplex.ObjValue-cplex.BestObjValue|  /  1e-10 + |cplex.ObjValue|
                        blnSolved = true;
                        StrObjLtDt.SetLastObj("EstSteps/Gap%", (cplex.MIPRelativeGap * 100).ToString("F4"));  //keep 4 decimal digits
                        StrObjLtDt.SetLastObj("Cost", cplex.ObjValue);
                        Console.WriteLine("Solution value = " + cplex.ObjValue);
                    }
                    else //if (strStatus == "Unknown") //we do not find any solution in a time limit
                    {
                        CrgOOTSolveSS.Add(LSCrg);
                        Console.WriteLine("didn't find any solution in the time limit.");
                    }
                }
                else
                {
                    CrgOOTSetSS.Add(LSCrg);
                }
            }
            catch (ILOG.Concert.Exception e)
            {
                if (e.Message == "CPLEX Error  1001: Out of memory.\n")
                {
                    if (blnSetting == false) //this can happen when we are setting up variables and constraints
                    {
                        Console.Write("During Setting: " + e.Message);
                        CrgOOMSetSS.Add(LSCrg);
                    }
                    else
                    {
                        Console.Write("During Solving: " + e.Message);
                        CrgOOMSolveSS.Add(LSCrg);
                    }
                }
                else if (e.Message == "CPLEX Error  3019: Failure to solve MIP subproblem.\n") //this can really happen
                {
                    Console.Write("During Solving: " + e.Message);
                    CrgCplexError3019SS.Add(LSCrg);
                }
                else  //other eroors, e.g., "CPLEX Error  1004: Null pointer for required data.\n"
                {
                    var strError = "ID: " + LSCrg.ID + "  " + "blnSetting == " + blnSetting.ToString() + ";    " + e.Message;
                    Console.Write(strError);
                    strOtherErrors += strError;
                    CrgOtherErrorsSS.Add(LSCrg);
                    //throw;
                }
            }
            catch (System.OutOfMemoryException e2) //this can really happen, though ILOG.Concert.Exception should occur instead
            {
                if (blnSetting == false)
                {
                    Console.WriteLine("During Setting: System exception " + e2.Message);
                    CrgOOMSetSS.Add(LSCrg);
                    //throw;
                }
                else
                {
                    CrgOOMSolveSS.Add(LSCrg);
                    Console.WriteLine("During Solving: System exception " + e2.Message);
                    //throw;
                }
            }
            finally
            {
                double dblMemoryInMB = CHelpFunc.GetConsumedMemoryInMB(false, lngStartMemory);
                if (blnSolved == false)
                {
                    crg.ID = -2;
                    StrObjLtDt.SetLastObj("EstSteps/Gap%", _intNoSolutionEstSteps.ToString("F4"));
                    //StrObjLtDt.SetLastObj("Cost", -1); //the cost value is -1 by default
                    Console.WriteLine("Crg:  ID  " + LSCrg.ID + ";    n  " + LSCrg.GetCphCount() + ";    m  " +
                                      LSCrg.AdjCorrCphsSD.Count + "  could not be solved by ILP!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
                }
                StrObjLtDt.SetLastObj("Time_L(ms)", pStopwatch.ElapsedMilliseconds);
                StrObjLtDt.SetLastObj("Time(ms)", pStopwatch.ElapsedMilliseconds);
                StrObjLtDt.SetLastObj("Memory(MB)", dblMemoryInMB);

                cplex.End();
            }



            return(crg);
        }