这是一个Haskell代写的Project，主要与分配调度问题相关

The student teams will implement 3 systems (one in Java, one in Haskell, and one in PROLOG) that will all solve the following simple scheduling problem:

We have 8 machines 1,2,3,4,5,6,7,8 and 8 tasks A,B,C,D,E,F,G,H. We need to assign to each machine one of the tasks so that each of the 8 tasks gets its own machine. There are additional so-called * hard constraints* (see below) that need to be fulfilled by an assignment of tasks to machines to make this assignment valid. Also, there are so-called

*(again, see below) that result in penalties for an assignment and the goal of the systems is to find the assignment of tasks to machines that has the minimal penalty value (if such an assignment exists).*

*soft constraints*Let us first take a look at the different types of hard and soft constraints before we define the structure of an input file for this problem and the required output formats.

** Hard constraints**:

*forced partial assignment:*

this hard constraint consists of up to 8 pairs (mach,task), with mach in {1,2,3,4,5,6,7,8} and task in {A,B,C,D,E,F,G,H}. Any assignment, that for any machine mach in one of the pairs does not assign the indicated task task to this machine is invalid.

Error handling: if among the pairs are two pairs with the same machine or two pairs with the same task, then the system should output “partial assignment error” and stop execution.:*forbidden machine*

this hard constraint consists of a list of pairs (mach,task), with mach in {1,2,3,4,5,6,7,8} and task in {A,B,C,D,E,F,G,H}. Any assignment, that assigns to a machine mach a task task that is in this list is invalid.*too-near tasks:*

this hard constraint consists of a list of pairs (task_{1},task_{2}), with task_{1},task_{2}in {A,B,C,D,E,F,G,H}. Any assignment that assigns task_{1}to a machine i and task_{2}to machine i+1 (or task_{1}to machine 8 and task_{2}to machine 1) is invalid.

For all these hard constraints, if in their description occurs either a machine that is not in {1,2,3,4,5,6,7,8} or a task that is not in {A,B,C,D,E,F,G,H}, then the system should terminate with the message “invalid machine/task”.

** Soft constraints**:

*machine penalties:*

this soft constraint is entered in the form of 8 lines each containing 8 natural numbers (including 0). If p is the number at position i on line j, then p is added to the penalty value of an assignment, if this assignment has assigned to machine j the task that is on the i-th position in A,B,C,D,E,F,G,H (so, the lines represent the machines and the columns represent the tasks).

Problem handling: if there are more or less than 8 lines (of the form described above) or if one of the lines does not have enough numbers, then the system should output “machine penalty error” and stop execution.*too-near penalities:*

this soft constraint is represented as a list of triples (task_{1},task_{2},p), with task_{1}, task_{2}in {A,B,C,D,E,F,G,H} and p a natural number. p is added to the penalty value of an assignment, if this assignment has assigned task_{1}to a machine i and task_{2}to machine i+1 (or task_{1}to machine 8 and task_{2}to machine 1).

Problem handling: if in any of the triples occurs a task that is not in {A,B,C,D,E,F,G,H}, then the system should terminate with the message “invalid task”. If we have two triples (task_{1},task_{2},p_{1}) and (task_{1},task_{2},p_{2}) then the p_{i}that appears last is the penality value to use.

The overall penalty value of an assignment is the sum of all soft constraint penalties from above.

For all these soft constraints, if the system expects a natural number and the input does not provide one, then the system should terminate with the message “invalid penalty”.

Note that * too-near tasks* and

*essentially deal with the same “problem”, namely not wanting certain tasks on “neighboring” machines. But while using a hard constraint might result in not being able to get any valid assignment (which sometimes is what we want), using a soft constraint allows to distinguish how “bad” the problem is for different task pairs.*

*too-near penalities*With these constraints, the general structure of an input file for your system is as follows:

Name:

*name*

forced partial assignment:

(*mach_{1}*,*task_{1}*)

…

(*mach_{n}*,*task_{n}*)

forbidden machine:

(*mach’_{1}*,*task’_{1}*)

…

(*mach’_{m}*,*task’_{m}*)

too-near tasks:

(*task”_{11}*,*task”_{12}*)

…

(*task”_{k1}*,*task”_{k2}*)

machine penalties:

*p_{11}* *p_{12}* *p_{13}* *p_{14}* *p_{15}* *p_{16}* *p_{17}* *p_{18}*

*p_{21}* *p_{22}* *p_{23}* *p_{24}* *p_{25}* *p_{26}* *p_{27}* *p_{28}*

*p_{31}* *p_{32}* *p_{33}* *p_{34}* *p_{35}* *p_{36}* *p_{37}* *p_{38}*

*p_{41}* *p_{42}* *p_{43}* *p_{44}* *p_{45}* *p_{46}* *p_{47}* *p_{48}*

*p_{51}* *p_{52}* *p_{53}* *p_{54}* *p_{55}* *p_{56}* *p_{57}* *p_{58}*

*p_{61}* *p_{62}* *p_{63}* *p_{64}* *p_{65}* *p_{66}* *p_{67}* *p_{68}*

*p_{71}* *p_{72}* *p_{73}* *p_{74}* *p_{75}* *p_{76}* *p_{77}* *p_{78}*

*p_{81}* *p_{82}* *p_{83}* *p_{84}* *p_{85}* *p_{86}* *p_{87}* *p_{88}*

too-near penalities

(*task+_{11}*,*task+_{12}*,*p_{1}*)

…

(*task+_{x1}*,*task+_{x2}*,*p_{x}*)

Here, *name* is any non-empty character string that does not contain a blank, *mach_{i}*, *mach’_{i}*, are out of {1,2,3,4,5,6,7,8}, *task_{i}*, *task’_{i}*, *task”_{ij}*, *task+_{ij}* are out of {A,B,C,D,E,F,G,H} and all *p_{i}* and *p_{ij}* are natural numbers (or 0). n is less or equal to 8. If n, m, k, or x are 0, then the file will just contain the key word for the particular constraint and no further lines (for that constraint). If any key word is missing, one of the place holders above is assigned an invalid value, or the file contains something not specified above, output “Error while parsing input file” (except if we already defined a different error message above).

Your systems should be to handle any additional blanks at the end of any line in the input file (handle meaning that the system should ignore them) and also any additional empty lines between lines.

Your systems have to read their input from file and also write all output to a file. So, if your system is called mysystem, the input file is myinput and the file for the output is myoutput, the command for running your system should be:

mysystem myinput myoutput

We will use scripts for performing our tests and therefore need all systems to strictly follow all requirements given above and below!

While, in theory, it is still possible to solve this problem by simply enumerating the 40320 possible assignments of tasks to machines, scheduling problems are often solved by using a so-called __branch-and-bound__ method. Regardless of the solution method, if there are no problems in the input file/problem instance specification, your system should output

“No valid solution possible!”

if there is no solution that fulfills the given hard constraints or

“Solution” *task*_{1} *task*_{2} *task*_{3} *task*_{4} *task*_{5} *task*_{6} *task*_{7} *task*_{8}“; Quality:” *qual*

where *task*_{i} in {A,B,C,D,E,F,G,H}, *task*_{i} is the task assigned to machine i in the best assignment, i.e. the assignment with minimal overall penalty value and *qual* is this overall penalty value of the assignment.

If there are several assignments with the same minimal overall penalty value, any of these assignments will be an acceptable output.