Descent Solver: Completed - Taboo Solver: Completed
This commit is contained in:
		
							parent
							
								
									f306a8c7f6
								
							
						
					
					
						commit
						5fe1352f2d
					
				
					 20 changed files with 1824 additions and 1306 deletions
				
			
		
							
								
								
									
										144
									
								
								Solvers-Results.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								Solvers-Results.txt
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,144 @@ | |||
|                          basic                         random                         | ||||
| instance size  best      runtime makespan ecart        runtime makespan ecart         | ||||
| aaa1     2x3     11            1       12   9.1            999       11   0.0         | ||||
| ft06     6x6     55            0       60   9.1            999       55   0.0         | ||||
| ft10     10x10  930            0     1319  41.8            999     1209  30.0         | ||||
| ft20     20x5  1165            0     1672  43.5            999     1529  31.2         | ||||
| la01     10x5   666            0      858  28.8            999      701   5.3         | ||||
| la02     10x5   655            0      904  38.0            999      729  11.3         | ||||
| la03     10x5   597            0      775  29.8            999      673  12.7         | ||||
| la04     10x5   590            0      854  44.7            999      667  13.1         | ||||
| la05     10x5   593            0      629   6.1            999      593   0.0         | ||||
| la06     15x5   926            0     1015   9.6            999      943   1.8         | ||||
| la07     15x5   890            0     1096  23.1            999      981  10.2         | ||||
| la08     15x5   863            0     1102  27.7            999      944   9.4         | ||||
| la09     15x5   951            0     1024   7.7            999      964   1.4         | ||||
| AVG      -        -          0.1        -  24.5          999.0        -   9.7 | ||||
| 
 | ||||
| 
 | ||||
|                          Greedy-SPT                    Greedy-LRPT                   Greedy-EST_SPT                Greedy-EST_LRPT                | ||||
| instance size  best      runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart         | ||||
| aaa1     2x3     11            6       16  45.5              0       11   0.0              0       11   0.0              1       11   0.0         | ||||
| ft06     6x6     55            2      108  96.4              2       74  34.5              1       88  60.0              1       61  10.9         | ||||
| ft10     10x10  930            3     2569 176.2              2     1289  38.6              2     1074  15.5              2     1108  19.1         | ||||
| ft20     20x5  1165            3     2765 137.3              3     1955  67.8              2     1267   8.8              1     1501  28.8         | ||||
| la01     10x5   666            1     1464 119.8              0      845  26.9              1      751  12.8              1      735  10.4         | ||||
| la02     10x5   655            1     1943 196.6              0      982  49.9              0      821  25.3              1      817  24.7         | ||||
| la03     10x5   597            1     1053  76.4              0      797  33.5              0      672  12.6              0      696  16.6         | ||||
| la04     10x5   590            1     1491 152.7              0     1000  69.5              1      711  20.5              0      758  28.5         | ||||
| la05     10x5   593            0     1521 156.5              0      666  12.3              0      610   2.9              0      593   0.0         | ||||
| la06     15x5   926            1     2372 156.2              1     1151  24.3              0     1200  29.6              0      926   0.0         | ||||
| la07     15x5   890            1     1823 104.8              1     1108  24.5              1     1034  16.2              1      970   9.0         | ||||
| la08     15x5   863            0     2309 167.6              0     1196  38.6              1      942   9.2              1      943   9.3         | ||||
| la09     15x5   951            0     2638 177.4              0     1233  29.7              0     1045   9.9              1     1015   6.7         | ||||
| AVG      -        -          1.5        - 135.6            0.7        -  34.6            0.7        -  17.2            0.8        -  12.6 | ||||
| 
 | ||||
| 
 | ||||
|                          Descent-SPT                   Descent-LRPT                  Descent-EST_SPT               Descent-EST_LRPT               | ||||
| instance size  best      runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart         | ||||
| aaa1     2x3     11           14       11   0.0              1       11   0.0              1       11   0.0              1       11   0.0         | ||||
| ft06     6x6     55           21       65  18.2              4       58   5.5              5       72  30.9              3       55   0.0         | ||||
| ft10     10x10  930           66     1379  48.3             23     1073  15.4              5     1017   9.4              2     1108  19.1         | ||||
| ft20     20x5  1165           79     1574  35.1             31     1513  29.9              1     1267   8.8              1     1501  28.8         | ||||
| la01     10x5   666           11      907  36.2              4      666   0.0              2      686   3.0              4      695   4.4         | ||||
| la02     10x5   655            8      869  32.7              2      806  23.1              3      685   4.6              1      782  19.4         | ||||
| la03     10x5   597            2      877  46.9              1      725  21.4              0      666  11.6              1      696  16.6         | ||||
| la04     10x5   590            6      852  44.4              2      794  34.6              1      702  19.0              0      747  26.6         | ||||
| la05     10x5   593           12      742  25.1              2      621   4.7              0      610   2.9              0      593   0.0         | ||||
| la06     15x5   926           11     1348  45.6              3      952   2.8              2      963   4.0              0      926   0.0         | ||||
| la07     15x5   890           14     1087  22.1              3      965   8.4              0     1034  16.2              5      923   3.7         | ||||
| la08     15x5   863           20     1320  53.0              2     1082  25.4              0      933   8.1              0      909   5.3         | ||||
| la09     15x5   951           29     1433  50.7              3     1084  14.0              1      975   2.5              1      985   3.6         | ||||
| AVG      -        -         22.5        -  35.2            6.2        -  14.2            1.6        -   9.3            1.5        -   9.8  | ||||
| 
 | ||||
| 
 | ||||
|                          Taboo-EST_LRPT(1,1)            | ||||
| instance size  best      runtime makespan ecart         | ||||
| aaa1     2x3     11           17       11   0.0         | ||||
| ft06     6x6     55           20       57   3.6         | ||||
| ft10     10x10  930           13     1108  19.1         | ||||
| ft20     20x5  1165            9     1501  28.8         | ||||
| la01     10x5   666            4      695   4.4         | ||||
| la02     10x5   655            3      803  22.6         | ||||
| la03     10x5   597            2      696  16.6         | ||||
| la04     10x5   590            2      747  26.6         | ||||
| la05     10x5   593            1      593   0.0         | ||||
| la06     15x5   926            2      926   0.0         | ||||
| la07     15x5   890            3      951   6.9         | ||||
| la08     15x5   863           12      909   5.3         | ||||
| la09     15x5   951            2      985   3.6         | ||||
| AVG      -        -          6.9        -  10.6 | ||||
| 
 | ||||
| 
 | ||||
|                          Taboo-EST_LRPT(1,10)          Taboo-EST_LRPT(2,10)          Taboo-EST_LRPT(3,10)          Taboo-EST_LRPT(4,10)          Taboo-EST_LRPT(5,10)          Taboo-EST_LRPT(6,10)          Taboo-EST_LRPT(7,10)          Taboo-EST_LRPT(8,10)          Taboo-EST_LRPT(9,10)          Taboo-EST_LRPT(10,10)          | ||||
| instance size  best      runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart         | ||||
| aaa1     2x3     11           25       11   0.0              4       11   0.0              4       11   0.0              2       11   0.0              2       11   0.0              2       11   0.0              2       11   0.0              1       11   0.0              2       11   0.0              3       11   0.0         | ||||
| ft06     6x6     55           14       55   0.0             11       55   0.0             11       55   0.0              7       55   0.0              8       55   0.0              7       55   0.0              6       55   0.0             16       55   0.0              4       55   0.0              4       55   0.0         | ||||
| ft10     10x10  930           21     1108  19.1             23     1108  19.1             19     1096  17.8             14     1108  19.1             19     1108  19.1             14     1108  19.1             12     1108  19.1             11     1108  19.1             11     1108  19.1             11     1108  19.1         | ||||
| ft20     20x5  1165            7     1501  28.8              7     1465  25.8              8     1465  25.8             15     1465  25.8              5     1465  25.8              4     1465  25.8              5     1465  25.8              5     1465  25.8              5     1465  25.8              5     1465  25.8         | ||||
| la01     10x5   666            4      695   4.4              2      692   3.9              3      692   3.9              2      692   3.9              3      692   3.9              2      692   3.9              2      692   3.9              2      692   3.9              2      692   3.9              2      692   3.9         | ||||
| la02     10x5   655            3      769  17.4              3      769  17.4              3      769  17.4              2      753  15.0              2      753  15.0              3      753  15.0              3      753  15.0              2      753  15.0              2      753  15.0              3      753  15.0         | ||||
| la03     10x5   597            2      692  15.9              2      692  15.9              6      689  15.4              2      689  15.4              2      692  15.9              4      692  15.9              3      692  15.9              2      692  15.9              3      692  15.9              2      692  15.9         | ||||
| la04     10x5   590            3      696  18.0              2      696  18.0              3      696  18.0              2      696  18.0              2      702  19.0              2      703  19.2              2      703  19.2              1      694  17.6              2      694  17.6              2      694  17.6         | ||||
| la05     10x5   593            3      593   0.0              2      593   0.0              1      593   0.0              1      593   0.0              1      593   0.0              1      593   0.0              1      593   0.0              1      593   0.0              1      593   0.0              1      593   0.0         | ||||
| la06     15x5   926            2      926   0.0              2      926   0.0              2      926   0.0              2      926   0.0              2      926   0.0              2      926   0.0              1      926   0.0              3      926   0.0              2      926   0.0              1      926   0.0         | ||||
| la07     15x5   890            7      912   2.5              5      912   2.5              4      912   2.5              8      912   2.5              4      912   2.5              4      912   2.5              5      912   2.5              4      912   2.5              4      912   2.5              4      912   2.5         | ||||
| la08     15x5   863            4      902   4.5              4      902   4.5              5      902   4.5              4      902   4.5              8      902   4.5              6      902   4.5              5      902   4.5              4      902   4.5              3      902   4.5              3      902   4.5         | ||||
| la09     15x5   951            3      951   0.0              2      951   0.0              3      951   0.0             15      985   3.6              6      985   3.6              5      951   0.0              4      951   0.0              4      951   0.0              4      951   0.0              6      951   0.0         | ||||
| AVG      -        -          7.5        -   8.5            5.3        -   8.2            5.5        -   8.1            5.8        -   8.3            4.9        -   8.4            4.3        -   8.1            3.9        -   8.1            4.3        -   8.0            3.5        -   8.0            3.6        -   8.0    | ||||
| 
 | ||||
| 
 | ||||
