You are on page 1of 3

BIRLA INSTITUTE OF TECHNOLOGY AND SCIENCE

PILANI-333031 (RAJASTHAN) INDIA


Second Semester 2007-2008
Course: EA C461 (Artificial Intelligence) Lab 5: Best-First Search for Scheduling
Prepared By: Dr. Mukesh Kumar Rohil rohil@bits-pilani.ac.in

This Lab is based on the book by Ivan Bratko, Prolog Programming for Artificial Intelligence, Third
Edition, 2001, Pearson Education Ltd., Second Impression 2007 (in India).

We can formulate a scheduling problem as a state-space search problem as follows:


• States are partial schedules;
• A successor state of some partial schedule is obtained by adding a not yet scheduled task to this
schedule; another possibility is to leave a processor that has completed its empty schedule;
• The start state is the empty schedule;
• Any schedule that includes all the tasks in the problem is a goal state;
• The cost of a solution (which is to be minimized) is the finish time of a goal schedule;
• Accordingly, the cost of a transition between two (partial) schedules whose finishing times are F1,
and F2 respectively is the difference F2 – F1.

Some refinements are done to the above approach as follows:


• We fill the schedule according to increasing time.
• Each time a task is added, the precedence constraint has to be checked.
• If a task is waiting for resource (i.e. processor or server) then the task is assigned to any idle
resource.

We need the following information:


• List of waiting tasks and their execution times
• Current engagement of the processors
• We add (for convenience) the finish time of the (partial) schedule
• The list of waiting tasks and their execution times are represented as: [Task1/Duration1,
Task3/Duration3, Task3/Duration3, ….]
• The current engagement of resources (or processors) represented by a list of tasks currently being
processed: Task/FinishTime
• Three components of partial schedule are represented as:
WaitingList*ActiveTasks*FinishingTime

A best-first program along these lines is shown in Table 1.

Do the following:
1. Find the time taken by the method to execute the query given at the end of Table 1. [Hint: Read
and Use time/2 predicate given in the LPA Win-Prolog help]
2. Comparing the program in Table 1 (of Lab 4) and Table 1 (of this Lab), make a table of
predicates of Table 1 and Table 3 by stating which predicate(s) in Table 3 does the analogous or
similar work of which predicate(s) in Table 1.
3. Change the program for any other scheduling problem involving at least 10 tasks and 15
precedence relations.
4. Name your files as L5_AI_YourID_pN and zip them as L5_AI_YourID.zip and transmit to
instructor’s email id. Replace the text YourID by your BITS IDNumber and N in pN by problem
number 1, 2, or 3 as the case may be.
% Problem-specific relations for the task-scheduling problem.
% The particular scheduling problem of Figure 12.8 is also defined by its
% precedence graph and an initial (empty) schedule as a start node for search.

/* Problem-specific relations for task scheduling

Nodes in the state space are partial schedules specified by:

[ WaitingTask1/D1, WaitingTask2/D2, ...] * ヘ


[ Task1/F1, Task2/F2, ...] * FinTime

The first list specifies the waiting tasks and their durations; the ヘ
second list specifies the currently executed tasks and their finishing ヘ
times, ordered so that F1 =< F2, F2 =< F3 ... . Fintime is the ヘ
latest completion time of current engagements of the processors.
*/

% s( Node, SuccessorNode, Cost)

s( Tasks1 * [_/F | Active1] * Fin1, Tasks2 * Active2 * Fin2, Cost) :-


del( Task/D, Tasks1, Tasks2), % Pick a waiting task
not ( member( T/_, Tasks2), before( T, Task) ), % Check precedence
not ( member( T1/F1, Active1), F < F1, before( T1, Task) ), %Active tasks too
Time is F + D, % Finishing time of activated task
insert( Task/Time, Active1, Active2, Fin1, Fin2),
Cost is Fin2 - Fin1.

s( Tasks * [_/F | Active1] * Fin, Tasks * Active2 * Fin, 0) :-


insertidle( F, Active1, Active2). % Leave processor idle

before( T1, T2) :- % Task T1 before T2 according to precedence


prec( T1, T2).

before( T1, T2) :-


prec( T, T2),
before( T1, T).

insert( S/A, [T/B | L], [S/A, T/B | L], F, F) :- % Task lists are ordered
A =< B, !.

insert( S/A, [T/B | L], [T/B | L1], F1, F2) :-


insert( S/A, L, L1, F1, F2).

insert( S/A, [], [S/A], _, A).

insertidle( A, [T/B | L], [idle/B, T/B | L] ) :- % Leave processor idle


A < B, !. % until first greater finishing time

insertidle( A, [T/B | L], [T/B | L1] ) :-


insertidle( A, L, L1).

del( A, [A | L], L). % Delete item from list

del( A, [B | L], [B | L1] ) :-


del( A, L, L1).

goal( [] * _ * _). % Goal state: no task waiting

% Heuristic estimate of a partial schedule is based on an


% optimistic estimate of the final finishing time of this
% partial schedule extended by all the remaining waiting tasks.

h( Tasks * Processors * Fin, H) :-


totaltime( Tasks, Tottime), % Total duration of waiting tasks
sumnum( Processors, Ftime, N), % Ftime is sum of finishing times
% of processors, N is their number
Finall is ( Tottime + Ftime)/N,
( Finall > Fin, !, H is Finall - Fin
;
H=0
).

totaltime( [], 0).

totaltime( [_/D | Tasks], T) :-


totaltime( Tasks, T1),
T is T1 + D.

sumnum( [], 0, 0).

sumnum( [_/T | Procs], FT, N) :-


sumnum( Procs, FT1, N1),
N is N1 + 1,
FT is FT1 + T.

% A task-precedence graph prec(TaskX, TaskY) means TaskX precedes TaskY

prec( t1, t4). prec( t1, t5). prec( t2, t4). prec( t2, t5).
prec( t3, t5). prec( t3, t6). prec( t3, t7).

% A start node

start( [t1/4, t2/2, t3/2, t4/20, t5/20, t6/11, t7/11] * [idle/0, idle/0, idle/0] * 0).

% An example query: start( Problem), bestfirst( Problem, Sol).

Table 1

You might also like