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 ). > >The array aFrequency can also be manually modified to force arbitrary items to change position in the sort - say to move products containing raw materials with higher profit nearer the top of the list.