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); }
/// <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--; } }
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); }
/// <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)); }
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)); }
/// <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)); }
/// <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]; //} }
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); }
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)); } }
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)); }
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); }
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); }
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); }
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); }
/// <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); }