|                          Taboo-EST_LRPT(1,100)         Taboo-EST_LRPT(6,100)         Taboo-EST_LRPT(8,100)         Taboo-EST_LRPT(10,100)        Taboo-EST_LRPT(12,100)        Taboo-EST_LRPT(14,100)        Taboo-EST_LRPT(20,100)        Taboo-EST_LRPT(50,100)        Taboo-EST_LRPT(100,100)        | ||||
| instance size  best      runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart         | ||||
| aaa1     2x3     11           48       11   0.0             13       11   0.0              9       11   0.0              6       11   0.0              5       11   0.0              5       11   0.0              3       11   0.0              2       11   0.0              3       11   0.0         | ||||
| ft06     6x6     55           43       55   0.0             36       55   0.0             27       55   0.0             20       55   0.0             20       55   0.0             15       55   0.0             17       55   0.0             10       55   0.0              6       55   0.0         | ||||
| ft10     10x10  930           95     1108  19.1             63     1037  11.5             59     1041  11.9             52     1032  11.0             60     1048  12.7             82     1046  12.5             55     1054  13.3             48     1098  18.1             34     1098  18.1         | ||||
| ft20     20x5  1165           42     1501  28.8             40     1329  14.1             41     1329  14.1             46     1311  12.5             37     1325  13.7             43     1329  14.1             51     1352  16.1             23     1399  20.1             18     1400  20.2         | ||||
| la01     10x5   666           23      695   4.4              9      666   0.0              7      666   0.0             19      666   0.0             16      690   3.6             13      688   3.3             15      671   0.8              8      690   3.6              6      692   3.9         | ||||
| la02     10x5   655           34      737  12.5             17      722  10.2             22      694   6.0             15      706   7.8             16      732  11.8             13      736  12.4             11      736  12.4              9      736  12.4             11      745  13.7         | ||||
| la03     10x5   597           21      692  15.9             21      651   9.0             21      676  13.2             17      637   6.7             15      678  13.6             16      670  12.2             14      617   3.4             10      648   8.5              7      692  15.9         | ||||
| la04     10x5   590           21      696  18.0             22      638   8.1             26      646   9.5             23      648   9.8             14      639   8.3             14      651  10.3             12      647   9.7              9      674  14.2              5      674  14.2         | ||||
| la05     10x5   593           11      593   0.0              8      593   0.0              8      593   0.0              5      593   0.0              5      593   0.0              5      593   0.0              4      593   0.0              4      593   0.0              5      593   0.0         | ||||
| la06     15x5   926           31      926   0.0             11      926   0.0              8      926   0.0              8      926   0.0              8      926   0.0              8      926   0.0             11      926   0.0              7      926   0.0              7      926   0.0         | ||||
| la07     15x5   890           33      890   0.0             14      890   0.0             13      890   0.0             17      890   0.0             11      890   0.0             15      890   0.0             11      890   0.0             10      890   0.0             11      890   0.0         | ||||
| la08     15x5   863           30      902   4.5             22      863   0.0             25      866   0.3             23      863   0.0             24      863   0.0             21      863   0.0             14      863   0.0             13      878   1.7              8      902   4.5         | ||||
| la09     15x5   951           15      951   0.0             11      951   0.0             11      951   0.0              9      951   0.0              8      951   0.0              9      951   0.0             23      951   0.0             13      951   0.0             13      951   0.0         | ||||
| AVG      -        -         34.4        -   7.9           22.1        -   4.1           21.3        -   4.2           20.0        -   3.7           18.4        -   4.9           19.9        -   5.0           18.5        -   4.3           12.8        -   6.0           10.3        -   7.0  | ||||
| 
 | ||||
| 
 | ||||
|                          Taboo-EST_LRPT(1,1000)        Taboo-EST_LRPT(6,1000)        Taboo-EST_LRPT(8,1000)        Taboo-EST_LRPT(10,1000)       Taboo-EST_LRPT(12,1000)       Taboo-EST_LRPT(14,1000)       Taboo-EST_LRPT(20,1000)       Taboo-EST_LRPT(50,1000)       Taboo-EST_LRPT(100,1000)       | ||||
| instance size  best      runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart         | ||||
| aaa1     2x3     11           99       11   0.0             24       11   0.0             23       11   0.0             25       11   0.0             24       11   0.0             21       11   0.0             18       11   0.0             14       11   0.0             12       11   0.0         | ||||
| ft06     6x6     55          160       55   0.0            137       55   0.0            133       55   0.0             99       55   0.0            103       55   0.0             76       55   0.0             73       55   0.0             49       55   0.0             55       55   0.0         | ||||
| ft10     10x10  930          583     1108  19.1            622     1013   8.9            569      983   5.7            541      978   5.2            573      978   5.2            530     1007   8.3            535     1029  10.6            360     1045  12.4            251     1015   9.1         | ||||
| ft20     20x5  1165          383     1501  28.8            396     1217   4.5            438     1262   8.3            366     1243   6.7            294     1255   7.7            321     1218   4.5            302     1219   4.6            209     1246   7.0            168     1271   9.1         | ||||
| la01     10x5   666          196      695   4.4             61      666   0.0             52      666   0.0             64      666   0.0             65      666   0.0             76      666   0.0             68      666   0.0             52      666   0.0             54      666   0.0         | ||||
| la02     10x5   655          244      737  12.5            170      667   1.8            177      665   1.5            158      665   1.5            142      662   1.1            134      655   0.0            108      671   2.4             69      692   5.6             58      720   9.9         | ||||
| la03     10x5   597          165      692  15.9            133      628   5.2            152      620   3.9            143      603   1.0            140      603   1.0            130      603   1.0            108      603   1.0             76      615   3.0             56      615   3.0         | ||||
| la04     10x5   590          203      696  18.0            129      638   8.1            160      598   1.4            151      599   1.5            148      604   2.4             75      637   8.0            104      597   1.2             91      620   5.1             72      620   5.1         | ||||
| la05     10x5   593           93      593   0.0             56      593   0.0             59      593   0.0             49      593   0.0             49      593   0.0             45      593   0.0             45      593   0.0             45      593   0.0             40      593   0.0         | ||||
| la06     15x5   926          169      926   0.0             90      926   0.0             80      926   0.0             82      926   0.0             77      926   0.0             72      926   0.0             76      926   0.0             64      926   0.0             65      926   0.0         | ||||
| la07     15x5   890          164      890   0.0             92      890   0.0             94      890   0.0             84      890   0.0             82      890   0.0             79      890   0.0             81      890   0.0             69      890   0.0             72      890   0.0         | ||||
| la08     15x5   863          326      902   4.5            103      863   0.0            105      863   0.0             90      863   0.0             92      863   0.0             82      863   0.0             82      863   0.0             72      863   0.0             72      863   0.0         | ||||
| la09     15x5   951          151      951   0.0             85      951   0.0             81      951   0.0             80      951   0.0             79      951   0.0             78      951   0.0             78      951   0.0             78      951   0.0             62      951   0.0         | ||||
| AVG      -        -        225.8        -   7.9          161.4        -   2.2          163.3        -   1.6          148.6        -   1.2          143.7        -   1.3          132.2        -   1.7          129.1        -   1.5           96.0        -   2.5           79.8        -   2.8     | ||||
| 
 | ||||
| 
 | ||||
|                          Taboo-EST_LRPT(1,5000)        Taboo-EST_LRPT(6,5000)        Taboo-EST_LRPT(8,5000)        Taboo-EST_LRPT(10,5000)       Taboo-EST_LRPT(12,5000)       Taboo-EST_LRPT(14,5000)       Taboo-EST_LRPT(20,5000)       Taboo-EST_LRPT(50,5000)       Taboo-EST_LRPT(100,5000)       | ||||
| instance size  best      runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart        runtime makespan ecart         | ||||
| aaa1     2x3     11          265       11   0.0            101       11   0.0             40       11   0.0             34       11   0.0             35       11   0.0             27       11   0.0             38       11   0.0             25       11   0.0             30       11   0.0         | ||||
| ft06     6x6     55          675       55   0.0            665       55   0.0            405       55   0.0            504       55   0.0            489       55   0.0            329       55   0.0            286       55   0.0            267       55   0.0            222       55   0.0         | ||||
| ft10     10x10  930         1000     1108  19.1           1000     1002   7.7           1000      954   2.6           1000      978   5.2           1000      976   4.9           1000      995   7.0           1000     1007   8.3           1000     1036  11.4           1000     1015   9.1         | ||||
| ft20     20x5  1165         1000     1501  28.8           1000     1217   4.5           1000     1262   8.3           1000     1193   2.4           1000     1255   7.7           1000     1192   2.3           1000     1187   1.9           1000     1189   2.1            699     1240   6.4         | ||||
| la01     10x5   666          999      695   4.4            320      666   0.0            278      666   0.0            273      666   0.0            274      666   0.0            280      666   0.0            255      666   0.0            240      666   0.0            242      666   0.0         | ||||
| la02     10x5   655         1000      737  12.5            959      667   1.8            722      660   0.8            612      655   0.0            604      658   0.5            620      655   0.0            473      655   0.0            420      660   0.8            329      669   2.1         | ||||
| la03     10x5   597          891      692  15.9            510      628   5.2            690      605   1.3            380      603   1.0            690      603   1.0            329      603   1.0            440      603   1.0            414      615   3.0            278      615   3.0         | ||||
| la04     10x5   590         1000      696  18.0            710      638   8.1            677      598   1.4            382      599   1.5            477      602   2.0            339      637   8.0            381      597   1.2            446      598   1.4            332      616   4.4         | ||||
| la05     10x5   593          504      593   0.0            302      593   0.0            278      593   0.0            271      593   0.0            250      593   0.0            249      593   0.0            252      593   0.0            214      593   0.0            223      593   0.0         | ||||
| la06     15x5   926          794      926   0.0            471      926   0.0            412      926   0.0            417      926   0.0            406      926   0.0            391      926   0.0            367      926   0.0            360      926   0.0            338      926   0.0         | ||||
| la07     15x5   890          787      890   0.0            462      890   0.0            477      890   0.0            474      890   0.0            474      890   0.0            421      890   0.0            395      890   0.0            373      890   0.0            381      890   0.0         | ||||
| la08     15x5   863         1000      902   4.5            473      863   0.0            455      863   0.0            445      863   0.0            421      863   0.0            411      863   0.0            387      863   0.0            372      863   0.0            351      863   0.0         | ||||
| la09     15x5   951          786      951   0.0            482      951   0.0            453      951   0.0            426      951   0.0            406      951   0.0            392      951   0.0            388      951   0.0            367      951   0.0            357      951   0.0         | ||||
| AVG      -        -        823.2        -   7.9          573.5        -   2.1          529.8        -   1.1          478.3        -   0.8          502.0        -   1.2          445.2        -   1.4          435.5        -   1.0          422.9        -   1.4          367.8        -   1.9    | ||||
| 
 | ||||
| 
 | ||||
