+{Page}InitialPlan ! 1 Initialize /10/29/2010 05:13:06.350 !---------------------------------------- +{Object.1} InitialPlan.[1]Initialize INTEGER(big):: bigSurID +{Trans} !Load raw table input already sorted by stores; create storage queues to hold lists of DCs, Retail Stores, etc. CALL Initializations &D.HighestLinkCost = 0. !Sort input by DCs and also by Retail Stores. DO bigRecord = 1, &B.Records !CALL Store(Queue pointer, Entity ID, Rank value) !In this case Entity IDs in Store routine represent link/arc numbers (bigRecord) corresponding to raw data in DistTranspData table CALL Store(queDCrecords,bigRecord,{t.D}DistTranspData(bigRecord,&R.DCidColumn)) CALL Store(queStoreRecords,bigRecord,{t.D}DistTranspData(bigRecord,&R.StoreIDcolumn)) &D.HighestLinkCost = MAX({t.D}DistTranspData(bigRecord,&R.CostIJcolumn),&D.HighestLinkCost) ENDDO WRITE (&I.Scratch,*)"Topic: Highest Link Cost:",&D.HighestLinkCost -{Trans} -{Object.1} InitialPlan.[1]Initialize !---------------------------------------- +{Object.3} InitialPlan.[3]Sort out DCs info +{Trans} !Go through each link sorted by DCs and store the Retail Stores each DC is allowed to supply; create DC index !While doing above each link (lnkInfo) is also updated with Sequence number of each DC and transportation cost from that DC to each Store it supplies qelDCrecordsP=>queDCrecords%Head !Points to DC at the head of DC records queue &R.PrevDCid = qelDCrecordsP%dblRank &R.DCseq = 1 &R.TargetStores = 0 DO bigRecord = qelDCrecordsP%bigEntId &R.DCid = qelDCrecordsP%dblRank IF(&R.DCid /= &R.PrevDCid)THEN !New DC ID WRITE(&I.Scratch,*)"DC",&R.DCseq,&R.PrevDCid,&R.TargetStores &D.Rank = &R.PrevDCid &B.EntID = &R.TargetStores CALL Store(queDCs,&B.EntID,&D.Rank) !Normalized and sorted list of DCs. !Entity ID property will hold number suppliable of retail stores. Rank value will hold DC ID &R.DCseq = QueueLength(queDCs) + 1 &R.PrevDCid = &R.DCid &R.TargetStores = 0 ENDIF &R.TargetStores = &R.TargetStores + 1 lnkInfo(bigRecord)%regDCseq = &R.DCseq lnkInfo(bigRecord)%dblCost = {t.D}DistTranspData(bigRecord,&R.CostIJcolumn) WRITE(&I.Scratch,*)bigRecord,lnkInfo(bigRecord)%regDCseq,{t.D}DistTranspData(bigRecord,&R.DCidColumn), & {t.D}DistTranspData(bigRecord,&R.StoreIDcolumn),lnkInfo(bigRecord)%dblCost IF(.NOT.ASSOCIATED(qelDCrecordsP%qelAft))THEN WRITE(&I.Scratch,*)"DC",&R.DCseq,&R.PrevDCid,&R.TargetStores &D.Rank = &R.PrevDCid &B.EntID = &R.TargetStores CALL Store(queDCs,&B.EntID,&D.Rank) EXIT ENDIF qelDCrecordsP=>qelDCrecordsP%qelAft ENDDO WRITE(&I.Scratch,*)"Topic: End of DC records" &R.TotalDCs = QueueLength(queDCs) !Allocate memory for DC objects ALLOCATE(dcDC(0:&R.TotalDCs)) dcDC(0)%regID = 0 -{Trans} -{Object.3} InitialPlan.[3]Sort out DCs info !---------------------------------------- +{Object.5} InitialPlan.[5]DCsStoresAndLinks +{Trans} !We have already created &R.TotalDCs DC objects while setting up lnkInfo objects from raw input data in DistTranspData table !Here we allocate memory for arcs out of each DC and set all initial and permanent properties of each DC CALL OpenForWriting(&I.DCsF,TRIM(modl%strPath) // "TranspDCs.TXT","DCs","Transportation.NET-86") qelDCsP => queDCs%Head qelDCrecordsP => queDCrecords%Head WRITE(&I.DCsF,*)"Seq ID Supply NumStores" DO bigDC = 1, &R.TotalDCs dcDC(bigDC)%regID = qelDCsP%dblRank &R.TargetStores = qelDCsP%bigEntID ALLOCATE(dcDC(bigDC)%bigLinkSeq(&R.TargetStores)) !Arcs out of this DC to Retail Stores it is allowed to supply DO bigFlowLink = 1,&R.TargetStores bigRecord = qelDCrecordsP%bigEntID dcDC(bigDC)%bigLinkSeq(bigFlowLink) = bigRecord qelDCrecordsP=>qelDCrecordsP%qelAft ENDDO dcDC(bigDC)%bigCapacity = {t.D}DistTranspData(bigRecord,&R.SupplyColumn) dcDC(bigDC)%bigRemCapacity = dcDC(bigDC)%bigCapacity dcDC(bigDC)%logRemCapacity = logYes dcDC(bigDC)%regStores = &R.TargetStores WRITE(&I.Scratch,*)"DC props",bigDC,dcDC(bigDC)%regID,dcDC(bigDC)%bigCapacity,&R.TargetStores, & bigRecord,&R.SupplyColumn,{t.D}DistTranspData(bigRecord,&R.SupplyColumn) WRITE(&I.DCsF,*)bigDC,dcDC(bigDC)%regID,dcDC(bigDC)%bigCapacity,&R.TargetStores qelDCsP=>qelDCsP%qelAft ENDDO CALL CloseFile(&I.DCsF,"Transportation.NET-168") WRITE(&I.Scratch,'(A,T32,I12)')" Total capacity:", SUM(dcDC(1:)%bigCapacity) WRITE(&I.Scratch,*)"Topic: End of all DCs info" !Allocate memory for arcs into Retail Stores, while creating index of Retail Stores !Store bigRecord as Entity IDs in the index sort CALL OpenForWriting(&I.StoresF,TRIM(modl%strPath) // "TranspStores.TXT","STOR","Transportation.NET-118") qelStoresP=>queStores%Head qelStoreRecordsP=>queStoreRecords%Head WRITE(&I.StoresF,*)"Seq ID Demand NumDCs" &R.MaxDCconnections = 0 DO bigStore = 1, &R.TotalStores rtsStore(bigStore)%regID = qelStoresP%dblRank &R.SourceDCs = qelStoresP%bigEntID ALLOCATE(rtsStore(bigStore)%bigLinkSeq(&R.SourceDCs)) DO bigFlowLink = 1,&R.SourceDCs bigRecord = qelStoreRecordsP%bigEntID rtsStore(bigStore)%bigLinkSeq(bigFlowLink) = bigRecord qelStoreRecordsP=>qelStoreRecordsP%qelAft ENDDO rtsStore(bigStore)%bigDemand = {t.D}DistTranspData(bigRecord,&R.DemandColumn) rtsStore(bigStore)%bigRemDemand = rtsStore(bigStore)%bigDemand !rtsStore(bigStore)%logRemDemand = logYes rtsStore(bigStore)%regDCs = &R.SourceDCs &R.MaxDCconnections = Max(&R.MaxDCconnections,&R.SourceDCs) WRITE(&I.Scratch,*)"Store props",bigStore,rtsStore(bigStore)%regID,rtsStore(bigStore)%bigDemand,&R.SourceDCs WRITE(&I.StoresF,*)bigStore,rtsStore(bigStore)%regID,rtsStore(bigStore)%bigDemand,&R.SourceDCs qelStoresP=>qelStoresP%qelAft ENDDO CALL CloseFile(&I.StoresF,"Transportation.NET-168") WRITE(&I.Scratch,'(A,T32,I12)')" Total Demand:", SUM(rtsStore(1:)%bigDemand) WRITE(&I.Scratch,*)"Topic: End of all Stores info" CALL CloseFile(&I.Scratch,"transportation.NET-144") ALLOCATE(dcP(1:&R.MaxDCconnections)) -{Trans} +{SignalTarget} !Sends surrogates along every link in the input file. Travel time is equated to per unit transportation cost from the DC to Retails Store in the link CALL OpenForWriting(&I.Links,TRIM(modl%strPath) // "TranspLinks.TXT","LINK","Transportation.NET-154") WRITE(&I.Links,*)"LinkSeq DCseq DCid StoreSeq StoreID UnitCost" DO bigRecord = 1, &B.Records !Surrogate will carry properties link/arc number and per unit transportation cost along the arc (i.e. bigRecord and lnkInfo(bigRecord)%dblCost) @B.FlowLink = bigRecord $D.SignalDuration = lnkInfo(bigRecord)%dblCost WRITE(&I.Links,*)bigRecord,lnkInfo(bigRecord)%regDCseq,{t.D}DistTranspData(bigRecord,&R.DCidColumn), & lnkInfo(bigRecord)%regStoreSeq,{t.D}DistTranspData(bigRecord,&R.StoreIDcolumn),$D.SignalDuration {Signal.9} !Surrgoate travels to Node 9 (InitialPlan.[9]InitialPlan) ENDDO CALL CloseFile(&I.Links,"Transportation.NET-168") -{SignalTarget} -{Object.5} InitialPlan.[5]DCsStoresAndLinks !---------------------------------------- +{Object.7} InitialPlan.[7]Sort out Stores Info +{Trans} !Go through each link sorted by Retail Stores and store DCs each Store is allowed to be supplied; create Retail Stores index !While doing above each connection (lnkInfo) is also updated with Sequence number of each Retail Store qelStoreRecordsP=>queStoreRecords%Head &R.PrevStoreID = qelStoreRecordsP%dblRank &R.SourceDCs = 0 &R.StoreSeq = 1 DO bigRecord = qelStoreRecordsP%bigEntId &R.StoreID = qelStoreRecordsP%dblRank IF(&R.StoreID /= &R.PrevStoreID)THEN WRITE(&I.Scratch,*)"Store",&R.StoreSeq,&R.PrevStoreID,&R.SourceDCs &D.Rank = &R.PrevStoreID &B.EntID = &R.SourceDCs CALL Store(queStores,&B.EntID,&D.Rank) &R.StoreSeq = QueueLength(queStores) + 1 &R.PrevStoreID = &R.StoreID &R.SourceDCs = 0 ENDIF &R.SourceDCs = &R.SourceDCs + 1 lnkInfo(bigRecord)%regStoreSeq = &R.StoreSeq WRITE(&I.Scratch,*)bigRecord,lnkInfo(bigRecord)%regDCseq,lnkInfo(bigRecord)%regStoreSeq,{t.D}DistTranspData(bigRecord,&R.DCidColumn), & {t.D}DistTranspData(bigRecord,&R.StoreIDcolumn),lnkInfo(bigRecord)%dblCost IF(.NOT.ASSOCIATED(qelStoreRecordsP%qelAft))THEN WRITE(&I.Scratch,*)"Store",&R.StoreSeq,&R.PrevStoreID,&R.SourceDCs &D.Rank = &R.PrevStoreID &B.EntID = &R.SourceDCs CALL Store(queStores,&B.EntID,&D.Rank) EXIT ENDIF qelStoreRecordsP=>qelStoreRecordsP%qelAft ENDDO WRITE(&I.Scratch,*)"Topic: End of Store records" &R.TotalStores = QueueLength(queStores) !Allocate memory for Store objects ALLOCATE(rtsStore(0:&R.TotalStores)) -{Trans} -{Object.7} InitialPlan.[7]Sort out Stores Info !---------------------------------------- +{Object.9} InitialPlan.[9]InitialPlan +{Trans} !Surrogates sent from InitialPlan.[5]DCsStoresAndLinks will arrive here in lowest to highest cost order !Surrogate property B.FlowLink contains value of a DC-Retail Store connection's link/arc number &R.DCseq = lnkInfo(@B.FlowLink)%regDCseq !Sequence number of DC in the link &R.StoreSeq = lnkInfo(@B.FlowLink)%regStoreSeq !Sequence number of Retail Store in the link &R.DCid = {t.D}DistTranspData(@B.FlowLink,&R.DCidColumn) !&R.DCid = dcDC(lnkInfo(@B.FlowLink)%regDCseq)%regID !Not tested. Decided to leave prev code along &R.StoreID = {t.D}DistTranspData(@B.FlowLink,&R.StoreIDcolumn) !&R.StoreID = rtsStore(lnkInfo(@B.FlowLink)%regStoreSeq)%regID !Maximum flow along this link cannot be more than currently remaining capacity of the DC or ...currently !unfulfilled demand of the Retail Store &B.Flow = MinF(dcDC(&R.DCseq)%bigRemCapacity, rtsStore(&R.StoreSeq)%bigRemDemand) !WRITE(21,*)"Arrival",@B.FlowLink,&R.DCseq,&R.StoreSeq,"from DC", & !&R.DCid,"to Store",&R.StoreID,lnkInfo(@B.FlowLink)%dblCost, & !dcDC(&R.DCseq)%bigRemCapacity,rtsStore(&R.StoreSeq)%bigRemDemand,&B.Flow IF(&B.Flow > 0)THEN dcDC(&R.DCseq)%bigRemCapacity = dcDC(&R.DCseq)%bigRemCapacity - &B.Flow rtsStore(&R.StoreSeq)%bigRemDemand = rtsStore(&R.StoreSeq)%bigRemDemand - &B.Flow lnkInfo(@B.FlowLink)%bigFlow = &B.Flow ENDIF -{Trans} +{SignalTarget} -{SignalTarget} -{Object.9} InitialPlan.[9]InitialPlan !---------------------------------------- +{Object.11} InitialPlan.[11]InitialPlan--->|SolutionReport INTEGER(big) :: bigDC INTEGER :: intAlStat LOGICAL :: logTempTrace +{Branch} {nop.L}Branch={EventsRemaining() < 1} -{Branch} +{Trans} $L.Trace = logYes $L.W = logYes $L.Q = logYes ! logNo $B.MaxEventsReq = 200000 DEALLOCATE({t.D}DistTranspData) !All raw data have been processed and entered into dcDC,rtsStore and lnkInfo logTempTrace = $L.Trace $L.Trace = logNo CALL DrainQueue(queDCrecords,"DC records") CALL DrainQueue(queStoreRecords,"Store records") $L.Trace = logTempTrace &L.SystemInfo = &R.TotalStores > &R.SystemInfo &R.HopsLimit = 2 * &R.TotalDCs - 1 !2M - 1 &R.MajorIterationLimit = 10 &R.MajorIteration = 0 &R.CostTable = 0 &I.DeficientStoreLinkedDCs = 0 &R.Basis = 1 {?|&R.HopsLimit} WRITE(*,*) &B.TotalNodes = &R.TotalDCs + &R.TotalStores !ALLOCATE(logVisited(ent%sur%bigLimit,&B.TotalNodes),STAT=intAlStat) !IF(intAlStat /= 0)CALL ErrMsg(9,0,"***Error allocating memory for logVisited matrix") !WRITE($I.LOG,*)"DIM logVisited",LBOUND(logVisited),UBOUND(logVisited),ent%sur%bigLimit dcDC(1:)%logRemCapacity = dcDC(1:)%bigRemCapacity > 0 dcDC(1:)%intShortStores = 0 !rtsStore(1:)%logRemDemand = rtsStore(1:)%bigRemDemand > 0 &B.RemDemandAftInitialSol = SUM(rtsStore(1:)%bigRemDemand) !Track DCs with units available to be shipped DO bigDC = 1,&R.TotalDCs IF (dcDC(bigDC)%logRemCapacity) THEN &D.Rank = dcDC(bigDC)%regID CALL Store(queUnused,bigDC,&D.Rank) ENDIF END DO &100.ReportName = "~ Initial Best Solution With Potential Constraints Violations" &100.LinksFile = "Links1.TXT" &100.SupplyFlowsFile = "SupplyFlows1.TXT" IF (&L.SystemInfo) THEN &I.SystemInfo = 1 WRITE(*,*)"SystemInfo",&I.SystemInfo CALL SystemCommand("SystemInfo >SystemInfo.TXT") END IF -{Trans} -{Object.11} InitialPlan.[11]InitialPlan--->|SolutionReport !---------------------------------------- +{Object.13} InitialPlan.[13]SolutionReport--->|MakeItFeasible +{Branch} {nop.L}Branch={QueueLength(queShortage) > 0} -{Branch} +{Trans} lnkInfo(:)%bigPrevFlow = lnkInfo(:)%bigFlow -{Trans} -{Object.13} InitialPlan.[13]SolutionReport--->|MakeItFeasible !---------------------------------------- +{Object.18} InitialPlan.[18]MakeItFeasible--->|SolutionReport +{Trans} CALL WriteSummaryResults("TArc 18") &100.ReportName = "~ Final Best Solution" &100.LinksFile = "Links2.TXT" &100.SupplyFlowsFile = "SupplyFlows2.TXT" -{Trans} -{Object.18} InitialPlan.[18]MakeItFeasible--->|SolutionReport -{Page}InitialPlan ////////////////////////////////////////// +{Page}MakeItFeasible ! 3 LaunchMajorIteration /10/29/2010 05:13:06.350 !---------------------------------------- +{Object.1} MakeItFeasible.[1]DistributionCenter INTEGER(big) :: bigIndx INTEGER(big) :: bigBaseSur +{Trans} bigBaseSur = bigSur WRITE(&35.State,*)"Landed: DC Send",@B.DCseq,dcDC(@B.DCseq)%regID,TRIM(StrSurName(bigSur)) {?|&35.State} &B.DatNetNode = @B.DCseq CALL SetHasBeenAt(bigSur,logYes,&B.DatNetNode) !logVisited(bigSur,&B.DatNetNode) = logYes &B.EntryArc = @B.Record &R.ConnectedStores = dcDC(@B.DCseq)%regStores DO bigIndx = 1, &R.ConnectedStores bigSur = bigBaseSur @B.StoreSeq = BigStoreSeqIndx(bigSur,@B.DCseq,bigIndx) &L.EntryArc = &B.EntryArc == @B.Record !@B.Record is obtained in StoreSeq function {?|@B.DCseq} {?|bigIndx} {?|&R.ConnectedStores} {?|@B.Record} {?|@B.StoreSeq} {?|&L.EntryArc} {??|"----------" IF (&L.EntryArc) CYCLE CALL CreateCopySur(bigBaseSur,bigSur) !Initialize new Surrogate properties with the orginal's; then update the new below as relevant !logVisited(bigSur,:) = logVisited(bigBaseSur,:) @B.TargetNode = &R.TotalDCs + @B.StoreSeq @L.DatNetSur = logYes CALL SendToSuccessors(bigSur) END DO bigSur = bigBaseSur @L.DatNetSur = logNo -{Trans} -{Object.1} MakeItFeasible.[1]DistributionCenter !---------------------------------------- +{Object.3} MakeItFeasible.[3]LaunchMajorIteration INTEGER(big) :: bigDC,bigBaseSur,bigIndx,bigHighestLink LOGICAL :: logRemCapacity +{Trans} bigBaseSur = bigSur @L.DatNetSur = logYes @B.Record = 0 !CALL ResetChainLinks(bigSur) CALL InitHasBeenAt(bigSur,&B.TotalNodes) !logVisited(:,:) = logYes !logNo @D.RunningCostPerUnit = 0._dbl !Casts zero with a KIND dbl value dcDC(:)%dblBestCost = $B.BigM !0._dbl dcDC(:)%bigBestLink = 0 dcDC(:)%logInCostMatrix = logNo &I.RelevantCostDCs = 0 &D.GrandTotalPrev = &D.GrandTotal &B.SUMofRemDemandPrev = &B.SUMofRemDemand &R.MajorIteration = &R.MajorIteration + 1 {?|&R.MajorIteration} CALL SetConceptualClock($I.LOG,0.0_dbl,"++++++ Setting Simulated Clock to Zero for Major Iteration ++++++") dcDC(:)%dblBestCost = dblBigM !Sets dblBestCost values of all DCs to largest possible value in preparation for minimum cost path travel rtsStore(:)%dblBestCost = dblBigM !Same for all Retail Stores as in case of DCs &B.ThreadsTotal = 0 &B.ThreadsAbandoned = 0 &B.ThreadsFullcycle = 0 &L.AllDemandSatisfied = logNo &B.UnusedQueueLength = QueueLength(queUnused) {?|&B.UnusedQueueLength} qelUnusedP => queUnused%Head DO bigDC = 1,&B.UnusedQueueLength logRemCapacity = dcDC(qelUnusedP%bigEntID)%logRemCapacity IF ($L.W) & WRITE(sys%intLOG,*)"bigDC,bigEntID,logRemCapacity",bigDC,qelUnusedP%bigEntID,logRemCapacity IF (logRemCapacity) THEN CALL CreateCopySur(bigBaseSur,bigSur) !Initialize new Surrogate properties with the orginal's; then update the new below as relevant !logVisited(bigSur,:) = logVisited(bigBaseSur,:) @B.SourceDCseq = qelUnusedP%bigEntID @B.DCseq = @B.SourceDCseq CALL SetHasBeenAt(bigSur,logYes,@B.DCseq) !logVisited(bigSur,@B.DCseq) = logYes dcDC(@B.DCseq)%dblBestCost = 0. {?|@B.SourceDCseq} CALL Store(queMajorIteration,bigSur) !To ensure all surrogates are initialized before any start traveling END IF qelUnusedP => qelUnusedP%qelAft END DO DO bigDC = 1,QueueLength(queMajorIteration) CALL Pull(queMajorIteration,bigSur) &R.SourceDCid = dcDC(@B.DCseq)%regID &R.DCid = &R.SourceDCid {?|bigSur} {?|@B.SourceDCseq} {?|&R.SourceDCid} {?|@B.Record} {?|@B.DCseq} {?|&R.DCid} {?|@D.RunningCostPerUnit} CALL SendToSuccessors(bigSur) END DO bigSur = bigBaseSur @L.DatNetSur = logNo -{Trans} -{Object.3} MakeItFeasible.[3]LaunchMajorIteration !---------------------------------------- +{Object.4} MakeItFeasible.[4]RetailStore INTEGER(big) :: bigIndx INTEGER(big) :: bigBaseSur +{Trans} bigBaseSur = bigSur WRITE(&35.State,*)"Landed: Store",@B.StoreSeq,rtsStore(@B.StoreSeq)%regID,TRIM(StrSurName(bigSur)) {?|&35.State} &B.DatNetNode = &R.TotalDCs + @B.StoreSeq CALL SetHasBeenAt(bigSur,logYes,&B.DatNetNode) !logVisited(bigSur,&B.DatNetNode) = logYes &B.EntryArc = @B.Record &R.ConnectedDCs = rtsStore(@B.StoreSeq)%regDCs &D.BestCost = rtsStore(@B.StoreSeq)%dblBestCost &L.Superceded = @D.RunningCostPerUnit > &D.BestCost IF (&L.Superceded) THEN !Will not send to successors and will be discarded {?|&B.EntryArc} {?|@D.RunningCostPerUnit} {?|&D.BestCost} {?|&L.Superceded} ELSE rtsStore(@B.StoreSeq)%bigBestLink = @B.Record WRITE($I.LOG,"(2(I4,I6),I7,F10.4,2(1X,A))")@B.SourceDCseq,dcDC(@B.SourceDCseq)%regID,@B.StoreSeq, & rtsStore(@B.StoreSeq)%regID,rtsStore(@B.StoreSeq)%bigBestLink,rtsStore(@B.StoreSeq)%dblBestCost, & TRIM(StrSurName(bigSur)),"Upd Best Lnk [4]RetailStore" DO bigIndx = 1, &R.ConnectedDCs bigSur = bigBaseSur @B.DCseq = BigDcSeqIndx(bigSur,@B.StoreSeq,bigIndx) &L.EntryArc = &B.EntryArc == @B.Record !@B.Record of forward link is obtained in DCseq function {??|"----------" {?|@B.StoreSeq} {?|bigIndx} {?|&R.ConnectedDCs} {?|@B.Record} {?|@B.DCseq} {?|&L.EntryArc} {??|"~~~~~~~~~~" IF (&L.EntryArc) CYCLE CALL CreateCopySur(bigBaseSur,bigSur) !Initialize new Surrogate properties with the orginal's; then update the new below as relevant !logVisited(bigSur,:) = logVisited(bigBaseSur,:) @B.TargetNode = @B.DCseq @L.DatNetSur = logYes CALL SendToSuccessors(bigSur) END DO END IF bigSur = bigBaseSur @L.DatNetSur = logNo -{Trans} -{Object.4} MakeItFeasible.[4]RetailStore !---------------------------------------- +{Object.5} MakeItFeasible.[5]DC->DC-BestCostQueue INTEGER(reg) :: regIndx INTEGER(big) :: bigBaseSur,bigBestCostToDCsur +{Trans} bigBaseSur = bigSur WRITE(&35.State,*)"Landed: DC Mtrx",@B.DCseq,dcDC(@B.DCseq)%regID,TRIM(StrSurName(bigSur)) {?|&35.State} &B.EntryArc = @B.Record &R.ConnectedStores = dcDC(@B.DCseq)%regStores &D.BestCost = dcDC(@B.DCseq)%dblBestCost &L.Superceded = @D.RunningCostPerUnit > &D.BestCost IF (&L.Superceded) THEN !Will not send to successors and will be discarded {?|&B.EntryArc} {?|&D.BestCost} {?|&L.Superceded} @L.DatNetSur = logNo ELSE &L.ShortStores = dcDC(@B.DCseq)%logShortStores dcDC(@B.DCseq)%bigBestLink = @B.Record dcDC(@B.DCseq)%dblBestCost = @D.RunningCostPerUnit {?|@B.SourceDCseq} {?|@B.DCseq} {?|&L.ShortStores} IF (&L.ShortStores) THEN IF (.NOT. dcDC(@B.DCseq)%logInCostMatrix) THEN dcDC(@B.DCseq)%logInCostMatrix = logYes &I.RelevantCostDCs = &I.RelevantCostDCs + 1 END IF WRITE($I.LOG,"(2(I4,I6),I7,F10.4,2(1X,A))")@B.SourceDCseq,dcDC(@B.SourceDCseq)%regID,@B.DCseq,dcDC(@B.DCseq)%regID, & dcDC(@B.DCseq)%bigBestLink,dcDC(@B.DCseq)%dblBestCost,TRIM(StrSurName(bigSur)),"Upd Best Lnk [5]DC->DC-BestCostQueue" CALL CreateCopySur(bigSur,bigBestCostToDCsur) !logVisited(bigBestCostToDCsur,:) = logVisited(bigSur,:) CALL Store(queBestCostToDCs,bigBestCostToDCsur,@D.RunningCostPerUnit) END IF END IF {?|@D.RunningCostPerUnit} bigSur = bigBaseSur &L.MakeDCtoDCBestCostMatrix = .NOT. @L.DatNetSur .AND. EventsRemaining() < 1 -{Trans} -{Object.5} MakeItFeasible.[5]DC->DC-BestCostQueue !---------------------------------------- +{Object.6} MakeItFeasible.[6]RetailStore--->|DC->DC-BestCostQueue +{Branch} {?|@L.DatNetSur} {nop.L}Branch = @L.DatNetSur IF (@L.DatNetSur) THEN &L.HasVisitedTarget = HasBeenAt(bigSur,@B.TargetNode) !&L.HasVisitedTarget = logVisited(bigSur,@B.TargetNode) {?|@B.StoreSeq} {?|@B.DCseq} {?|@B.Record} {?|&L.HasVisitedTarget} {nop.L}Branch = .NOT. &L.HasVisitedTarget IF ({nop.L}Branch) THEN &B.Flow = lnkInfo(@B.Record)%bigFlow &L.SlackToDC = &B.Flow > 0 {?|&B.Flow} {?|&L.SlackToDC} &D.TargetDCbestCost = dcDC(@B.DCseq)%dblBestCost @D.StoreToDCdecrease = lnkInfo(@B.Record)%dblCost {?|@D.RunningCostPerUnit} {?|@D.StoreToDCdecrease} {?|&D.TargetDCbestCost} @D.RunningCostPerUnit = @D.RunningCostPerUnit - @D.StoreToDCdecrease &L.LowerCost = @D.RunningCostPerUnit < &D.TargetDCbestCost {?|@D.RunningCostPerUnit} {?|&L.LowerCost} {nop.L}Branch = &L.SlackToDC .AND. &L.LowerCost END IF END IF !of @L.DatNetSur IF (.NOT. (@L.DatNetSur .OR. {nop.L}Branch)) THEN IF (EventsRemaining() < 1) & {Signal.15} END IF -{Branch} +{Trans} dcDC(@B.DCseq)%dblBestCost = @D.RunningCostPerUnit CALL LinkProperties(@B.Record) WRITE(&75.Note,"(I5,F10.3,2I5,F10.3,A,2I5,F10.3,I5,1X,A)")@B.Record,&D.Cost,&R.DCseq,&R.DCid,&D.BestDCcost, & " <-",&R.StoreSeq,&R.StoreID,&D.BestStoreCost,@B.SourceDCseq,TRIM(StrSurName(bigSur)) !CALL AddLinkToChain(bigSur,@B.Record,&75.Note) -{Trans} +{Duration} !Clock/cost handled through @D.RunningCostPerUnit as cumulative cost to a DC can be < clock position -{Duration} +{SignalTarget} -{SignalTarget} -{Object.6} MakeItFeasible.[6]RetailStore--->|DC->DC-BestCostQueue !---------------------------------------- +{Object.7} MakeItFeasible.[7]TradeRoute +{Trans} IF (&L.UpdateSolution) THEN &L.GrandTotIncrease = &D.GrandTotal > &D.GrandTotalPrev &L.GrandRemDecrease = &B.SUMofRemDemand < &B.SUMofRemDemandPrev &L.ContinueSearch = &L.GrandTotIncrease .AND. &L.GrandRemDecrease .AND. .NOT. &L.AllDemandSatisfied &1.Cr = " " {?|&D.GrandTotalPrev} {?|&D.GrandTotal} {?|&L.GrandTotIncrease} {?|@B.FlowChange} {?|&B.SUMofRemCapacityPrev} {?|&B.SUMofRemCapacity} {?|&B.SUMofRemDemandPrev} {?|&B.SUMofRemDemand} {?|&B.RemCapDemDiffPrev} {?|&B.RemCapDemDiff} {?|&L.GrandRemDecrease} ELSE &L.ContinueSearch = logYes &L.AllDemandSatisfied = logNo END IF !{?|@L.UpdateSolution} {?|&L.AllDemandSatisfied} {?|&L.ContinueSearch} $L.YellowFlag = &R.CostTable > 20 -{Trans} -{Object.7} MakeItFeasible.[7]TradeRoute !---------------------------------------- +{Object.9} MakeItFeasible.[9]LaunchMajorIteration--->|DistributionCenter +{Branch} {nop.L}Branch={@L.DatNetSur} -{Branch} -{Object.9} MakeItFeasible.[9]LaunchMajorIteration--->|DistributionCenter !---------------------------------------- +{Object.10} MakeItFeasible.[10]DC->DC-BestCostQueue--->|DistributionCenter +{Branch} {?|&I.RelevantCostDCs} {?|&I.DeficientStoreLinkedDCs} {nop.L}Branch = @L.DatNetSur IF ({nop.L}Branch) THEN {nop.L}Branch = &I.RelevantCostDCs < &I.DeficientStoreLinkedDCs .OR. EventsRemaining() > 0 IF (.NOT. {nop.L}Branch) & {Signal.15} END IF -{Branch} +{SignalTarget} -{SignalTarget} -{Object.10} MakeItFeasible.[10]DC->DC-BestCostQueue--->|DistributionCenter !---------------------------------------- +{Object.11} MakeItFeasible.[11]DistributionCenter--->|RetailStore +{Branch} {?|@L.DatNetSur} {nop.L}Branch = @L.DatNetSur IF ({nop.L}Branch) THEN {?|@B.TargetNode} &L.HasVisitedTarget = HasBeenAt(bigSur,@B.TargetNode) !&L.HasVisitedTarget = logVisited(bigSur,@B.TargetNode) &L.RemDemand = rtsStore(@B.StoreSeq)%logRemDemand {?|@B.SourceDCseq} {?|@B.DCseq} {?|@B.StoreSeq} {?|@B.Record} {?|&L.HasVisitedTarget} {?|&L.RemDemand} {nop.L}Branch = .NOT. (&L.HasVisitedTarget .OR. &L.RemDemand) IF ({nop.L}Branch) THEN &B.Flow = lnkInfo(@B.Record)%bigFlow &B.OriginalDemand = rtsStore(@B.StoreSeq)%bigDemand &B.OriginalSupply = dcDC(@B.SourceDCseq)%bigCapacity &L.SlackToStore = &B.OriginalDemand - &B.Flow > 0 .AND. &B.OriginalSupply > 0 {?|&B.OriginalSupply} {?|&B.OriginalDemand} {?|&B.Flow} {?|&L.SlackToStore} &D.TargetStoreBestCost = rtsStore(@B.StoreSeq)%dblBestCost @D.DCtoStoreIncrease = lnkInfo(@B.Record)%dblCost {?|@D.RunningCostPerUnit} {?|@D.DCtoStoreIncrease} {?|&D.TargetStoreBestCost} @D.RunningCostPerUnit = @D.RunningCostPerUnit + @D.DCtoStoreIncrease &L.LowerCost = @D.RunningCostPerUnit < &D.TargetStoreBestCost IF (@D.RunningCostPerUnit < DblTime()) THEN !Clock shouldn't be advanced if running cost is trying to catch up... @D.DCtoStoreIncrease = 0. !due to high costs on certain segments that held it up ELSE IF (DblTime() + @D.DCtoStoreIncrease > @D.RunningCostPerUnit) & @D.DCtoStoreIncrease = @D.RunningCostPerUnit - DblTime() END IF {?|@D.RunningCostPerUnit} {?|&L.LowerCost} {nop.L}Branch = &L.SlackToStore .AND. &L.LowerCost END IF END IF !of {nop.L}Branch IF (.NOT. (@L.DatNetSur .OR. {nop.L}Branch)) THEN IF (EventsRemaining() < 1) & {Signal.15} END IF -{Branch} +{Trans} rtsStore(@B.StoreSeq)%dblBestCost = @D.RunningCostPerUnit CALL LinkProperties(@B.Record) WRITE(&75.Note,"(I5,F10.3,2I5,F10.3,A,2I5,F10.3,I5,1X,A)")@B.Record,&D.Cost,&R.DCseq,&R.DCid,&D.BestDCcost, & " ->",&R.StoreSeq,&R.StoreID,&D.BestStoreCost,@B.SourceDCseq,TRIM(StrSurName(bigSur)) !CALL AddLinkToChain(bigSur,@B.Record,&75.Note) -{Trans} +{Duration} {nop.D}Duration={@D.DCtoStoreIncrease}... -{Duration} +{SignalTarget} -{SignalTarget} -{Object.11} MakeItFeasible.[11]DistributionCenter--->|RetailStore !---------------------------------------- +{Object.13} MakeItFeasible.[13]DeQueueBestCostQueue INTEGER(big) :: bigDCseq,bigStoreSeq,bigBaseSur,bigSurToStore +{Trans} bigBaseSur = bigSur CALL SetConceptualClock($I.LOG,0.0_dbl,"++++++ Setting Simulated Clock to Zero for Hops to Unfulfilled Stores ++++++") IF ($L.W) & CALL WriteDCtoDCcostTable() dcDC(1:)%logBestCostFound = logNo DO bigDCseq = 1,QueueLength(queBestCostToDCs) CALL Pull(queBestCostToDCs,bigSur,@D.RunningCostPerUnit) &L.BestCostTo = dcDC(@B.DCseq)%logBestCostFound IF (&L.BestCostTo) THEN {?|&L.BestCostTo} ELSE dcDC(@B.DCseq)%logBestCostFound = logYes dcDC(@B.DCseq)%bigBestLink = @B.Record &L.ShortStores = dcDC(@B.DCseq)%logShortStores IF ($L.W) & WRITE($I.LOG,"(A,I3,I8,I4,I5,2X,I5,I6,F10.3,2I6,1X,A)") & "Track @B.SourceDCseq & supply",bigDCseq,dcDC(@B.SourceDCseq)%bigRemCapacity,@B.SourceDCseq,DCid(@B.SourceDCseq), & @B.DCseq,DCid(@B.DCseq),@D.RunningCostPerUnit,@B.Record,dcDC(@B.DCseq)%bigBestLink,TRIM(StrSurName(bigSur)) WRITE($I.LOG,"(2(I4,I6),I7,F10.4,2(1X,A))")@B.SourceDCseq,dcDC(@B.SourceDCseq)%regID,@B.DCseq,dcDC(@B.DCseq)%regID, & dcDC(@B.DCseq)%bigBestLink,dcDC(@B.DCseq)%dblBestCost,TRIM(StrSurName(bigSur)),"Upd Best Lnk BestCostMatrix" IF (&L.ShortStores) THEN DO bigStoreSeq = 1,dcDC(@B.DCseq)%regStores @B.StoreSeq = BigStoreSeqIndx(bigSur,@B.DCseq,bigStoreSeq) CALL CreateCopySur(bigSur,bigSurToStore) !logVisited(bigSurToStore,:) = logVisited(bigSur,:) CALL SendToSuccessors(bigSurToStore,bigSeq) !Optional argument bigSeq will re-stamp surrogate's logical node seq # END DO ELSE {?|&L.ShortStores} END IF !of &L.ShortStores END IF !of .NOT. dcDC(@B.DCseq)%logBestCostFound CALL DisposeSur(bigSur) END DO bigSur = bigBaseSur @L.DatNetSur = logNo -{Trans} -{Object.13} MakeItFeasible.[13]DeQueueBestCostQueue !---------------------------------------- +{Object.14} MakeItFeasible.[14]DeQueueBestCostQueue--->|TradeRoute +{Branch} @D.Cost = lnkInfo(@B.Record)%dblCost &B.Flow = lnkInfo(@B.Record)%bigFlow &L.RemDemand = rtsStore(@B.StoreSeq)%logRemDemand {?|@B.SourceDCseq} {?|@B.DCseq} {?|@B.StoreSeq} {?|@B.Record} {?|&B.Flow} {?|@D.RunningCostPerUnit} {?|@D.Cost} {?|&L.RemDemand} {nop.L}Branch = @L.DatNetSur .AND. &L.RemDemand -{Branch} +{Trans} CALL LinkProperties(@B.Record) &D.BestStoreCost = dcDC(@B.DCseq)%dblBestCost + @D.Cost !Recalculating here to keep WRITE below identical with others WRITE(&75.Note,"(I5,F10.3,2I5,F10.3,A,2I5,F10.3,I5,1X,A)")@B.Record,&D.Cost,&R.DCseq,&R.DCid,&D.BestDCcost, & " ->",&R.StoreSeq,&R.StoreID,&D.BestStoreCost,@B.SourceDCseq,TRIM(StrSurName(bigSur)) !CALL AddLinkToChain(bigSur,@B.Record,&75.Note) -{Trans} +{Duration} {nop.D}Duration={@D.RunningCostPerUnit + @D.Cost}... !Since clock is reset to zero in the node where DC-to-DC cost matrix is created -{Duration} -{Object.14} MakeItFeasible.[14]DeQueueBestCostQueue--->|TradeRoute !---------------------------------------- +{Object.15} MakeItFeasible.[15]DC->DC-BestCostQueue--->|DeQueueBestCostQueue +{Branch} {nop.L}Branch = &L.MakeDCtoDCBestCostMatrix -{Branch} +{SignalTarget} &R.CostTable = &R.CostTable + 1 WRITE(&50.CostTableUpdate,*)"Surplus-DCs-to-Other-DCs Cost Matrix Update",&R.CostTable WRITE($I.LOG,"(2A)")&1.Cr,TRIM(&50.CostTableUpdate) WRITE(*,"(2A)")&1.Cr,TRIM(&50.CostTableUpdate) &1.Cr = "+" -{SignalTarget} -{Object.15} MakeItFeasible.[15]DC->DC-BestCostQueue--->|DeQueueBestCostQueue !---------------------------------------- +{Object.16} MakeItFeasible.[16]TradeRoute--->|LaunchMajorIteration +{Branch} {nop.L}Branch = &L.ContinueSearch .AND. EventsRemaining() < 1 IF ({nop.L}Branch .AND. &R.TotalStores > 10) & REWIND $I.LOG {?|&L.ContinueSearch} IF ({nop.L}Branch .AND. &L.SystemInfo) THEN &I.SystemInfo = &I.SystemInfo + 1 WRITE(*,*)"SystemInfo",&I.SystemInfo CALL SystemCommand("SystemInfo >>SystemInfo.TXT") END IF -{Branch} -{Object.16} MakeItFeasible.[16]TradeRoute--->|LaunchMajorIteration !---------------------------------------- +{Object.17} MakeItFeasible.[17]TradeRoute--->|ReturnToWriteReport +{Branch} {nop.L}Branch = &L.AllDemandSatisfied .OR. .NOT. &L.ContinueSearch IF ({nop.L}Branch) THEN &B.SUMofRemCapacity = SUM(dcDC(1:)%bigRemCapacity) CALL WriteSummaryResults("Arc 17") IF (EventsRemaining() > 0) THEN IF (&L.AllDemandSatisfied) THEN WRITE($I.LOG,*)"*** All demand satisfied. Draining Events queue to dispose off search surrogates. ***" ELSE WRITE($I.LOG,*)"*** Cannot improve solution further. Removing search surrogates from Events queue. ***" END IF CALL DrainEventsQueue() WRITE(*,*)"All demands satisfied. Removing search surrogates from Events queue." END IF END IF -{Branch} -{Object.17} MakeItFeasible.[17]TradeRoute--->|ReturnToWriteReport -{Page}MakeItFeasible ////////////////////////////////////////// +{Page}SolutionReport ! 1 DCsReport /10/29/2010 05:13:06.350 !---------------------------------------- +{Object.1} SolutionReport.[1]DCsReport +{Trans} !Write DCs report. How many units are shipped from each DC to each Retail Store it is allowed to supply. Calculate grand total cost. CALL OpenForWriting(&I.SupplyFlowsF,TRIM(modl%strPath) // TRIM(&100.SupplyFlowsFile),"SPLY","Transportation.NET-148") WRITE(&I.SupplyFlowsF,*)"Optimal DCs-to-Stores Transportation Flows Model" CALL WriteAuthorSignature(&I.SupplyFlowsF) WRITE(&I.SupplyFlowsF,"(/A/A/)")" Topic: From-DCs-to-Stores Flows " // TRIM(&100.ReportName) &D.GrandTotal = 0. DO bigDC = 1, &R.TotalDCs &B.Flows = 0 &D.Costs = 0. WRITE(&I.SupplyFlowsF,*)REPEAT("-",66) WRITE(&I.SupplyFlowsF,*)" " WRITE(&I.SupplyFlowsF,*)"DC Sequence:",bigDC WRITE(&I.SupplyFlowsF,*)"DC ID:",dcDC(bigDC)%regID WRITE(&I.SupplyFlowsF,*)"Flows from DC",dcDC(bigDC)%regID,"to",dcDC(bigDC)%regStores,"Stores..." WRITE(&I.SupplyFlowsF,*)" " WRITE(&I.SupplyFlowsF,'(A)')" Record Store UnitCost Flow FlowCost" DO bigFlowLink = 1, dcDC(bigDC)%regStores bigRecord = dcDC(bigDC)%bigLinkSeq(bigFlowLink) &B.Flow = lnkInfo(bigRecord)%bigFlow !IF(&B.Flow > 0)THEN &D.Cost = lnkInfo(bigRecord)%dblCost !/100. &D.FlowCost = &B.Flow * &D.Cost &B.Flows = &B.Flows + &B.Flow &D.Costs = &D.Costs + &D.FlowCost !&R.StoreID = {t.D}DistTranspData(bigRecord,&R.StoreIDcolumn) &R.StoreID = rtsStore(lnkInfo(bigRecord)%regStoreSeq)%regID WRITE(&I.SupplyFlowsF,'(3I10,F13.4,I10,F14.3)')bigFlowLink,bigRecord,&R.StoreID,&D.Cost,&B.Flow,&D.FlowCost !ENDIF ENDDO &D.GrandTotal = &D.GrandTotal + &D.Costs WRITE(&I.SupplyFlowsF,'(T44,I10,F14.3)')&B.Flows,&D.Costs WRITE(&I.SupplyFlowsF,*)" " WRITE(&I.SupplyFlowsF,'(A)')" DC capacity Total shipped Remaining capacity" WRITE(&I.SupplyFlowsF,'(I12,I15,I21)')dcDC(bigDC)%bigCapacity,&B.Flows,dcDC(bigDC)%bigRemCapacity ENDDO WRITE(&I.SupplyFlowsF,*)REPEAT("-",66) WRITE(&I.SupplyFlowsF,*)"Total costs:",&D.GrandTotal WRITE(&I.SupplyFlowsF,*)" " -{Trans} -{Object.1} SolutionReport.[1]DCsReport !---------------------------------------- +{Object.2} SolutionReport.[2]StoresReport +{Trans} !Write Retail Stores report. How many units are shipped to each Store from its permitted supply DC. Calculate grand total cost (again for verification). WRITE(&I.SupplyFlowsF,"(/A/A/)")" Topic: To-Stores-From-DCs Flows " // TRIM(&100.ReportName) &D.GrandTotal = 0. DO bigStore = 1, &R.TotalStores rtsStore(bigStore)%logRemDemand = rtsStore(bigStore)%bigRemDemand > 0 IF (rtsStore(bigStore)%logRemDemand) THEN WRITE(&40.Shortage,*)"Shortage at",bigStore,rtsStore(bigStore)%regID &D.Rank = rtsStore(bigStore)%regID CALL Store(queShortage,bigStore,&D.Rank) ELSE &40.Shortage = "" END IF &B.Flows = 0 &D.Costs = 0. WRITE(&I.SupplyFlowsF,*)REPEAT("-",66) WRITE(&I.SupplyFlowsF,*)" " WRITE(&I.SupplyFlowsF,*)"Store Sequence:",bigStore WRITE(&I.SupplyFlowsF,*)"Store ID:",rtsStore(bigStore)%regID WRITE(&I.SupplyFlowsF,*)"Flows to Store",rtsStore(bigStore)%regID,"from",rtsStore(bigStore)%regDCs,"DCs..." WRITE(&I.SupplyFlowsF,*)" " WRITE(&I.SupplyFlowsF,'(A)')" Record DC UnitCost Flow FlowCost" DO bigFlowLink = 1, rtsStore(bigStore)%regDCs &B.Record = rtsStore(bigStore)%bigLinkSeq(bigFlowLink) &B.Flow = lnkInfo(&B.Record)%bigFlow &B.DCseq = lnkInfo(&B.Record)%regDCseq IF(rtsStore(bigStore)%logRemDemand) THEN IF (dcDC(&B.DCseq)%intShortStores == 0) & &I.DeficientStoreLinkedDCs = &I.DeficientStoreLinkedDCs + 1 dcDC(&B.DCseq)%intShortStores = dcDC(&B.DCseq)%intShortStores + 1 END IF !IF(&B.Flow > 0)THEN bigRecord = rtsStore(bigStore)%bigLinkSeq(bigFlowLink) &D.Cost = lnkInfo(bigRecord)%dblCost !/100. &D.FlowCost = &B.Flow * &D.Cost &B.Flows = &B.Flows + &B.Flow &D.Costs = &D.Costs + &D.FlowCost !&R.DCid = {t.D}DistTranspData(bigRecord,&R.DCidColumn) &R.DCid = dcDC(&B.DCseq)%regID WRITE(&I.SupplyFlowsF,'(3I10,F13.4,I10,F14.3)')bigFlowLink,bigRecord,&R.DCid,&D.Cost,&B.Flow,&D.FlowCost !ENDIF ENDDO &D.GrandTotal = &D.GrandTotal + &D.Costs WRITE(&I.SupplyFlowsF,'(T44,I10,F14.3)')&B.Flows,&D.Costs WRITE(&I.SupplyFlowsF,*)" " WRITE(&I.SupplyFlowsF,'(A)')" Store Demand Total received Unfulfilled demand" WRITE(&I.SupplyFlowsF,'(I13,I16,I21,1X,A)')rtsStore(bigStore)%bigDemand,&B.Flows, & rtsStore(bigStore)%bigRemDemand,TRIM(&40.Shortage) ENDDO WRITE(&I.SupplyFlowsF,*)REPEAT("-",66) WRITE(&I.SupplyFlowsF,*)"Total costs:",&D.GrandTotal CALL CloseFile(&I.SupplyFlowsF,"Transportation.NET-540") dcDC(1:)%logShortStores = dcDC(1:)%intShortStores > 0 -{Trans} -{Object.2} SolutionReport.[2]StoresReport !---------------------------------------- +{Object.4} SolutionReport.[4]SurplusDeficitReport INTEGER :: intIndx,intIndy +{Trans} {?|&B.Records} {?|&100.LinksFile} CALL OpenForWriting(&I.Links,TRIM(modl%strPath) // TRIM(&100.LinksFile),"LINK","Transportation.NET-857") WRITE(&I.SupplyFlowsF,*)"Optimal DCs-to-Stores Transportation Flows Model" CALL WriteAuthorSignature(&I.SupplyFlowsF) WRITE(&I.SupplyFlowsF,"(/A/A/)")" Topic: Flows on Links " // TRIM(&100.ReportName) WRITE(&I.Links,*)"RESULTS SUMMARY" WRITE(&I.Links,*)" " WRITE(&I.Links,'(A,T35,F12.3,F12.3)')" Total cost:", & &D.GrandTotal !,SUM(lnkInfo(1:&B.Records)%bigFlow * lnkInfo(1:&B.Records)%dblCost) WRITE(&I.Links,'(A,T35,I12)')" Total capacity:", & SUM(dcDC(1:)%bigCapacity) WRITE(&I.Links,'(A,T35,I12)')" Total allocated capacity:", & SUM(dcDC(1:)%bigCapacity - dcDC(1:)%bigRemCapacity) WRITE(&I.Links,'(A,T35,I12)')" Total unused capacity:", & SUM(dcDC(1:)%bigRemCapacity) WRITE(&I.Links,'(A,T35,I12)')" Total demand:", & SUM(rtsStore(1:)%bigDemand) &B.SUMofRemDemand = SUM(rtsStore(1:)%bigRemDemand) WRITE(&I.Links,'(A,T35,I12)')" Total fulfilled demand:", & SUM(rtsStore(1:)%bigDemand) - &B.SUMofRemDemand WRITE(&I.Links,'(A,T35,I12)')" Total unfulfilled demand:", & &B.SUMofRemDemand WRITE(&I.Links,'(A,T35,I12)')" Capacity surplus/-deficiency:", & SUM(dcDC(1:)%bigRemCapacity) - SUM(rtsStore(1:)%bigRemDemand) WRITE(&I.Links,*)" " &B.QueueLength = QueueLength(queUnused) IF(&B.QueueLength > 0)THEN WRITE(&I.Links,*)"Following",&B.QueueLength,"DCs have unused supply..." WRITE(&I.Links,*)" " WRITE(&I.Links,'(A)')" DC Seq DC ID Unused" qelUnusedP => queUnused%Head DO intIndx = 1, &B.QueueLength bigDC = qelUnusedP%bigEntID WRITE(&I.Links,'(I10,I12,I12,I12,I12)')intIndx,bigDC,dcDC(bigDC)%regID,dcDC(bigDC)%bigRemCapacity qelUnusedP => qelUnusedP%qelAft ENDDO ENDIF &B.QueueLength = QueueLength(queShortage) IF(&B.QueueLength > 0)THEN WRITE(&I.Links,*)" " WRITE(&I.Links,*)"Following",&B.QueueLength,"stores have unfulfilled demand..." WRITE(&I.Links,*)" " WRITE(&I.Links,'(A,A)')" Store Seq Store ID Shortage", & " |---------Connected DC 1--------|--------Connected DC 2---------|--------Connected DC 3---------|" IF (ALLOCATED(lnkDCsP)) DEALLOCATE(lnkDCsP) ALLOCATE(lnkDCsP(1:&B.QueueLength,1:3)) qelShortageP => queShortage%Head DO intIndx = 1, &B.QueueLength bigStore = qelShortageP%bigEntID rtsP => rtsStore(bigStore) lnkDCsP(intIndx,1:rtsP%regDCs) = lnkInfo(rtsP%bigLinkSeq(1:rtsP%regDCs)) dcP(1:rtsP%regDCs) = dcDC(lnkDCsP(intIndx,1:rtsP%regDCs)%regDCseq) WRITE(&I.Links,'(I10,I12,I12,I12,A,3(2I10,F10.3,A))')intIndx,bigStore,rtsStore(bigStore)%regID, & rtsStore(bigStore)%bigRemDemand," |", & (lnkDCsP(intIndx,intIndy)%regDCseq,dcP(intIndy)%regID,lnkDCsP(intIndx,intIndy)%dblCost," |",intIndy = 1,rtsP%regDCs) qelShortageP => qelShortageP%qelAft ENDDO ENDIF WRITE(&I.Links,*) -{Trans} -{Object.4} SolutionReport.[4]SurplusDeficitReport !---------------------------------------- +{Object.7} SolutionReport.[7]LinksReport +{Trans} {?|&B.Records} {?|&100.LinksFile} CALL WriteLinksInSolution(&I.Links) CALL CloseFile(&I.Links,"Transportation.NET-604") -{Trans} -{Object.7} SolutionReport.[7]LinksReport -{Page}SolutionReport ////////////////////////////////////////// +{Page}TradeRoute ! 2 UnfulfilledStore /10/29/2010 05:13:06.350 !---------------------------------------- +{Object.2} TradeRoute.[2]UnfulfilledStore +{Trans} WRITE(sys%intLOG,*)"Topic: Solution: Tracking current route feasibility back to Source DC..." &R.Hops = 0 &L.UpdateSolution = logNo @B.RemSourceDCcapacity = dcDC(@B.SourceDCseq)%bigRemCapacity @B.RemDemand = rtsStore(@B.StoreSeq)%bigRemDemand !Max delta-flow must be remaining demand at current Store or remaining current capacity at source DC, whichever is less @B.FlowChange = MinF(@B.RemDemand,@B.RemSourceDCcapacity) &B.RouteSlack = $B.BigM &B.BestLinkIn = @B.Record CALL LinkProperties(&B.BestLinkIn) {?|@B.SourceDCseq} {?|@B.RemSourceDCcapacity} {?|@B.StoreSeq} {?|@B.RemDemand} {?|@B.FlowChange} {?|&B.BestLinkIn} {?|&R.MajorIteration} CALL ShowTravelNotes(bigSur) -{Trans} -{Object.2} TradeRoute.[2]UnfulfilledStore !---------------------------------------- +{Object.3} TradeRoute.[3]DistributionCenter +{Trans} &R.SourceDCseq = @B.SourceDCseq &L.ReachedSourceDC = &R.DCseq == &R.SourceDCseq &B.BestLinkIn = dcDC(&R.DCseq)%bigBestLink &R.Hops = &R.Hops + 1 {?|&R.Hops} {?|@B.FlowChange} {?|&R.DCseq} {?|&B.BestLinkIn} {?|&L.ReachedSourceDC} IF (&R.Hops > &R.HopsLimit) & STOP "Hops limit reached" -{Trans} -{Object.3} TradeRoute.[3]DistributionCenter !---------------------------------------- +{Object.4} TradeRoute.[4]RetailStore +{Trans} &B.BestLinkIn = rtsStore(&R.StoreSeq)%bigBestLink {?|&R.StoreSeq} {?|&B.BestLinkIn} -{Trans} -{Object.4} TradeRoute.[4]RetailStore !---------------------------------------- +{Object.6} TradeRoute.[6]DistributionCenter--->|DistributionCenter +{Branch} {nop.L}Branch = &L.ReachedSourceDC .AND. @B.FlowChange > 0 IF ({nop.L}Branch) THEN IF ($L.W) & WRITE(sys%intLOG,*)"Topic: Solution: Update solution basis...",&R.Basis &L.UpdateSolution = logYes &R.Basis = &R.Basis + 1 &B.BestLinkIn = @B.Record rtsStore(@B.StoreSeq)%dblBestCost = dcDC(&R.DCseq)%dblBestCost + lnkInfo(&B.BestLinkIn)%dblCost &B.PrevLinkFlow = lnkInfo(&B.BestLinkIn)%bigFlow &D.SumTradeRouteCij = lnkInfo(&B.BestLinkIn)%dblCost &B.NewLinkFlow = &B.PrevLinkFlow + @B.FlowChange lnkInfo(&B.BestLinkIn)%bigFlow = &B.NewLinkFlow &B.SUMofRemDemandPrev = SUM(rtsStore(1:)%bigRemDemand) &B.SUMofRemCapacityPrev = SUM(dcDC(1:)%bigRemCapacity) WRITE($I.LOG,"(A,I5,1X,A,5I7,2F10.3)")"TradeRoute:",&R.Basis,"ST",@B.StoreSeq,rtsStore(@B.StoreSeq)%regID, & &B.BestLinkIn,&B.PrevLinkFlow,&B.NewLinkFlow,&D.SumTradeRouteCij,&D.SumTradeRouteCij {?|&R.Basis} {?|@B.StoreSeq} {?|&B.BestLinkIn} {?|&B.PrevLinkFlow} {?|&B.NewLinkFlow} &R.DCseq = lnkInfo(&B.BestLinkIn)%regDCseq &B.BestLinkIn = dcDC(&R.DCseq)%bigBestLink END IF -{Branch} -{Object.6} TradeRoute.[6]DistributionCenter--->|DistributionCenter !---------------------------------------- +{Object.7} TradeRoute.[7]DistributionCenter--->|RetailStore +{Branch} CALL LinkProperties(&B.BestLinkIn,logYes) &B.SlackToDC = &B.Flow {?|&B.SlackToDC} {nop.L}Branch = .NOT. &L.ReachedSourceDC .AND. &B.SlackToDC > 0 IF ({nop.L}Branch) THEN @B.FlowChange = MinF(@B.FlowChange,&B.SlackToStore) ELSE {?|&L.ReachedSourceDC} IF (.NOT. &L.ReachedSourceDC) & {Signal.16} END IF -{Branch} +{SignalTarget} -{SignalTarget} -{Object.7} TradeRoute.[7]DistributionCenter--->|RetailStore !---------------------------------------- +{Object.8} TradeRoute.[8]UnfulfilledStore--->|DistributionCenter +{Branch} {nop.L}Branch = @B.FlowChange > 0 .AND. dcDC(@B.SourceDCseq)%bigRemCapacity > 0 IF ({nop.L}Branch) THEN CALL LinkProperties(&B.BestLinkIn,logYes) &B.SlackToStore = rtsStore(@B.StoreSeq)%bigRemDemand @B.FlowChange = MinF(@B.FlowChange,&B.SlackToStore) {?|&B.BestLinkIn} {?|&B.SlackToStore} ELSE {Signal.16} END IF -{Branch} +{SignalTarget} -{SignalTarget} -{Object.8} TradeRoute.[8]UnfulfilledStore--->|DistributionCenter !---------------------------------------- +{Object.9} TradeRoute.[9]RetailStore--->|DistributionCenter +{Branch} CALL LinkProperties(&B.BestLinkIn,logYes) &B.SlackToStore = rtsStore(&R.StoreSeq)%bigDemand - &B.Flow {?|&B.SlackToStore} {nop.L}Branch = &B.SlackToStore > 0 IF ({nop.L}Branch) THEN @B.FlowChange = MinF(@B.FlowChange,&B.SlackToDC) ELSE {Signal.16} END IF -{Branch} +{SignalTarget} -{SignalTarget} -{Object.9} TradeRoute.[9]RetailStore--->|DistributionCenter !---------------------------------------- +{Object.10} TradeRoute.[10]DistributionCenter +{Trans} &R.SourceDCseq = @B.SourceDCseq &L.ReachedSourceDC = &R.DCseq == &R.SourceDCseq IF (&L.ReachedSourceDC) THEN WRITE($I.LOG,"(A,I5,1X,A,5I7,2F10.3)")"TradeRoute:",&R.Basis,"DC",&R.DCseq,dcDC(&R.DCseq)%regID ELSE CALL LinkProperties(&B.BestLinkIn,logYes) {?|&B.BestLinkIn} END IF -{Trans} -{Object.10} TradeRoute.[10]DistributionCenter !---------------------------------------- +{Object.12} TradeRoute.[12]RetailStore +{Trans} CALL LinkProperties(&B.BestLinkIn,logYes) {?|&B.BestLinkIn} -{Trans} -{Object.12} TradeRoute.[12]RetailStore !---------------------------------------- +{Object.13} TradeRoute.[13]DistributionCenter--->|RetailStore +{Branch} {nop.L}Branch = .NOT. &L.ReachedSourceDC IF ({nop.L}Branch) THEN &B.PrevLinkFlow = lnkInfo(&B.BestLinkIn)%bigFlow &B.NewLinkFlow = &B.PrevLinkFlow - @B.FlowChange lnkInfo(&B.BestLinkIn)%bigFlow = &B.NewLinkFlow &D.SumTradeRouteCij = &D.SumTradeRouteCij - lnkInfo(&B.BestLinkIn)%dblCost {?|&B.PrevLinkFlow} {?|&B.NewLinkFlow} WRITE($I.LOG,"(A,I5,1X,A,5I7,2F10.3)")"TradeRoute:",&R.Basis,"DC",&R.DCseq,dcDC(&R.DCseq)%regID, & &B.BestLinkIn,&B.PrevLinkFlow,&B.NewLinkFlow,lnkInfo(&B.BestLinkIn)%dblCost,&D.SumTradeRouteCij &B.BestLinkIn = rtsStore(&R.StoreSeq)%bigBestLink END IF -{Branch} -{Object.13} TradeRoute.[13]DistributionCenter--->|RetailStore !---------------------------------------- +{Object.14} TradeRoute.[14]RetailStore--->|DistributionCenter +{Trans} IF ({nop.L}Branch) THEN &B.PrevLinkFlow = lnkInfo(&B.BestLinkIn)%bigFlow &B.NewLinkFlow = &B.PrevLinkFlow + @B.FlowChange lnkInfo(&B.BestLinkIn)%bigFlow = &B.NewLinkFlow &D.SumTradeRouteCij = &D.SumTradeRouteCij + lnkInfo(&B.BestLinkIn)%dblCost {?|&B.PrevLinkFlow} {?|&B.NewLinkFlow} WRITE($I.LOG,"(A,I5,1X,A,5I7,2F10.3)")"TradeRoute:",&R.Basis,"ST",&R.StoreSeq,rtsStore(&R.StoreSeq)%regID, & &B.BestLinkIn,&B.PrevLinkFlow,&B.NewLinkFlow,lnkInfo(&B.BestLinkIn)%dblCost,&D.SumTradeRouteCij &B.BestLinkIn = dcDC(&R.DCseq)%bigBestLink END IF -{Trans} -{Object.14} TradeRoute.[14]RetailStore--->|DistributionCenter !---------------------------------------- +{Object.15} TradeRoute.[15]DistributionCenter--->|BackToReferringNet +{Branch} {nop.L}Branch = &L.ReachedSourceDC IF ({nop.L}Branch) THEN @B.RemDemand = @B.RemDemand - @B.FlowChange @B.RemSourceDCcapacity = @B.RemSourceDCcapacity - @B.FlowChange rtsStore(@B.StoreSeq)%bigRemDemand = @B.RemDemand dcDC(@B.SourceDCseq)%bigRemCapacity = @B.RemSourceDCcapacity {?|&R.Basis} &B.SUMofRemDemand = SUM(rtsStore(1:)%bigRemDemand) &B.SUMofRemCapacity = SUM(dcDC(1:)%bigRemCapacity) &B.RemCapDemDiff = &B.SUMofRemCapacity - &B.SUMofRemDemand &B.RemCapDemDiffPrev = &B.SUMofRemCapacityPrev - &B.SUMofRemDemandPrev &L.AllDemandSatisfied = &B.SUMofRemDemand < 1 WRITE(sys%intLOG,*)REPEAT("-",25) &D.GrandTotal = SUM(lnkInfo(1:&B.Records)%bigFlow * lnkInfo(1:&B.Records)%dblCost) WRITE($I.LOG,"(A,I5,2F10.3,A)")"TradeRoute:",&R.Basis,&D.SumTradeRouteCij,&D.GrandTotal,"---------------" CALL WriteLinksInSolution($I.LOG) {?|@B.RemSourceDCcapacity} {?|@B.RemDemand} CALL WriteRemDCcapcitiesToSysLOG(bigSur) CALL WriteRemDemandsAtStoresToSysLOG(bigSur) IF (@B.RemSourceDCcapacity < 1) THEN dcDC(@B.SourceDCseq)%logRemCapacity = logNo !IF ($L.W) & WRITE(sys%intLOG,*)"DC's Unused supplies exhausted. Pulling from unused supply queue",@B.SourceDCseq,dcDC(@B.SourceDCseq)%regID CALL PullEntity(queUnused,@B.SourceDCseq) END IF IF (@B.RemDemand < 1) THEN rtsStore(@B.StoreSeq)%logRemDemand = logNo DO bigFlowLink = 1, rtsStore(@B.StoreSeq)%regDCs &B.Record = rtsStore(@B.StoreSeq)%bigLinkSeq(bigFlowLink) &B.DCseq = lnkInfo(&B.Record)%regDCseq dcDC(&B.DCseq)%intShortStores = dcDC(&B.DCseq)%intShortStores - 1 dcDC(&B.DCseq)%logShortStores = dcDC(&B.DCseq)%intShortStores > 0 IF (dcDC(&B.DCseq)%logShortStores) THEN WRITE($I.LOG,*)"# of deficient stores linked to",&B.DCseq,dcDC(&B.DCseq)%regID,"=", & dcDC(&B.DCseq)%intShortStores WRITE(*,*)"# of deficient stores linked to",&B.DCseq,dcDC(&B.DCseq)%regID,"=", & dcDC(&B.DCseq)%intShortStores ELSE &I.DeficientStoreLinkedDCs = &I.DeficientStoreLinkedDCs - 1 {?|&I.DeficientStoreLinkedDCs} WRITE($I.LOG,*)&B.DCseq,dcDC(&B.DCseq)%regID,"no longer has any stores with shortage" WRITE(*,*)&B.DCseq,dcDC(&B.DCseq)%regID,"no longer has stores with shortage"!,dcDC(&B.DCseq)%intShortStores END IF END DO !IF ($L.W) & WRITE(sys%intLOG,*)"Store demand satisfied. Pulling",@B.StoreSeq,rtsStore(@B.StoreSeq)%regID,"from deficient stores queue" CALL PullEntity(queShortage,@B.StoreSeq) END IF CALL WriteSummaryResults("UpdSol") {??|"-------- End Solution Update --------" WRITE(*,"(I4,I6,3I10,I8,F15.3,F12.3)")&R.MajorIteration,&R.Basis,&B.SUMofRemCapacity,&B.SUMofRemDemand, & &B.RemDemandAftInitialSol - &B.SUMofRemDemand,&B.SUMofRemCapacityPrev - &B.SUMofRemCapacity, & &D.GrandTotal,&D.GrandTotal - &D.GrandTotalPrev END IF -{Branch} -{Object.15} TradeRoute.[15]DistributionCenter--->|BackToReferringNet !---------------------------------------- +{Object.16} TradeRoute.[16]BackToReferringNet +{Trans} -{Trans} +{SignalTarget} -{SignalTarget} -{Object.16} TradeRoute.[16]BackToReferringNet -{Page}TradeRoute //////////////////////////////////////////