// Lingo callback function to display the current iteration count public static int MyCallback(int pLingoEnv, int nReserved, IntPtr pMyData) { var cb = new CallbackData(); Marshal.PtrToStructure(pMyData, cb); int nIterations = -1; int nErr = lingo.LSgetCallbackInfoLng(pLingoEnv, lingo.LS_IINFO_ITERATIONS_LNG, ref nIterations); if (nErr == lingo.LSERR_NO_ERROR_LNG && nIterations != cb.nIterations) cb.nIterations = nIterations; Marshal.StructureToPtr(cb, pMyData, true); return 0; }
public void MinimizeCost(IEnumerable<TransportUnit> transportUnits, int maxNumberOfSolutions) { int nPointersNow = -1; double dStatus = -1; double maxTripTime = double.MaxValue; foreach (TransportUnit unit in transportUnits) { unit.ProposedRoutes.Clear(); } int solutionIndex; for (solutionIndex = 0; solutionIndex < maxNumberOfSolutions; solutionIndex++) { try { System.Threading.Monitor.Enter(this); // Open LINGO's log file var logFile = Path.Combine(_logFileFolder.FullName, string.Format("lingo.{0}.log", Guid.NewGuid())); int errorCode = lingo.LSopenLogFileLng(_pLingoEnv, logFile); CheckIfError(errorCode); // Let Lingo know we have a callback function var cbd = new CallbackData(); var cb = new lingo.typCallback(LngCallback.MyCallback); errorCode = lingo.LSsetCallbackSolverLng(_pLingoEnv, cb, cbd); CheckIfError(errorCode); // must pin lingo's transfer areas in memory unsafe { fixed (double* pResult = new double[_numLegs], pMinTrp = _minTrp, pMaxTrp = _maxTrp, pCost = _cost, pDuration = _duration, pStartTime = _startTime, pRequestedVolume = new double[transportUnits.Count()], pTotalTripTime = new double[transportUnits.Count()], pMinStartTime = new double[transportUnits.Count()] ) { //clean mem.areas from previous runs errorCode = lingo.LSclearPointersLng(_pLingoEnv); CheckIfError(errorCode); var inputFilePath = Path.Combine(_inputFileFolder.FullName, "logistikcenter.txt"); using (var inputFile = new StreamWriter(inputFilePath, false)) { string demandString = string.Empty; //nodes: TODO inputFile.WriteLine("{0} ~", _nodeString); //leg_id:n inputFile.WriteLine("{0} ~", _legIdString); //com type: TODO inputFile.WriteLine("1 2 ~"); //transport inputFile.WriteLine("{0} ~", _transportString); //com cust sup int currentUnit = 0; foreach (TransportUnit transportUnit in transportUnits) { demandString += (string.Format("1 {0} {1}\r\n", transportUnit.Origin.Id, transportUnit.Destination.Id)); pRequestedVolume[currentUnit] = transportUnit.Cargo.Volume; TimeSpan span = (transportUnit.MaxDeliveryTime - _zeroTime); pTotalTripTime[currentUnit] = span.TotalHours; span = (transportUnit.MinPickupTime - _zeroTime); pMinStartTime[currentUnit] = span.TotalHours; currentUnit++; } //demand inputFile.WriteLine("{0} ~", demandString); } // Pointer to the min totalCapacity errorCode = lingo.LSsetPointerLng(_pLingoEnv, &pMinTrp[0], ref nPointersNow); CheckIfError(errorCode); // Pointer to the max totalCapacity errorCode = lingo.LSsetPointerLng(_pLingoEnv, &pMaxTrp[0], ref nPointersNow); CheckIfError(errorCode); // Pointer to the cost errorCode = lingo.LSsetPointerLng(_pLingoEnv, &pCost[0], ref nPointersNow); CheckIfError(errorCode); // Pointer to the duration errorCode = lingo.LSsetPointerLng(_pLingoEnv, &pDuration[0], ref nPointersNow); CheckIfError(errorCode); // Pointer to the starttime errorCode = lingo.LSsetPointerLng(_pLingoEnv, &pStartTime[0], ref nPointersNow); CheckIfError(errorCode); // Pointer to the customer demanded volume errorCode = lingo.LSsetPointerLng(_pLingoEnv, &pRequestedVolume[0], ref nPointersNow); CheckIfError(errorCode); // Pointer to the customer demanded max time errorCode = lingo.LSsetPointerLng(_pLingoEnv, &pTotalTripTime[0], ref nPointersNow); CheckIfError(errorCode); // Pointer to the customer demanded max time errorCode = lingo.LSsetPointerLng(_pLingoEnv, &pMinStartTime[0], ref nPointersNow); CheckIfError(errorCode); // max trip time errorCode = lingo.LSsetPointerLng(_pLingoEnv, &maxTripTime, ref nPointersNow); CheckIfError(errorCode); // Pointer to the solution status code errorCode = lingo.LSsetPointerLng(_pLingoEnv, &dStatus, ref nPointersNow); CheckIfError(errorCode); // Total trip time double totalTripTime = -1; errorCode = lingo.LSsetPointerLng(_pLingoEnv, &totalTripTime, ref nPointersNow); CheckIfError(errorCode); // Here is the script we want LINGO to run. string cScript = string.Format("set echoin 1 \n take {0} \n go \n quit \n", _modelPath.FullName); // Run the script errorCode = lingo.LSexecuteScriptLng(_pLingoEnv, cScript); CheckIfError(errorCode); // Close the log file lingo.LScloseLogFileLng(_pLingoEnv); // Any problems? if (errorCode != 0) throw new FaildToSolveOptimizationException(); //hittade vi en lösning? if (dStatus == lingo.LS_STATUS_GLOBAL_LNG || dStatus == lingo.LS_STATUS_LOCAL_LNG) { //get results FetchResults(transportUnits); //set max trip time to force another solution maxTripTime = totalTripTime; } } } } finally { System.Threading.Monitor.Exit(this); } } }