|  | @ -1,5 +1,5 @@ | |||
| # Example instance | ||||
| 3 3 # num-jobs num-tasks | ||||
| 2  3  0  3  1  2 | ||||
| 2  4  0  3  1  2 | ||||
| 1  7  0  6  2  5 | ||||
| 0  2  1 10  2  4 | ||||
							
								
								
									
										5
									
								
								instances/aaa3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								instances/aaa3
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| # Example instance | ||||
| 3 3 # num-jobs num-tasks | ||||
| 1  4  2  3  0  2 | ||||
| 1  7  0  6  2  5 | ||||
| 0  2  1 10  2  4 | ||||
|  | @ -2,6 +2,8 @@ package jobshop; | |||
| 
 | ||||
| import java.util.Arrays; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| public class BestKnownResult { | ||||
| 
 | ||||
|  | @ -9,6 +11,13 @@ public class BestKnownResult { | |||
|         return bests.containsKey(instanceName); | ||||
|     } | ||||
| 
 | ||||
|     public static List<String> instancesMatching(String namePrefix) { | ||||
|         return Arrays.stream(instances) | ||||
|                 .filter(i -> i.startsWith(namePrefix)) | ||||
|                 .sorted() | ||||
|                 .collect(Collectors.toList()); | ||||
|     } | ||||
| 
 | ||||
|     public static int of(String instanceName) { | ||||
|         if(!bests.containsKey(instanceName)) { | ||||
|             throw new RuntimeException("Unknown best result for "+instanceName); | ||||
|  |  | |||
|  | @ -4,10 +4,12 @@ import jobshop.encodings.JobNumbers; | |||
| import jobshop.encodings.ResourceOrder; | ||||
| import jobshop.encodings.Task; | ||||
| import jobshop.solvers.DescentSolver; | ||||
| import jobshop.solvers.GreedySolver; | ||||
| import jobshop.solvers.DescentSolver.Block; | ||||
| import jobshop.solvers.DescentSolver.Swap; | ||||
| import jobshop.solvers.GreedySolver; | ||||
| import jobshop.solvers.GreedySolver.PriorityESTRule; | ||||
| import jobshop.solvers.GreedySolver.PriorityRule; | ||||
| import jobshop.solvers.TabooSolver; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Paths; | ||||
|  | @ -26,19 +28,20 @@ public class DebuggingMain { | |||
|             //        mais on commençait à compter à 1 ce qui donnait [1 2 2 1 1 2] | ||||
|             JobNumbers enc = new JobNumbers(instance); | ||||
|             enc.jobs[enc.nextToSet++] = 0; | ||||
|             enc.jobs[enc.nextToSet++] = 1; | ||||
|             enc.jobs[enc.nextToSet++] = 1; | ||||
|             enc.jobs[enc.nextToSet++] = 0; | ||||
|             enc.jobs[enc.nextToSet++] = 1; | ||||
|             enc.jobs[enc.nextToSet++] = 1; | ||||
|             enc.jobs[enc.nextToSet++] = 0; | ||||
|             enc.jobs[enc.nextToSet++] = 1; | ||||
| 
 | ||||
|             System.out.println("\nJOB NUMBER ENCODING: " + enc + "\n"); | ||||
|             System.out.println("\nENCODING: " + enc); | ||||
| 
 | ||||
|             Schedule sched = enc.toSchedule(); | ||||
|              | ||||
|             System.out.println("SCHEDULE:\n" + sched); | ||||
|             System.out.println("VALID: " + sched.isValid() + "\n"); | ||||
|             System.out.println("MAKESPAN: " + sched.makespan() + "\n"); | ||||
|             // TODO: make it print something meaningful | ||||
|             // by implementing the toString() method | ||||
|             System.out.println("SCHEDULE: " + sched); | ||||
|             System.out.println("VALID: " + sched.isValid()); | ||||
|             System.out.println("MAKESPAN: " + sched.makespan()); | ||||
|              | ||||
|             System.out.println("---------------------------------------------\n"); | ||||
|              | ||||
|  | @ -81,8 +84,8 @@ public class DebuggingMain { | |||
|              | ||||
|             System.out.println("---------------------------------------------\n"); | ||||
|              | ||||
|             JobNumbers jo = JobNumbers.fromSchedule(sched); | ||||
|             System.out.println("JOB NUMBER ENCODING (FROM_SCHEDULE): " + jo + "\n"); | ||||
|             /*JobNumbers jo = JobNumbers.fromSchedule(sched); | ||||
|             System.out.println("JOB NUMBER ENCODING (FROM_SCHEDULE): " + jo + "\n");*/ | ||||
|              | ||||
|             System.out.println("---------------------------------------------\n"); | ||||
|             System.out.println("Greedy Solver: STP"); | ||||
|  | @ -118,10 +121,9 @@ public class DebuggingMain { | |||
|             System.out.println("MAKESPAN: " + sched.makespan()); | ||||
|              | ||||
|             System.out.println("---------------------------------------------\n"); | ||||
|             System.out.println("Greedy Solver: ic void applyOn(ResourceOrder order) {\r\n" +  | ||||
|             		"            throw new UnsupportedOperationException();EST_SPT\n"); | ||||
|             System.out.println("Greedy Solver: EST_LRPT\n"); | ||||
|             PriorityESTRule EST_LRPT = PriorityESTRule.EST_LRPT; | ||||
|             Solver solverEST_LRPT = new GreedySolver(EST_SPT); | ||||
|             Solver solverEST_LRPT = new GreedySolver(EST_LRPT); | ||||
|             Result resultEST_LRPT = solverEST_LRPT.solve(instance, System.currentTimeMillis() + 10); | ||||
|             sched = resultEST_LRPT.schedule; | ||||
|              | ||||
|  | @ -130,19 +132,53 @@ public class DebuggingMain { | |||
|             System.out.println("MAKESPAN: " + sched.makespan()); | ||||
|              | ||||
|             System.out.println("---------------------------------------------\n"); | ||||
|             System.out.println("Descent Solver: \n"); | ||||
|             DescentSolver solverDescent = new DescentSolver(); | ||||
|             System.out.println("Descent Solver: [Executed with EST_LRPT]\n"); | ||||
|              | ||||
|             DescentSolver solverDescent = new DescentSolver(EST_LRPT); | ||||
|              | ||||
|              | ||||
|             System.out.print("****** TEST: blocksOfCriticalPath() ******\n"); | ||||
|             System.out.print("Number of Jobs     : " + instance2.numJobs + "\n"); | ||||
|             System.out.print("Number of Tasks    : " + instance2.numTasks + "\n"); | ||||
|             System.out.print("Number of Machines : " + instance2.numMachines + "\n\n"); | ||||
|              | ||||
|              | ||||
|              | ||||
|             List<Block> criticalBlockList = solverDescent.blocksOfCriticalPath(ro2); | ||||
|             for(Block b : criticalBlockList) { | ||||
|             	System.out.println(b); | ||||
|             	//System.out.println(solverDescent.neighbors(b)); | ||||
|             	for(Swap s : solverDescent.neighbors(b)) { | ||||
|             		System.out.println(s); | ||||
|             	} | ||||
|             /* | ||||
|             sched = ro2.toSchedule(); | ||||
|             } | ||||
|             System.out.print("******************************************\n"); | ||||
|              | ||||
|              | ||||
|             Result resultDescent = solverDescent.solve(instance2, System.currentTimeMillis() + 10); | ||||
|             sched = resultDescent.schedule; | ||||
|              | ||||
|             System.out.println("SCHEDULE:\n" + sched); | ||||
|             System.out.println("VALID: " + sched.isValid()); | ||||
|             System.out.println("MAKESPAN: " + sched.makespan());*/ | ||||
|             System.out.println("MAKESPAN: " + sched.makespan()); | ||||
|              | ||||
|             System.out.println("---------------------------------------------\n"); | ||||
|             System.out.println("Taboo Solver: [Executed with EST_LRPT]\n"); | ||||
|              | ||||
|             TabooSolver solverTaboo = new TabooSolver(EST_LRPT, 50, 1000);             | ||||
|             Result resultTaboo = solverTaboo.solve(instance2, System.currentTimeMillis() + 10); | ||||
|             sched = resultTaboo.schedule; | ||||
|             /* | ||||
|             List<Block>criticalBlockList2 = solverTaboo.blocksOfCriticalPath(ro2); | ||||
|             for(Block b : criticalBlockList2) { | ||||
|             	System.out.println(b); | ||||
|             	for(Swap s : solverTaboo.neighbors(b)) { | ||||
|             		System.out.println(s); | ||||
|             	} | ||||
|             } | ||||
|             */ | ||||
|             System.out.println("SCHEDULE:\n" + sched); | ||||
|             System.out.println("VALID: " + sched.isValid()); | ||||
|             System.out.println("MAKESPAN: " + sched.makespan()); | ||||
| 
 | ||||
|         } catch (IOException e) { | ||||
|             e.printStackTrace(); | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| package jobshop; | ||||
| 
 | ||||
| import jobshop.encodings.Task; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
|  | @ -24,9 +26,15 @@ public class Instance { | |||
|     public int duration(int job, int task) { | ||||
|         return durations[job][task]; | ||||
|     } | ||||
|     public int duration(Task t) { | ||||
|         return duration(t.job, t.task); | ||||
|     } | ||||
|     public int machine(int job, int task) { | ||||
|         return machines[job][task]; | ||||
|     } | ||||
|     public int machine(Task t) { | ||||
|         return this.machine(t.job, t.task); | ||||
|     } | ||||
| 
 | ||||
|     /** among the tasks of the given job, returns the task index that uses the given machine. */ | ||||
|     public int task_with_machine(int job, int wanted_machine) { | ||||
|  | @ -46,6 +54,7 @@ public class Instance { | |||
|         machines = new int[numJobs][numTasks]; | ||||
|     } | ||||
| 
 | ||||
|     /** Parses a instance from a file. */ | ||||
|     public static Instance fromFile(Path path) throws IOException { | ||||
|         Iterator<String> lines = Files.readAllLines(path).stream() | ||||
|                 .filter(l -> !l.startsWith("#")) | ||||
|  | @ -63,11 +72,8 @@ public class Instance { | |||
|                 pb.machines[job][task] = line.nextInt(); | ||||
|                 pb.durations[job][task] = line.nextInt(); | ||||
|             } | ||||
|             line.close(); | ||||
|         } | ||||
| 
 | ||||
|         header.close(); | ||||
|   | ||||
|         return pb; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -3,16 +3,15 @@ package jobshop; | |||
| import java.io.PrintStream; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| 
 | ||||
| 
 | ||||
| import jobshop.solvers.BasicSolver; | ||||
| import jobshop.solvers.RandomSolver; | ||||
| import jobshop.solvers.*; | ||||
| import jobshop.solvers.GreedySolver.PriorityESTRule; | ||||
| import jobshop.solvers.GreedySolver.PriorityRule; | ||||
| import jobshop.solvers.GreedySolver; | ||||
| import net.sourceforge.argparse4j.ArgumentParsers; | ||||
| import net.sourceforge.argparse4j.inf.ArgumentParser; | ||||
| import net.sourceforge.argparse4j.inf.ArgumentParserException; | ||||
|  | @ -20,6 +19,22 @@ import net.sourceforge.argparse4j.inf.Namespace; | |||
| 
 | ||||
| 
 | ||||
| public class Main { | ||||
| 	// ******************************************** Main - Arguments ************************************************ // | ||||
| 	// *** Basic + Random *** // | ||||
| 	// --solver basic random --instance aaa1 ft06 ft10 ft20 la01 la02 la03 la04 la05 la06 la07 la08 la09 | ||||
| 	 | ||||
| 	// *** Greedy Solvers *** //  | ||||
| 	// --solver Greedy-SPT Greedy-LRPT Greedy-EST_SPT Greedy-EST_LRPT --instance aaa1 ft06 ft10 ft20 la01 la02 la03 la04 la05 la06 la07 la08 la09 | ||||
| 	 | ||||
| 	// *** Descent Solvers *** // | ||||
| 	// --solver Descent-SPT Descent-LRPT Descent-EST_SPT Descent-EST_LRPT --instance aaa1 ft06 ft10 ft20 la01 la02 la03 la04 la05 la06 la07 la08 la09 | ||||
| 	 | ||||
| 	// *** Taboo Solvers *** // | ||||
| 	// --solver Taboo-EST_LRPT(1,1) --instance aaa1 ft06 ft10 ft20 la01 la02 la03 la04 la05 la06 la07 la08 la09 | ||||
| 	// --solver Taboo-EST_LRPT(1,10) Taboo-EST_LRPT(2,10) Taboo-EST_LRPT(3,10) Taboo-EST_LRPT(4,10) Taboo-EST_LRPT(5,10) Taboo-EST_LRPT(6,10) Taboo-EST_LRPT(7,10) Taboo-EST_LRPT(8,10) Taboo-EST_LRPT(9,10) Taboo-EST_LRPT(10,10) --instance aaa1 ft06 ft10 ft20 la01 la02 la03 la04 la05 la06 la07 la08 la09 | ||||
| 	// --solver Taboo-EST_LRPT(1,100) Taboo-EST_LRPT(6,100) Taboo-EST_LRPT(8,100) Taboo-EST_LRPT(10,100) Taboo-EST_LRPT(12,100) Taboo-EST_LRPT(14,100) Taboo-EST_LRPT(20,100) Taboo-EST_LRPT(50,100) Taboo-EST_LRPT(100,100) --instance aaa1 ft06 ft10 ft20 la01 la02 la03 la04 la05 la06 la07 la08 la09 | ||||
| 	// --solver Taboo-EST_LRPT(1,1000) Taboo-EST_LRPT(6,1000) Taboo-EST_LRPT(8,1000) Taboo-EST_LRPT(10,1000) Taboo-EST_LRPT(12,1000) Taboo-EST_LRPT(14,1000) Taboo-EST_LRPT(20,1000) Taboo-EST_LRPT(50,1000) Taboo-EST_LRPT(100,1000) --instance aaa1 ft06 ft10 ft20 la01 la02 la03 la04 la05 la06 la07 la08 la09 | ||||
| 	// --solver Taboo-EST_LRPT(1,5000) Taboo-EST_LRPT(6,5000) Taboo-EST_LRPT(8,5000) Taboo-EST_LRPT(10,5000) Taboo-EST_LRPT(12,5000) Taboo-EST_LRPT(14,5000) Taboo-EST_LRPT(20,5000) Taboo-EST_LRPT(50,5000) Taboo-EST_LRPT(100,5000) --instance aaa1 ft06 ft10 ft20 la01 la02 la03 la04 la05 la06 la07 la08 la09 | ||||
| 	 | ||||
| 	/** All solvers available in this program */ | ||||
|     private static HashMap<String, Solver> solvers; | ||||
|  | @ -27,18 +42,69 @@ public class Main { | |||
|         solvers = new HashMap<>(); | ||||
|         solvers.put("basic", new BasicSolver()); | ||||
|         solvers.put("random", new RandomSolver()); | ||||
|         // add new solvers here | ||||
|         // Add new solvers here | ||||
|         // ******************** Greedy Solver ******************** // | ||||
|         PriorityRule SPT = PriorityRule.SPT; | ||||
|         solvers.put("greedySPT", new GreedySolver(SPT)); | ||||
|         solvers.put("Greedy-SPT", new GreedySolver(SPT)); | ||||
|         PriorityRule LRPT = PriorityRule.LRPT; | ||||
|         solvers.put("greedyLRPT", new GreedySolver(LRPT)); | ||||
|         solvers.put("Greedy-LRPT", new GreedySolver(LRPT)); | ||||
|         PriorityESTRule EST_SPT = PriorityESTRule.EST_SPT; | ||||
|         solvers.put("greedyEST_SPT", new GreedySolver(EST_SPT)); | ||||
|         solvers.put("Greedy-EST_SPT", new GreedySolver(EST_SPT)); | ||||
|         PriorityESTRule EST_LRPT = PriorityESTRule.EST_LRPT; | ||||
|         solvers.put("greedyEST_LRPT", new GreedySolver(EST_LRPT)); | ||||
|         solvers.put("Greedy-EST_LRPT", new GreedySolver(EST_LRPT)); | ||||
|          | ||||
|         // ******************* Descent Solver ******************** // | ||||
|         solvers.put("Descent-SPT",      new DescentSolver(SPT)); | ||||
|         solvers.put("Descent-LRPT",     new DescentSolver(LRPT)); | ||||
|         solvers.put("Descent-EST_SPT",  new DescentSolver(EST_SPT)); | ||||
|         solvers.put("Descent-EST_LRPT", new DescentSolver(EST_LRPT)); | ||||
|          | ||||
|         // ******************** Taboo Solver ********************* // | ||||
|         solvers.put("Taboo-EST_LRPT(1,1)",   new TabooSolver(EST_LRPT, 1, 1)); | ||||
|          | ||||
|         solvers.put("Taboo-EST_LRPT(1,10)",  new TabooSolver(EST_LRPT, 1, 10)); | ||||
|         solvers.put("Taboo-EST_LRPT(2,10)",  new TabooSolver(EST_LRPT, 2, 10)); | ||||
|         solvers.put("Taboo-EST_LRPT(3,10)",  new TabooSolver(EST_LRPT, 3, 10)); | ||||
|         solvers.put("Taboo-EST_LRPT(4,10)",  new TabooSolver(EST_LRPT, 4, 10)); | ||||
|         solvers.put("Taboo-EST_LRPT(5,10)",  new TabooSolver(EST_LRPT, 5, 10)); | ||||
|         solvers.put("Taboo-EST_LRPT(6,10)",  new TabooSolver(EST_LRPT, 6, 10)); | ||||
|         solvers.put("Taboo-EST_LRPT(7,10)",  new TabooSolver(EST_LRPT, 7, 10)); | ||||
|         solvers.put("Taboo-EST_LRPT(8,10)",  new TabooSolver(EST_LRPT, 8, 10)); | ||||
|         solvers.put("Taboo-EST_LRPT(9,10)",  new TabooSolver(EST_LRPT, 9, 10)); | ||||
|         solvers.put("Taboo-EST_LRPT(10,10)", new TabooSolver(EST_LRPT, 10, 10)); | ||||
|          | ||||
|         solvers.put("Taboo-EST_LRPT(1,100)",   new TabooSolver(EST_LRPT, 1, 100)); | ||||
|         solvers.put("Taboo-EST_LRPT(6,100)",   new TabooSolver(EST_LRPT, 6, 100)); | ||||
|         solvers.put("Taboo-EST_LRPT(8,100)",   new TabooSolver(EST_LRPT, 8, 100)); | ||||
|         solvers.put("Taboo-EST_LRPT(10,100)",  new TabooSolver(EST_LRPT, 10, 100)); | ||||
|         solvers.put("Taboo-EST_LRPT(12,100)",  new TabooSolver(EST_LRPT, 12, 100)); | ||||
|         solvers.put("Taboo-EST_LRPT(14,100)",  new TabooSolver(EST_LRPT, 14, 100)); | ||||
|         solvers.put("Taboo-EST_LRPT(20,100)",  new TabooSolver(EST_LRPT, 20, 100)); | ||||
|         solvers.put("Taboo-EST_LRPT(50,100)",  new TabooSolver(EST_LRPT, 50, 100)); | ||||
|         solvers.put("Taboo-EST_LRPT(100,100)", new TabooSolver(EST_LRPT, 100, 100)); | ||||
|          | ||||
|         solvers.put("Taboo-EST_LRPT(1,1000)",   new TabooSolver(EST_LRPT, 1, 1000)); | ||||
|         solvers.put("Taboo-EST_LRPT(6,1000)",   new TabooSolver(EST_LRPT, 6, 1000)); | ||||
|         solvers.put("Taboo-EST_LRPT(8,1000)",   new TabooSolver(EST_LRPT, 8, 1000)); | ||||
|         solvers.put("Taboo-EST_LRPT(10,1000)",  new TabooSolver(EST_LRPT, 10, 1000)); | ||||
|         solvers.put("Taboo-EST_LRPT(12,1000)",  new TabooSolver(EST_LRPT, 12, 1000)); | ||||
|         solvers.put("Taboo-EST_LRPT(14,1000)",  new TabooSolver(EST_LRPT, 14, 1000)); | ||||
|         solvers.put("Taboo-EST_LRPT(20,1000)",  new TabooSolver(EST_LRPT, 20, 1000)); | ||||
|         solvers.put("Taboo-EST_LRPT(50,1000)",  new TabooSolver(EST_LRPT, 50, 1000)); | ||||
|         solvers.put("Taboo-EST_LRPT(100,1000)", new TabooSolver(EST_LRPT, 100, 1000)); | ||||
|          | ||||
|         solvers.put("Taboo-EST_LRPT(1,5000)",   new TabooSolver(EST_LRPT, 1, 5000)); | ||||
|         solvers.put("Taboo-EST_LRPT(6,5000)",   new TabooSolver(EST_LRPT, 6, 5000)); | ||||
|         solvers.put("Taboo-EST_LRPT(8,5000)",   new TabooSolver(EST_LRPT, 8, 5000)); | ||||
|         solvers.put("Taboo-EST_LRPT(10,5000)",  new TabooSolver(EST_LRPT, 10, 5000)); | ||||
|         solvers.put("Taboo-EST_LRPT(12,5000)",  new TabooSolver(EST_LRPT, 12, 5000)); | ||||
|         solvers.put("Taboo-EST_LRPT(14,5000)",  new TabooSolver(EST_LRPT, 14, 5000)); | ||||
|         solvers.put("Taboo-EST_LRPT(20,5000)",  new TabooSolver(EST_LRPT, 20, 5000)); | ||||
|         solvers.put("Taboo-EST_LRPT(50,5000)",  new TabooSolver(EST_LRPT, 50, 5000)); | ||||
|         solvers.put("Taboo-EST_LRPT(100,5000)", new TabooSolver(EST_LRPT, 100, 5000));      | ||||
|     } | ||||
| 
 | ||||
|     @SuppressWarnings("unused") | ||||
| 
 | ||||
|     public static void main(String[] args) { | ||||
|         ArgumentParser parser = ArgumentParsers.newFor("jsp-solver").build() | ||||
|                 .defaultHelp(true) | ||||
|  | @ -79,20 +145,23 @@ public class Main { | |||
|                 System.exit(1); | ||||
|             } | ||||
|         } | ||||
|         List<String> instances = ns.<String>getList("instance"); | ||||
|         for(String instanceName : instances) { | ||||
|             if(!BestKnownResult.isKnown(instanceName)) { | ||||
|                 System.err.println("ERROR: instance \"" + instanceName + "\" is not avalaible."); | ||||
|         List<String> instancePrefixes = ns.getList("instance"); | ||||
|         List<String> instances = new ArrayList<>(); | ||||
|         for(String instancePrefix : instancePrefixes) { | ||||
|             List<String> matches = BestKnownResult.instancesMatching(instancePrefix); | ||||
|             if(matches.isEmpty()) { | ||||
|                 System.err.println("ERROR: instance prefix \"" + instancePrefix + "\" does not match any instance."); | ||||
|                 System.err.println("       available instances: " + Arrays.toString(BestKnownResult.instances)); | ||||
|                 System.exit(1); | ||||
|             } | ||||
|             instances.addAll(matches); | ||||
|         } | ||||
| 
 | ||||
|         float[] runtimes = new float[solversToTest.size()]; | ||||
|         float[] distances = new float[solversToTest.size()]; | ||||
| 
 | ||||
|         try { | ||||
|             output.print(  "                         ");; | ||||
|             output.print(  "                         "); | ||||
|             for(String s : solversToTest) | ||||
|                 output.printf("%-30s", s); | ||||
|             output.println(); | ||||
|  |  | |||
|  | @ -1,8 +1,5 @@ | |||
| package jobshop; | ||||
| 
 | ||||
| import java.util.Optional; | ||||
| 
 | ||||
| @SuppressWarnings("unused") | ||||
| public class Result { | ||||
| 
 | ||||
|     public Result(Instance instance, Schedule schedule, ExitCause cause) { | ||||
|  |  | |||
|  | @ -1,15 +1,11 @@ | |||
| package jobshop; | ||||
| 
 | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| import java.util.Comparator; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.Optional; | ||||
| import java.util.stream.IntStream; | ||||
| 
 | ||||
| import jobshop.encodings.Task; | ||||
| 
 | ||||
| import java.util.*; | ||||
| import java.util.stream.IntStream; | ||||
| 
 | ||||
| public class Schedule { | ||||
|     public final Instance pb; | ||||
|     // start times of each job and task | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ public class JobNumbers extends Encoding { | |||
|     /** A numJobs * numTasks array containing the representation by job numbers. */ | ||||
|     public final int[] jobs; | ||||
| 
 | ||||
|     /** In case the encoding is only partially filled, indicates the index of first | ||||
|     /** In case the encoding is only partially filled, indicates the index of the first | ||||
|      * element of `jobs` that has not been set yet. */ | ||||
|     public int nextToSet = 0; | ||||
| 
 | ||||
|  | @ -77,38 +77,6 @@ public class JobNumbers extends Encoding { | |||
|         return new Schedule(instance, startTimes); | ||||
|     } | ||||
| 
 | ||||
|     public static JobNumbers fromSchedule(Schedule sched) { | ||||
| 		JobNumbers jo = new JobNumbers(sched.pb); | ||||
| 		 | ||||
| 		int current_time = 0; | ||||
| 		Task current_task = new Task(-1,-1); | ||||
| 		Task [] done_tasks = new Task[sched.pb.numJobs*sched.pb.numTasks]; | ||||
| 		Arrays.fill(done_tasks, current_task); | ||||
| 		 | ||||
| 		int min; | ||||
| 		 | ||||
| 		for (int i = 0; i < sched.pb.numJobs*sched.pb.numTasks; i++) { | ||||
| 			// Il faut faire le code ci-dessous autant de fois que l'on a de taches | ||||
| 			// On trouve le minimum parmis les restants | ||||
| 			min = Integer.MAX_VALUE; | ||||
| 			for (int job = 0; job < sched.pb.numJobs; job++) { | ||||
| 				for (int task = 0; task < sched.pb.numTasks; task++) { | ||||
| 					int task_start_time = sched.startTime(job, task); | ||||
| 					Task this_task = new Task(job, task); | ||||
| 					if (task_start_time < min && task_start_time >= current_time && !(Arrays.asList(done_tasks).contains(this_task))) { | ||||
| 						min = task_start_time; | ||||
| 						current_task = this_task; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			// Une fois on a trouvé la suivante tache a realiser on introduit le numero du job dans jobs | ||||
| 			jo.jobs[jo.nextToSet++] = current_task.job; | ||||
| 			done_tasks[i] = current_task; | ||||
| 		} | ||||
|     	 | ||||
|     	return jo; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public String toString() { | ||||
|         return Arrays.toString(Arrays.copyOfRange(jobs,0, nextToSet)); | ||||
|  |  | |||
|  | @ -1,35 +1,37 @@ | |||
| package jobshop.encodings; | ||||
| 
 | ||||
| import java.util.Comparator; | ||||
| import java.util.Optional; | ||||
| import java.util.stream.IntStream; | ||||
| 
 | ||||
| import jobshop.Encoding; | ||||
| import jobshop.Instance; | ||||
| import jobshop.Schedule; | ||||
| 
 | ||||
| import java.util.Comparator; | ||||
| import java.util.Optional; | ||||
| import java.util.stream.IntStream; | ||||
| 
 | ||||
| public class ResourceOrder extends Encoding { | ||||
| 
 | ||||
|     // for each machine m, taskByMachine[m] is an array of tasks to be | ||||
|     // executed on this machine in the same order | ||||
|     public final Task[][] tasksByMachine; | ||||
| 
 | ||||
|     // for each machine, indicate on many tasks have been initialized | ||||
|     public final int[] nextFreeSlot; | ||||
| 
 | ||||
| 	public ResourceOrder(Instance instance) { | ||||
|     /** Creates a new empty resource order. */ | ||||
|     public ResourceOrder(Instance instance) | ||||
|     { | ||||
|         super(instance); | ||||
| 
 | ||||
| 		this.tasksByMachine = new Task[instance.numMachines][instance.numJobs]; | ||||
| 		for (int i = 0; i < instance.numMachines; i++) { | ||||
| 			for (int j = 0; j < instance.numJobs; j++) { | ||||
| 				this.tasksByMachine[i][j] = new Task(-1,-1); | ||||
| 			} | ||||
| 		} | ||||
|         // matrix of null elements (null is the default value of objects) | ||||
|         tasksByMachine = new Task[instance.numMachines][instance.numJobs]; | ||||
| 
 | ||||
|         // no task scheduled on any machine (0 is the default value) | ||||
|         nextFreeSlot = new int[instance.numMachines]; | ||||
|     } | ||||
| 
 | ||||
| 	public ResourceOrder(Schedule schedule) { | ||||
|     /** Creates a resource order from a schedule. */ | ||||
|     public ResourceOrder(Schedule schedule) | ||||
|     { | ||||
|         super(schedule.pb); | ||||
|         Instance pb = schedule.pb; | ||||
| 
 | ||||
|  | @ -51,7 +53,6 @@ public class ResourceOrder extends Encoding { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	 | ||||
|     @Override | ||||
|     public Schedule toSchedule() { | ||||
|         // indicate for each task that have been scheduled, its start time | ||||
|  | @ -88,7 +89,7 @@ public class ResourceOrder extends Encoding { | |||
| 
 | ||||
|                 // compute the earliest start time (est) of the task | ||||
|                 int est = t.task == 0 ? 0 : startTimes[t.job][t.task-1] + instance.duration(t.job, t.task-1); | ||||
|                 est = Math.max(est, releaseTimeOfMachine[instance.machine(t.job, t.task)]); | ||||
|                 est = Math.max(est, releaseTimeOfMachine[instance.machine(t)]); | ||||
|                 startTimes[t.job][t.task] = est; | ||||
| 
 | ||||
|                 // mark the task as scheduled | ||||
|  | @ -105,6 +106,11 @@ public class ResourceOrder extends Encoding { | |||
|         return new Schedule(instance, startTimes); | ||||
|     } | ||||
| 
 | ||||
|     /** Creates an exact copy of this resource order. */ | ||||
|     public ResourceOrder copy() { | ||||
|         return new ResourceOrder(this.toSchedule()); | ||||
|     } | ||||
| 	 | ||||
| 	@Override | ||||
|     public String toString() { | ||||
| 		String res = ""; | ||||
|  |  | |||
|  | @ -36,7 +36,7 @@ public final class Task { | |||
| 
 | ||||
|     @Override | ||||
|     public String toString() { | ||||
|         return "Job " + this.job + " Task " + this.task; | ||||
|         return "(" + job +", " + task + '}'; | ||||
|     } | ||||
|      | ||||
|     public Task add_one() { | ||||
|  |  | |||
|  | @ -2,16 +2,35 @@ package jobshop.solvers; | |||
| 
 | ||||
| import jobshop.Instance; | ||||
| import jobshop.Result; | ||||
| import jobshop.Result.ExitCause; | ||||
| import jobshop.Schedule; | ||||
| import jobshop.Solver; | ||||
| import jobshop.encodings.ResourceOrder; | ||||
| import jobshop.encodings.Task; | ||||
| import jobshop.solvers.GreedySolver.PriorityESTRule; | ||||
| import jobshop.solvers.GreedySolver.PriorityRule; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class DescentSolver implements Solver { | ||||
| 	 | ||||
| 	private PriorityRule priorityRule; | ||||
| 	private PriorityESTRule priorityESTRule; | ||||
| 	 | ||||
| 	// 2 constructors: the default and one with the EST restriction | ||||
| 	public DescentSolver(PriorityRule rule) { | ||||
| 		super(); | ||||
| 		this.priorityRule = rule; | ||||
| 		this.priorityESTRule = null; | ||||
| 	} | ||||
| 	 | ||||
| 	public DescentSolver(PriorityESTRule ruleEST) { | ||||
| 		super(); | ||||
| 		this.priorityESTRule = ruleEST; | ||||
| 		this.priorityRule = null; | ||||
| 	} | ||||
| 
 | ||||
|     /** A block represents a subsequence of the critical path such that all tasks in it execute on the same machine. | ||||
|      * This class identifies a block in a ResourceOrder representation. | ||||
|      * | ||||
|  | @ -78,7 +97,7 @@ public class DescentSolver implements Solver { | |||
|             // Retrieve the tasks to be swap | ||||
|         	Task task1 = order.tasksByMachine[this.machine][this.t1]; | ||||
|             Task task2 = order.tasksByMachine[this.machine][this.t2]; | ||||
|             // Make the swap | ||||
|             // Make the swap (default in/out) | ||||
|             order.tasksByMachine[this.machine][this.t1] = task2; | ||||
|             order.tasksByMachine[this.machine][this.t2] = task1; | ||||
|         } | ||||
|  | @ -87,90 +106,142 @@ public class DescentSolver implements Solver { | |||
|         	return "Swap: {M" + this.machine + " | t1 = " + this.t1 + " | t2 = " + this.t2 + "}"; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     // ************************************************************************************************************* // | ||||
|     // *************************************** DescentSolver: solve Method ***************************************** // | ||||
|     // ************************************************************************************************************* // | ||||
|     @Override | ||||
|     public Result solve(Instance instance, long deadline) { | ||||
|         throw new UnsupportedOperationException(); | ||||
|     	// Choosing rule (SPT / LRPT / EST_SPT / EST_LRPT) | ||||
|     	GreedySolver greedy = null; | ||||
|     	if(priorityESTRule == null) { | ||||
|     		PriorityRule currentRule = this.priorityRule; | ||||
|     		greedy = new GreedySolver(currentRule); | ||||
|     	} else if(priorityRule == null) { | ||||
|     		PriorityESTRule currentESTRule = this.priorityESTRule; | ||||
|     		greedy = new GreedySolver(currentESTRule); | ||||
|     	} else { | ||||
|     		System.out.printf("Error priorityRule and priorityRuleEST are null. You must give a value to one of them."); | ||||
|     	} | ||||
|     	 | ||||
|         // Start: Sinit <- GreedySolver(instance) | ||||
|     	Result resultLRPT = greedy.solve(instance, deadline); | ||||
|     	Schedule initialSolution = resultLRPT.schedule; | ||||
|     	 | ||||
|     	// Record the best solution | ||||
|     	Schedule bestSolution = initialSolution; | ||||
|     	ResourceOrder bestResourceOrder = new ResourceOrder(bestSolution); | ||||
|     	 | ||||
|     	// Repeat: Explore the concurrent neighbors | ||||
|     	Boolean optimizable = true; | ||||
|     	Schedule currentSolution; | ||||
|     	ResourceOrder currentResourceOrder; | ||||
|     	List<Block> criticalBlockList; | ||||
|     	 | ||||
|     	while(optimizable && deadline > System.currentTimeMillis()) { | ||||
|     		// We first take the critical path from the bestSolution | ||||
|         	bestResourceOrder = new ResourceOrder(bestSolution); | ||||
|         	criticalBlockList = this.blocksOfCriticalPath(bestResourceOrder); | ||||
|         	// By default we suppose there will be no optimization possible. If there is, this value will be later changed | ||||
|         	optimizable = false; | ||||
|         	// We search for the best solution by checking all neighbors | ||||
|         	for(Block b : criticalBlockList) { | ||||
|         		for(Swap s : this.neighbors(b)) { | ||||
|                 	// We copy to a variable the bestResourceOrder in order to modified freely while searching for the best solution | ||||
|                 	currentResourceOrder = bestResourceOrder.copy(); | ||||
|         			// We apply the swap on the current Resource Order and we schedule it | ||||
|         			s.applyOn(currentResourceOrder); | ||||
|         			currentSolution = currentResourceOrder.toSchedule(); | ||||
|         			// If the currentSolution duration is smaller than the bestSolution one, save the currentSolution | ||||
|         			if(currentSolution != null) { | ||||
| 	        			if(currentSolution.makespan() < bestSolution.makespan()) { | ||||
| 	        				bestSolution = currentSolution; | ||||
| 	        				// While we find better solutions keep running the solve method | ||||
| 	        				optimizable = true; | ||||
| 	        			} | ||||
|         			} | ||||
|         		} | ||||
|         	} | ||||
|     	} | ||||
|     	// We find the exit cause in order to create the result we will return | ||||
|     	ExitCause exitCause = null; | ||||
|     	if(deadline <= System.currentTimeMillis()) { | ||||
|     		exitCause = ExitCause.Timeout; | ||||
|     	} else { | ||||
|     		exitCause = ExitCause.ProvedOptimal; | ||||
|     	} | ||||
|     	 | ||||
|     	return new Result(instance, bestSolution, exitCause); | ||||
|     } | ||||
|      | ||||
|     // ************************************************************************************************************* // | ||||
|      | ||||
|      | ||||
|     // ************************************************************************************************************* // | ||||
|     // ***************************** blocksOfCriticalPath and neighbors Methods ************************************ // | ||||
|     // ************************************************************************************************************* // | ||||
|     /** Returns a list of all blocks of the critical path. */ | ||||
|     public List<Block> blocksOfCriticalPath(ResourceOrder order) { | ||||
|     	List<Block> criticalBlockList = new ArrayList<>(); | ||||
|     	List<Integer> checkedMachines = new ArrayList<>(); | ||||
|     	 | ||||
|     	Block currentBlock; | ||||
|     	// Obtain the critical task list from the resource order instance | ||||
|         Schedule criticalSchedule = order.toSchedule(); | ||||
|         List<Task> criticalTaskList = criticalSchedule.criticalPath(); | ||||
|          | ||||
|         Block currentBlock; | ||||
|         int currentMachine, m; | ||||
|         int firstTask = 0, lastTask = 0; | ||||
|         Task currentTask; | ||||
|         int totalNumMachines = criticalSchedule.pb.numMachines; | ||||
|         int totalNumJobs     = criticalSchedule.pb.numJobs; | ||||
|          | ||||
|         System.out.print("Number of Jobs     : " + order.instance.numJobs + "\n"); | ||||
|         System.out.print("Number of Tasks    : " + order.instance.numTasks + "\n"); | ||||
|         System.out.print("Number of Machines : " + order.instance.numMachines + "\n"); | ||||
|         System.out.print("Critical path      : " + criticalTaskList + "\n"); | ||||
|         Task currentTaskRO; | ||||
|         int currentTaskIndexRO, currentCriticalTaskIndex, firstTask, lastTask; | ||||
|          | ||||
|         // Initialize the block list | ||||
|         for(int i = 0; i < order.instance.numMachines; i++) { | ||||
|         	currentBlock = new Block(i, -1, -1); | ||||
|         	criticalBlockList.add(i, currentBlock); | ||||
|         // We check for all machines | ||||
|         for(int currentMachine = 0; currentMachine < totalNumMachines; currentMachine++) { | ||||
|         	currentTaskIndexRO = 0; | ||||
|             while(currentTaskIndexRO < (totalNumJobs-1)){ | ||||
|                 currentTaskRO = order.tasksByMachine[currentMachine][currentTaskIndexRO]; | ||||
|                 if (criticalTaskList.contains(currentTaskRO)) { | ||||
|                     currentCriticalTaskIndex = criticalTaskList.indexOf(currentTaskRO); | ||||
|                     //If the next task in the critical path is running in the same machine try find the last task index | ||||
|                     if(currentMachine == criticalSchedule.pb.machine(criticalTaskList.get(currentCriticalTaskIndex+1))) { | ||||
|                         firstTask = currentTaskIndexRO; | ||||
|                         while(currentCriticalTaskIndex < (criticalTaskList.size()-1) && currentMachine == criticalSchedule.pb.machine(criticalTaskList.get(currentCriticalTaskIndex+1))){ | ||||
|                         	// We advance in the list | ||||
|                             currentCriticalTaskIndex++; | ||||
|                             // We have to also advance in the resource order | ||||
|                             currentTaskIndexRO++; | ||||
|                         } | ||||
|          | ||||
|         for(int i = 0; i < criticalTaskList.size(); i++) { | ||||
|         	currentTask = criticalTaskList.get(i); | ||||
|         	currentMachine = order.instance.machine(currentTask.job, currentTask.task); | ||||
|         	 | ||||
|         	// When we find a machine we have not explored, we start searching for all its appearances in the critical path  | ||||
|         	// and we safe the first and last occurrence of the machine.   | ||||
|         	if(!checkedMachines.contains(currentMachine)) { | ||||
|         		firstTask = 0; | ||||
|                 lastTask = 0; | ||||
|         		for(int index = i; index < criticalTaskList.size(); index++) { | ||||
| 	        		m = order.instance.machine(criticalTaskList.get(index).job, criticalTaskList.get(index).task); | ||||
| 	        		// If we find a task running in the same machine and it is not the first task, add 1 to the last task | ||||
| 	        		if(currentMachine == m && index > i){ | ||||
| 	    				lastTask++; | ||||
| 	        		} | ||||
|         		} | ||||
|             	// Add the machine to the checked machines list | ||||
|             	checkedMachines.add(currentMachine); | ||||
|                         // Create and add the new block to the list | ||||
|                         lastTask = currentTaskIndexRO; | ||||
|                 	    currentBlock = new Block(currentMachine, firstTask, lastTask); | ||||
|             	criticalBlockList.set(currentMachine, currentBlock); | ||||
|                         criticalBlockList.add(currentBlock); | ||||
|                     } | ||||
|                 } | ||||
|                 // We move on to the next task in the resource order | ||||
|                 currentTaskIndexRO++; | ||||
|             } | ||||
|         } | ||||
|         return criticalBlockList; | ||||
|      } | ||||
| 
 | ||||
| 
 | ||||
|      /** For a given block, return the possible swaps for the Nowicki and Smutnicki neighborhood */ | ||||
|      public List<Swap> neighbors(Block block) { | ||||
|     	List<Swap> swapList = new ArrayList<>(); | ||||
|     	Swap currentSwap; | ||||
|     	Swap swap1, swap2; | ||||
|     	 | ||||
|     	int machine   = block.machine; | ||||
|     	int firstTask = block.firstTask; | ||||
|     	int lastTask  = block.lastTask; | ||||
|     	 | ||||
|     	// Case when there is just one element in the block | ||||
|     	if(firstTask == lastTask) { | ||||
|     		swapList = null; | ||||
|     	} | ||||
|     	 | ||||
|      	for(int i = firstTask; i < lastTask; i++) { | ||||
|      		if(i == firstTask + 1) { | ||||
|      			currentSwap = new Swap(machine, firstTask, i); | ||||
|      			swapList.add(currentSwap); | ||||
|      		} | ||||
|      		if (i == lastTask - 1) { | ||||
|      			currentSwap = new Swap(machine, i, lastTask); | ||||
|      			swapList.add(currentSwap); | ||||
|      		} | ||||
|     	// One single swap if there are just 2 elements in the block, two swaps if there are more than 2. | ||||
|  		if(firstTask + 1 == lastTask) { | ||||
|  			swap1 = new Swap(machine, firstTask, lastTask); | ||||
|  			swapList.add(swap1); | ||||
|  		} else { | ||||
|  			swap1 = new Swap(machine, firstTask, firstTask+1); | ||||
|  			swap2 = new Swap(machine, lastTask-1 , lastTask); | ||||
|  			swapList.add(swap1); | ||||
|  			swapList.add(swap2); | ||||
|  		} | ||||
|         return swapList; | ||||
|      }    | ||||
| 
 | ||||
|      // ************************************************************************************************************* // | ||||
| } | ||||
|  |  | |||
|  | @ -3,9 +3,9 @@ package jobshop.solvers; | |||
| import java.util.ArrayList; | ||||
| 
 | ||||
| import jobshop.*; | ||||
| import jobshop.Result.ExitCause; | ||||
| import jobshop.encodings.ResourceOrder; | ||||
| import jobshop.encodings.Task; | ||||
| import jobshop.solvers.GreedySolver.PriorityESTRule; | ||||
| 
 | ||||
| public class GreedySolver implements Solver { | ||||
| 	 | ||||
|  | @ -100,12 +100,12 @@ public class GreedySolver implements Solver { | |||
| 			// Search for the date or dates which start sooner | ||||
| 			ArrayList<Task> priorityTasks = new ArrayList<>(); | ||||
| 			int minStartDate = Integer.MAX_VALUE; | ||||
| 
 | ||||
| 			 | ||||
| 			Task currentTask; | ||||
| 			int currentMachine, currentStartDate; | ||||
| 			for(int i = 0; i < achievableTasks.size(); i++) { | ||||
| 				Task currentTask = achievableTasks.get(i); | ||||
| 				int currentMachine = instance.machine(currentTask.job, currentTask.task); | ||||
| 				int currentStartDate = Integer.max(nextStartDateJobs[currentTask.job], nextStartDateMachines[currentMachine]); | ||||
| 				currentTask = achievableTasks.get(i); | ||||
| 				currentMachine = instance.machine(currentTask); | ||||
| 				currentStartDate = Integer.max(nextStartDateJobs[currentTask.job], nextStartDateMachines[currentMachine]); | ||||
| 						 | ||||
| 				if(currentStartDate < minStartDate) { | ||||
| 					minStartDate = currentStartDate; | ||||
|  | @ -124,16 +124,18 @@ public class GreedySolver implements Solver { | |||
| 	/********************** Greedy Solver: Constructors + Solve function *************************/ | ||||
| 	/*********************************************************************************************/ | ||||
| 	 | ||||
| 	public PriorityRule priorityRule; | ||||
| 	public PriorityESTRule priorityESTRule; | ||||
| 	private PriorityRule priorityRule; | ||||
| 	private PriorityESTRule priorityESTRule; | ||||
| 	 | ||||
| 	// 2 constructors: the default and one with the EST restriction | ||||
| 	public GreedySolver(PriorityRule rule) { | ||||
| 		super(); | ||||
| 		this.priorityRule = rule; | ||||
| 		this.priorityESTRule = null; | ||||
| 	} | ||||
| 	 | ||||
| 	public GreedySolver(PriorityESTRule ruleEST) { | ||||
| 		super(); | ||||
| 		this.priorityESTRule = ruleEST; | ||||
| 		this.priorityRule = null; | ||||
| 	} | ||||
|  | @ -143,7 +145,7 @@ public class GreedySolver implements Solver { | |||
| 	@Override | ||||
|     public Result solve(Instance instance, long deadline) { | ||||
| 		 | ||||
| 		int currentMachine, currentDuration; | ||||
| 		int currentMachine, currentDuration, currentStartDate, nextFreeSlot; | ||||
| 		// We declare 2 arrays containing the updated moment the next task will start in a job and a machine respectively | ||||
| 		int[] nextStartDateJobs = new int[instance.numJobs]; | ||||
| 		int[] nextStartDateMachines = new int[instance.numMachines]; | ||||
|  | @ -155,11 +157,10 @@ public class GreedySolver implements Solver { | |||
|        | ||||
|         // Initialize the array list with all the first task achievable | ||||
| 		for(int i = 0 ; i < instance.numJobs ; i++) { | ||||
| 			Task currentTask = new Task(i, 0); | ||||
| 			achievableTasks.add(currentTask); | ||||
| 			achievableTasks.add(new Task(i, 0)); | ||||
|         } | ||||
| 		 | ||||
|         while(!achievableTasks.isEmpty()) { | ||||
|         while(!achievableTasks.isEmpty() && deadline > System.currentTimeMillis()) { | ||||
|             // We take the task we should do now in function of the priority rule used | ||||
|         	Task currentTask = null; | ||||
|         	if(priorityESTRule == null) { | ||||
|  | @ -170,25 +171,33 @@ public class GreedySolver implements Solver { | |||
|         		System.out.printf("Error priorityRule and priorityRuleEST are null. You must give a value to one of them."); | ||||
|         	} | ||||
|         	 | ||||
|         	// Updating starting dates | ||||
| 			currentMachine = instance.machine(currentTask.job, currentTask.task); | ||||
| 			currentDuration = instance.duration(currentTask.job, currentTask.task); | ||||
| 			nextStartDateJobs[currentTask.job] += currentDuration; | ||||
| 			nextStartDateMachines[currentMachine] += currentDuration; | ||||
|              | ||||
|             // We remove the current task from the achievable tasks list | ||||
|             achievableTasks.remove(currentTask); | ||||
|         	 | ||||
|         	// Updating starting dates | ||||
| 			currentMachine   = instance.machine(currentTask); | ||||
| 			currentDuration  = instance.duration(currentTask); | ||||
|             currentStartDate = Integer.max(nextStartDateJobs[currentTask.job], nextStartDateMachines[currentMachine]); | ||||
| 
 | ||||
| 			nextStartDateJobs[currentTask.job]    = currentStartDate + currentDuration; | ||||
| 			nextStartDateMachines[currentMachine] = currentStartDate + currentDuration; | ||||
|              | ||||
|             // If it's not the last task of the job, we update the array list with the new task | ||||
|             if (currentTask.task < (instance.numTasks - 1)) { | ||||
|             	achievableTasks.add(new Task(currentTask.job, currentTask.task + 1)); | ||||
|             } | ||||
|              | ||||
|             // We add the current task to the solution | ||||
|             int nextFreeSlot = solution.nextFreeSlot[currentMachine]++; | ||||
|             nextFreeSlot = solution.nextFreeSlot[currentMachine]++; | ||||
|             solution.tasksByMachine[currentMachine][nextFreeSlot] = currentTask; | ||||
|         } | ||||
| 
 | ||||
|         return new Result(instance, solution.toSchedule(), Result.ExitCause.Blocked); | ||||
|     	// We find the exit cause in order to create the result we will return | ||||
|     	ExitCause exitCause = null; | ||||
|     	if(deadline <= System.currentTimeMillis()) { | ||||
|     		exitCause = ExitCause.Timeout; | ||||
|     	} else { | ||||
|     		exitCause = ExitCause.ProvedOptimal; | ||||
|     	} | ||||
|         return new Result(instance, solution.toSchedule(), exitCause); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ import jobshop.encodings.JobNumbers; | |||
| import java.util.Optional; | ||||
| import java.util.Random; | ||||
| 
 | ||||
| @SuppressWarnings("unused") | ||||
| public class RandomSolver implements Solver { | ||||
| 
 | ||||
|     @Override | ||||
|  |  | |||
							
								
								
									
										231
									
								
								src/main/java/jobshop/solvers/TabooSolver.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								src/main/java/jobshop/solvers/TabooSolver.java
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,231 @@ | |||
| package jobshop.solvers; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import jobshop.Instance; | ||||
| import jobshop.Result; | ||||
| import jobshop.Schedule; | ||||
| import jobshop.Solver; | ||||
| import jobshop.Result.ExitCause; | ||||
| import jobshop.encodings.ResourceOrder; | ||||
| import jobshop.encodings.Task; | ||||
| import jobshop.solvers.GreedySolver.PriorityESTRule; | ||||
| import jobshop.solvers.GreedySolver.PriorityRule; | ||||
| import jobshop.solvers.DescentSolver.*; | ||||
| 
 | ||||
| 
 | ||||
| public class TabooSolver implements Solver { | ||||
| 	 | ||||
| 	private PriorityRule priorityRule; | ||||
| 	private PriorityESTRule priorityESTRule; | ||||
| 	private int dureeTaboo; | ||||
| 	private int maxIter; | ||||
| 	 | ||||
| 	// 2 constructors: the default and one with the EST restriction | ||||
| 	public TabooSolver(PriorityRule rule, int dureeTaboo, int maxIter) { | ||||
| 		super(); | ||||
| 		this.priorityRule = rule; | ||||
| 		this.priorityESTRule = null; | ||||
| 		this.dureeTaboo = dureeTaboo; | ||||
| 		this.maxIter = maxIter; | ||||
| 	} | ||||
| 	 | ||||
| 	public TabooSolver(PriorityESTRule ruleEST, int dureeTaboo, int maxIter) { | ||||
| 		super(); | ||||
| 		this.priorityESTRule = ruleEST; | ||||
| 		this.priorityRule = null; | ||||
| 		this.dureeTaboo = dureeTaboo; | ||||
| 		this.maxIter = maxIter; | ||||
| 	} | ||||
| 	 | ||||
| 	 | ||||
| 	// ************************************************************************************************************* // | ||||
| 	// *************************************** TabooSolver: solve Method ******************************************* // | ||||
| 	// ************************************************************************************************************* // | ||||
| 	 | ||||
|     @Override | ||||
|     public Result solve(Instance instance, long deadline) { | ||||
|     	// Choosing rule (SPT / LRPT / EST_SPT / EST_LRPT) | ||||
|     	GreedySolver greedy = null; | ||||
|     	if(priorityESTRule == null) { | ||||
|     		PriorityRule currentRule = this.priorityRule; | ||||
|     		greedy = new GreedySolver(currentRule); | ||||
|     	} else if(priorityRule == null) { | ||||
|     		PriorityESTRule currentESTRule = this.priorityESTRule; | ||||
|     		greedy = new GreedySolver(currentESTRule); | ||||
|     	} else { | ||||
|     		System.out.printf("Error priorityRule and priorityRuleEST are null. You must give a value to one of them."); | ||||
|     	} | ||||
|     	 | ||||
|         // Generating a viable solution | ||||
|     	Result result = greedy.solve(instance, deadline); | ||||
|     	Schedule initialSolution = result.schedule; | ||||
|     	ResourceOrder initialResourceOrder = new ResourceOrder(initialSolution); | ||||
|          | ||||
|     	// Declaring all solution types | ||||
|     	ResourceOrder bestRO         = initialResourceOrder; // s* | ||||
|     	ResourceOrder currentRO      = bestRO.copy();		 // s | ||||
|     	ResourceOrder bestNeighborRO = bestRO.copy();		 // s'  | ||||
|     	ResourceOrder neighborRO;							 // s'' | ||||
|     	 | ||||
| 		// Defining the sTaboo variables | ||||
|     	int totalTasks = instance.numJobs * instance.numTasks; | ||||
| 		int[][] sTaboo = new int[totalTasks][totalTasks]; | ||||
| 		// Initializing sTaboo with all 0 | ||||
| 		for (int[] row : sTaboo) { | ||||
| 			Arrays.fill(row, 0); | ||||
| 		} | ||||
| 		 | ||||
|     	// Declaring other variables | ||||
| 		List<Block> criticalBlockList; | ||||
|     	int TASK_PER_JOB, j1, i1, j2, i2, taskID1, taskID2, forbiddenTaskID1, forbiddenTaskID2; | ||||
|     	int bestMakespan = initialSolution.makespan(); | ||||
|     	int bestNeighborMakespan, neighborMakespan; | ||||
|     	boolean updated; | ||||
|     	 | ||||
|     	// Iteration Counter | ||||
|     	int k = 0; | ||||
| 
 | ||||
|         while (deadline > System.currentTimeMillis() && k <= this.maxIter) { | ||||
|         	// ***************** 1. k <- k + 1 ******************************************************** // | ||||
|             k++; | ||||
|              | ||||
|             // ***************** 2. Choose the best neighbor s' that is not in sTaboo ***************** // | ||||
|             bestNeighborMakespan = Integer.MAX_VALUE; | ||||
|             forbiddenTaskID1 = -1;  | ||||
|             forbiddenTaskID2 = -1; | ||||
|             updated = false; | ||||
|     		 | ||||
|             // We first take the critical path from the currentRO (s) | ||||
|     		currentRO = bestNeighborRO.copy(); // (s <- s') | ||||
|         	criticalBlockList = this.blocksOfCriticalPath(currentRO); | ||||
|         	 | ||||
|             for(Block b : criticalBlockList) { | ||||
|                 for(Swap s : neighbors(b)) { | ||||
|                 	// Extract the current index values for sTaboo | ||||
|         			TASK_PER_JOB = currentRO.instance.numTasks; | ||||
|         			j1 = currentRO.tasksByMachine[s.machine][s.t1].job; | ||||
|          			j2 = currentRO.tasksByMachine[s.machine][s.t2].job; | ||||
|         			i1 = currentRO.tasksByMachine[s.machine][s.t1].task; | ||||
|         			i2 = currentRO.tasksByMachine[s.machine][s.t2].task; | ||||
|         			taskID1 = j1 * TASK_PER_JOB + i1; | ||||
|         			taskID2 = j2 * TASK_PER_JOB + i2; | ||||
|         			 | ||||
|                     // Check if it is a forbidden swap | ||||
|                     if(sTaboo[taskID1][taskID2] < k) { | ||||
|                     	updated= true; | ||||
|                         neighborRO = currentRO.copy(); | ||||
|                         // We apply the swap on the current Resource Order and we schedule it to find its makespan | ||||
|                         s.applyOn(neighborRO); | ||||
|                         neighborMakespan = neighborRO.toSchedule().makespan();                         | ||||
|                          | ||||
|                         if(neighborMakespan < bestNeighborMakespan) { | ||||
|                         	// We forbid the opposite permutation of the given tasks (in index taskID1 and taskID2) | ||||
|                         	forbiddenTaskID1 = taskID1; | ||||
|                         	forbiddenTaskID2 = taskID2; | ||||
|                             // We have checked all neighbors and we have chosen the best one: bestNeighborRO | ||||
|                         	bestNeighborMakespan = neighborMakespan; | ||||
|                             bestNeighborRO = neighborRO.copy(); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             // ************************ 3. Add bestNeighborSolution (s') to sTaboo *************************** // | ||||
|             // If it is not updated it means all solutions are forbidden | ||||
|             if(updated) { | ||||
|             	sTaboo[forbiddenTaskID2][forbiddenTaskID1] = this.dureeTaboo + k; | ||||
|             	// ******************** 4. If s' is better than s* then s* <- s' ************************** // | ||||
|                 if(bestNeighborMakespan < bestMakespan) { | ||||
|                 	bestMakespan = bestNeighborMakespan; | ||||
|                 	bestRO = bestNeighborRO.copy(); | ||||
|                 } | ||||
|             }  | ||||
|         } | ||||
|     	// We find the exit cause in order to create the result we will return | ||||
|     	ExitCause exitCause = null; | ||||
|     	if(deadline <= System.currentTimeMillis()) { | ||||
|     		exitCause = ExitCause.Timeout; | ||||
|     	} else if(k >= this.maxIter) { | ||||
|     		exitCause = ExitCause.Blocked; | ||||
|     	} else { | ||||
|     		exitCause = ExitCause.ProvedOptimal; | ||||
|     	} | ||||
|     	return new Result(instance, bestRO.toSchedule(), exitCause); | ||||
|     } | ||||
|     // ************************************************************************************************************* // | ||||
|      | ||||
|      | ||||
|     // ************************************************************************************************************* // | ||||
|     // ********************************** Copied functions from DescentSolver ************************************** // | ||||
|     // ************************************************************************************************************* // | ||||
|      | ||||
|     /** Returns a list of all blocks of the critical path. */ | ||||
|     private List<Block> blocksOfCriticalPath(ResourceOrder order) { | ||||
|      	List<Block> criticalBlockList = new ArrayList<>(); | ||||
|      	Block currentBlock; | ||||
|      	// Obtain the critical task list from the resource order instance | ||||
|          Schedule criticalSchedule = order.toSchedule(); | ||||
|          List<Task> criticalTaskList = criticalSchedule.criticalPath(); | ||||
|           | ||||
|          int totalNumMachines = criticalSchedule.pb.numMachines; | ||||
|          int totalNumJobs     = criticalSchedule.pb.numJobs; | ||||
|           | ||||
|          Task currentTaskRO; | ||||
|          int currentTaskIndexRO, currentCriticalTaskIndex, firstTask, lastTask; | ||||
|           | ||||
|          // We check for all machines | ||||
|          for(int currentMachine = 0; currentMachine < totalNumMachines; currentMachine++) { | ||||
|          	currentTaskIndexRO = 0; | ||||
|              while(currentTaskIndexRO < (totalNumJobs-1)){ | ||||
|                  currentTaskRO = order.tasksByMachine[currentMachine][currentTaskIndexRO]; | ||||
|                  if (criticalTaskList.contains(currentTaskRO)) { | ||||
|                      currentCriticalTaskIndex = criticalTaskList.indexOf(currentTaskRO); | ||||
|                      //If the next task in the critical path is running in the same machine try find the last task index | ||||
|                      if(currentMachine == criticalSchedule.pb.machine(criticalTaskList.get(currentCriticalTaskIndex+1))) { | ||||
|                          firstTask = currentTaskIndexRO; | ||||
|                          while(currentCriticalTaskIndex < (criticalTaskList.size()-1) && currentMachine == criticalSchedule.pb.machine(criticalTaskList.get(currentCriticalTaskIndex+1))){ | ||||
|                          	// We advance in the list | ||||
|                              currentCriticalTaskIndex++; | ||||
|                              // We have to also advance in the resource order | ||||
|                              currentTaskIndexRO++; | ||||
|                          } | ||||
|                          // Create and add the new block to the list | ||||
|                          lastTask = currentTaskIndexRO; | ||||
|                  	    currentBlock = new Block(currentMachine, firstTask, lastTask); | ||||
|                          criticalBlockList.add(currentBlock); | ||||
|                      } | ||||
|                  } | ||||
|                  // We move on to the next task in the resource order | ||||
|                  currentTaskIndexRO++; | ||||
|              } | ||||
|          } | ||||
|          return criticalBlockList; | ||||
|      } | ||||
| 
 | ||||
|     /** For a given block, return the possible swaps for the Nowicki and Smutnicki neighborhood */ | ||||
|     private List<Swap> neighbors(Block block) { | ||||
|     	List<Swap> swapList = new ArrayList<>(); | ||||
|     	Swap swap1; | ||||
|     	Swap swap2; | ||||
|     	 | ||||
|     	int machine   = block.machine; | ||||
|     	int firstTask = block.firstTask; | ||||
|     	int lastTask  = block.lastTask; | ||||
|     	 | ||||
|     	// One single swap if there are just 2 elements in the block, two swaps if there are more than 2. | ||||
|  		if(firstTask + 1 == lastTask) { | ||||
|  			swap1 = new Swap(machine, firstTask, lastTask); | ||||
|  			swapList.add(swap1); | ||||
|  		} else { | ||||
|  			swap1 = new Swap(machine, firstTask, firstTask+1); | ||||
|  			swap2 = new Swap(machine, lastTask-1 , lastTask); | ||||
|  			swapList.add(swap1); | ||||
|  			swapList.add(swap2); | ||||
|  		} | ||||
|         return swapList; | ||||
|     } | ||||
| 		 | ||||
|     // ************************************************************************************************************* // | ||||
| } | ||||
|  | @ -5,9 +5,6 @@ import jobshop.Result; | |||
| import jobshop.Schedule; | ||||
| import jobshop.Solver; | ||||
| import jobshop.solvers.BasicSolver; | ||||
| import jobshop.solvers.GreedySolver; | ||||
| import jobshop.solvers.GreedySolver.PriorityRule; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
|  | @ -75,29 +72,4 @@ public class EncodingTests { | |||
|         assert result.schedule.makespan() == sched.makespan(); // should have the same makespan | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testGreedySolver() throws IOException { | ||||
|         Instance instance = Instance.fromFile(Paths.get("instances/aaa1")); | ||||
| 
 | ||||
|         // build a solution that should be equal to the result of BasicSolver | ||||
|         JobNumbers enc = new JobNumbers(instance); | ||||
|         enc.jobs[enc.nextToSet++] = 0; | ||||
|         enc.jobs[enc.nextToSet++] = 1; | ||||
|         enc.jobs[enc.nextToSet++] = 0; | ||||
|         enc.jobs[enc.nextToSet++] = 1; | ||||
|         enc.jobs[enc.nextToSet++] = 0; | ||||
|         enc.jobs[enc.nextToSet++] = 1; | ||||
| 
 | ||||
|         Schedule sched = enc.toSchedule(); | ||||
|         assert sched.isValid(); | ||||
|         assert sched.makespan() == 12; | ||||
|          | ||||
|         PriorityRule priorityRule = PriorityRule.SPT; | ||||
|         Solver solver = new GreedySolver(priorityRule); | ||||
|         Result result = solver.solve(instance, System.currentTimeMillis() + 10); | ||||
| 
 | ||||
|         assert result.schedule.isValid(); | ||||
|         assert result.schedule.makespan() == sched.makespan(); // should have the same makespan | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue