Raw Frequency Material (descending) 9 422 0 406 2 404 4 403 6 402 7 402 1 398 3 394 8 389 5 384This shows that raw material 9 has the highest frequency, followed by 0. In the above, the variance in frequency is quite small, so I have included a piece of code that will amplify the differences - with the intention that this will increase the probability of like items being grouped together. For the frequency table above, raw material 9 should appear in all rows near the top of the cursor Process_Sequence.
*- Production_Scheduling.Prg #Define lDEBUGGING .T. #Define iTOTAL_TEST_ROWS 1000 Set Talk Off *- Generate test data. Create Cursor Schedule ( iID I, nFeed1 N(1), nFeed2 N(1), nFeed3 N(1), nFeed4 N(1) ) Rand(-1) For iTestRow = 1 To iTOTAL_TEST_ROWS *- nFeed1 through 4 will have values in the range 0 to 9 inclusive. *- Also assume that a raw material in one feed cannot also simultaneously be in another feed. Store -1 TO nNewFeed1, nNewFeed2, nNewFeed3, nNewFeed4 nNewFeed1 = Int( Rand() * 10 ) nNewFeed2 = Int( Rand() * 10 ) Do While nNewFeed2 == nNewFeed1 nNewFeed2 = Int( Rand() * 10 ) EndDo nNewFeed3 = Int( Rand() * 10 ) Do While InList( nNewFeed3, nNewFeed1, nNewFeed2 ) nNewFeed3 = Int( Rand() * 10 ) EndDo nNewFeed4 = Int( Rand() * 10 ) Do While InList( nNewFeed4, nNewFeed1, nNewFeed2, nNewFeed3 ) nNewFeed4 = Int( Rand() * 10 ) EndDo Insert Into Schedule ; (iID, nFeed1, nFeed2, nFeed3, nFeed4) ; Values ; (Reccount("Schedule") + 1 ; , nNewFeed1, nNewFeed2, nNewFeed3, nNewFeed4 ) Next iTestRow Select Schedule Locate Browse Last NoWait *- Determine frequencies of various raw materials. Dimension aFrequency[ 10, 2 ] aFrequency = 0 For iRawMaterial = 1 To 10 aFrequency[ iRawMaterial, 1 ] = iRawMaterial - 1 Next iRawMaterial #If iTOTAL_TEST_ROWS > 65000 Then Select fDetermineFrequency( nFeed1, nFeed2, nFeed3, nFeed4 ) ; From Schedule ; Into Cursor curNotUsed Use In curNotUsed #Else Select fDetermineFrequency( nFeed1, nFeed2, nFeed3, nFeed4 ) ; From Schedule ; Into Array aNotUsed Release aNotUsed #Endif ACopy( aFrequency, aSorted ) ASort( aSorted, 2, -1, 1 ) #If lDEBUGGING Clear _ClipText = "" #Endif *- The following loop may be useful if there are only small differences *- in the frequencies. It will amplify the differences. For iRawMaterial = 1 To 10 iFrequencyRow = aSorted[ iRawMaterial, 1] + 1 #If lDEBUGGING ? aFrequency[ iFrequencyRow, 1 ], aFrequency[ iFrequencyRow, 2 ] _ClipText = _ClipText ; + Str( aFrequency[ iFrequencyRow, 1 ], 1 ) ; + Chr( 9 ) ; + Str( aFrequency[ iFrequencyRow, 2 ], 15, 0 ) ; + Chr( 13 ) + Chr( 10 ) #Endif *- Amplify the frequency differences. aFrequency[ iFrequencyRow, 2 ] = aFrequency[ iFrequencyRow, 2 ] ^ ( 10 - iRawMaterial ) Next iRawMaterial *- Determine optimum production schedule (that is, minimize the number of Feed transitions). Select iID ; , nFeed1 ; , nFeed2 ; , nFeed3 ; , nFeed4 ; , aFrequency[ nFeed1 + 1, 2 ] ; + aFrequency[ nFeed2 + 1, 2 ] ; + aFrequency[ nFeed3 + 1, 2 ] ; + aFrequency[ nFeed4 + 1, 2 ] As nOrder ; From Schedule ; Into Cursor Process_Sequence ; Order By nOrder Descending Browse Last NoWait Return .T. ************************************************************** Function fDetermineFrequency( nFeed1, nFeed2, nFeed3, nFeed4 ) ************************************************************** aFrequency[ nFeed1 + 1, 2 ] = aFrequency[ nFeed1 + 1, 2 ] + 1 aFrequency[ nFeed2 + 1, 2 ] = aFrequency[ nFeed2 + 1, 2 ] + 1 aFrequency[ nFeed3 + 1, 2 ] = aFrequency[ nFeed3 + 1, 2 ] + 1 aFrequency[ nFeed4 + 1, 2 ] = aFrequency[ nFeed4 + 1, 2 ] + 1 Return .T. EndFunc && fDetermineFrequency( nFeed1, nFeed2, nFeed3, nFeed4 ).