Automated Distributed Meeting Scheduler


September 1999 - January 2000

Roman Berres

Competent Professor:

Eugénio Oliveira

Faculdade de Engenharia, Universidade do Porto, NIAD&R-LIACC

Rua dos Bragas

4099 Porto Codex, Portugal


I. Preface *

II. The Problem Meeting-Scheduling *

1. General *

2. Formal *

3. Boundary Conditions *

III. Agents * 1. The word Ąagent" *

2. What is an agent? *

3. Taxonomy of autonomous agents *

4. Application fields *

5. Agent communications *

6. Agent-host *

7. Stationary/Mobile Agents *

8. Aglets *

IV. Implementation * 1. Java1.2. *

1.1. Why Java? *

1.2. Different classes/parts *

1.2.1. User Interface *

1.2.2. Calendar *

1.2.3. Data-classes *

1.2.4. Calculation Module *

1.2.5. Negotiation-module *

1.2.6. Communication-module *

1.2.7. Preferences *

1.2.8. Directory *

2. JATLite: Java Agent Template Light *

2.1. Set-up of a JATLite-agent-system *

2.2. Communication via router *

2.3. class-hierarchy *

2.4. KQML *

2.5. This agent and JATLite *

2.5.1. Start of the agent *

2.5.2. Receiving messages *

2.5.3. Sending Messages *

3. Problems *
V. Features * 1. User-input-autonomous *

2. Priority orientated *

3. User-friendliness *

4. Large amount of different settings *

5. Security measures *

VI. Negotiating-strategies * 1. Elementary Parts *

2. Best fitting slots of one agent *

3. Fitting slots of all agents *

4. Find best fittings slots for all agents *

4.1. ĄFirst Possible"-strategy *

4.2. ĄTake Best"-strategy *

5. Comparison of the two negotiation-strategies *

6. Example *

VII. Handling * 1. Identification *

2. Main Frame *

3. Show/Cancel a Meeting *

4. Find/Cancel a meeting *

5. Preferences *

6. Fix a Ąprivate" meeting *

7. Fix A Date-frame *

8. Directory *

VIII. Improvement proposals *

References *

Figures *

I. Preface

The goal was, to create an automated distributed meeting scheduler agent that:

  1. allows its user to inputs his/her meeting-request
  2. negotiates with the agents of the invited persons
  3. finds out its best fitting and free time slots
  4. compares them with the sent fitting slots of the invited agents and find out the best ones
  5. reacts to incoming invitations by sending back its best fitting free time-slots
  6. shows all fixed meetings in a time-table
  7. allows the user to input his/her preferences
The agent should also be independent from the user. This means that it should have the possibility to react on incoming invitations without needing any user-input. What makes this point very important is, that the user maybe doesn't sit in front of his/her computer all the time. To avoid long scheduling-times, the independence is necessary.

The program is implemented in Java1.2. For the communications, I used JATLite, a platform that allows you, to install a message-router. All agents send their messages to this router, which then forwards them to the correct receivers. The advantage of it is, that you get a robustly communication over the Internet.

I donít lay claim, that this agent is absolutely perfect, or that it's scheduling-algorithm is excellent. But it is based on the normal activities, you will do, if you want to schedule a meeting. In the end, it can take on the routine-activities, a user would do, to fix a meeting, and so it can make the every day work of a possible user a little bit easier and help to concentrate his-/herself on more complex works.

II. The Problem Meeting-Scheduling

1. General

Arranging meetings, e.g. for a conference, is an inherent distributed process. The negotiations for a fitting time-interval can be seen as a distributed searching-process. In this connection at least the following questions arise:

The problem meeting scheduling is not easy. To solve it, today heuristics are used more and more, because there is no optimal algorithm that fits for all possible situations. Also, techniques of the artificial intelligence are used. An intelligent agent means, that the agent has the knowledge about the interests and priorities of persons. Organisational routine-tasks with regard to the meeting scheduling are practised by the agent in that way, that it filters and administrates information and answers questions. Supposing, that every person has got itís own calendar, which is administrated by an agent, the reliability of his/her calendar will be very well, because the dependability and the capability of parallelism of agents. Also, a certain security of the private data is guaranteed.

The agent can take the part of the inviting-, but also the part of the invited agent. If it takes the inviting-part, it takes control over the scheduling-process. So, it will be the one, which sets the tasks. If it takes the invited-part, it will receive a meeting-announcement, and, depending on the scheduling-strategy, the time-proposals of the inviting-agent. The negotiations can extend over several rounds, until a fitting time-slot for all participants is found, or rather, the meeting has to be cancelled.

But, in practice, automated meeting scheduling proves to be very complicated. A condition for this is the existence of electronically calendars for all users/meeting-participants. These calendars have to be updated very careful, so that an automated meeting scheduling makes sense and is successful at all. Also, you have to take care, that not only a few user will profit from the system; typically, this are that persons who initiate the meetings. For all other persons, such a system could lead to an additional expenditure.

In research works, but also in commercial areas meeting scheduling systems have been tested and used, with more or less good results. The support of the users vary from simply applications, that administrates the timetable up to real agents, that negotiate for their users and try to get as best as possible results for him/her.

2. Formal

    number of still fixed meetings: n

    number of participants: k

    the problem of meeting scheduling (PMS) can be defined as a set (A,M)

    with: A = {1,...,k} set of all involved agents

    M = {m1,...,mn} set of meetings mi that have to be scheduled.

    There should be no overlapping times!

    Specification of a meeting

    mi = (Ai,hi,li,pi,ri,oi,di,Ti), with

    AiÎ A: set of all participants of a meeting

    hi ÎAi: one of the invited agents

    li Î{0,1,Ö} duration of the meeting (e.g. in hours)

    pi Î{0,1,Ö} priority of the meeting

    ri = (Di, Hi) preferred starting time for the meeting of the invited agent hi. (Di,Hi) means the

    datum and the exact time

    oi = (Doi, Hoi) deadline of the meeting. This is the last date, where the meeting can take place.

    di = (Ddi, Hdi) deadline of the negotiation. Until that time, the meeting has to be scheduled.

    Ti: final time interval for meeting mi, containing the times {(Dmi, Hmi), ..., (Dmi, Hmi + li -1)}.

    Specification of the calendar

    Every user has an own calendar, which is administrated by his/her agent.

    This calendar contains a set of times. For each time, there is an additional information, representing, if this time is blocked by a still fixed meeting or not.


    Ds: beginning date of the calendar

    De: ending date of the calendar

    L: number of time slots (e.g. hours) of every day

    Xx,y: contains mi, if mi exists, and j Î Ai and (Dx, y) Î Ti or nil in every other case

3. Boundary Conditions

Besides a lot of interactions between the agents, there are also some boundary conditions important to solve the problem of meeting scheduling. These are:

III. Agents

1. The word Ąagent"

    Originally Ąagent" is based on the Latin-word Ąagere", which means Ąto act". In the Oxford English Dictionary, it is explained as ĄOne who (or that which) acts or exerts power".

    In the colloquial language Ąagent" will be used, if you talk about a person, that acts autonomous, but by order of another person.

    Figure 1 Agent activities


2.What is an agent?

In the data processing technology, an agent is software that supports a person, by executing autonomous several processes. Persons can delegate work to agents, instead of doing them on their own.

Agents represent human users. The main difference to traditional software is their relative autonomy, which can be explained as a goal-directed, proactive and self-starting behaviour. Software-agents run continuous and autonomous in a defined environment, together with other agents and processes. Above all in dynamic environments with lots of permanent changing data and competing processes, these characteristics are very important.

Also, agents need:

3. Taxonomy of autonomous agents
    In the biology, the classification of organisms by characteristics like descent, race, nature, etc. are prescribed by the evolution. The classification of autonomous agents in different classes is not that unequivocal, because there hadnít been an evolution like that. So for a differentiation, you have to analyse other characteristics, which are not fixed by any nature, so that they have to be defined.

    One classification-method is, to different between the kind of knowledge and the control-structure, the different agents have. So, Regulation-Agents react on incoming sensor-data. All the time, they know what to do next. Planing-Agents has the additional knowledge, to plan their actions, until they reached their goal. You can subdivide them by their different planing-basics. Adaptive-Agents also have the possibility to get new knowledge on their own.

    Until now, there does not exist any unequivocal classification-norm, or rather, there is non word-wide accepted.

4. Application fields

5. Agent communications

  1. Low level: amount of fixed procedure-calls
  2. High level: messaging interface (e.g. KQML, see below)

6. Agent-host

Figure 2 Agent-host

7. Stationary/Mobile Agents



8. Aglets


1. Java1.2.

1.1. Why Java?

- Java has been designed for heterogen networks At first, I tried to implement ADMS in Java1.02., so that it may could be used in HTML-pages, too. But I realised very early, that this would be too difficult, because a lot of functions, I needed had just been introduced with Java1.2 (not compatible with Netscape or Internet Explorer).

1.2. Different classes/parts

You can split up the implementation into the following parts:

  1. user interface
  2. calendar
  3. data-classes
  4. calculation-module
  5. negotiation-module
  6. communication-module
  7. preferences
  8. directory
1.2.1. User Interface

The User Interface (UI) should be as easy as possible, so that the familiarisation time is very short. On the other hand, it should contain enough functions, so that the user can do all necessary operations without clicking through lots of windows. Also, it should not look very different from other applications, the user already knows. So, the buttons should look like ever and they should be on the well-known places; no unusual fonts, the common colours should be used, etc.

Using Java 1.2. makes this easy, because the UIManager lookandfeel of the Swing-classes, allows you to choose between a platform-typical surface and a surface which is platform-independent. I chose the last one, so that it looks always the same, no matter, if you run it on a Windows- or UNIX-computer, e.g.. The main advantage is, that, using the look-and-feel-manager, all components are painted in the same style. So you donít have to take care about the colours of the button-texts, the size of the scrollbars... . The only disadvantage is, that it is not longer possible to use non-Swing-components, that have been improved by Swing, because this could lead to unwanted effects.

In every frame and in every panel, I used the gridbag-layout. It is true, that this is the most complicated layout-manager, but it is also the one, that gives you the most powerful control about where to place the components, and how they should react on a resizing of the frame.

Placing a component with this manager works not by giving the exact pixels in the frame, but by handing over only relative values. You can split up your area into several parts, by creating a grid with the Constraints-instance. Here you can say, how much rows and columns you want, and how large each cell should be. But all values are relative, so, resizing the area, resizes every cell, and with that every component in it.

The only controls over the absolute values of the components are:

To get good results, you have to overlay different panels, that all contain their own gridbag-Layout. To make it easier, I wrote the Panel2 class, which extends the JPanel class by adding the buildConstraints-method, which allows to set all Constraints-values I needed with only one constructor.

Following the idea of doing this meeting-scheduler as similar to a normal timetable as possible, but also add some additional improvements led me to the following conclusions:

Every day is shown by itís own table (JTable), so that the user can scroll it with the arrow-keys, without influence the other day-tables. So, s/he can e.g. compare the last meeting of one day with the first of the following (But, of course, all tables can be scrolled by a single scrollbar). Another idea for that was, to make the table of the first-shown day larger than the others, to show more information. But in the end, I dropped this idea, because I think it would have led to more confusion than it would have helped in any way.

Every table is placed in a JViewport. This is necessary, because otherwise, you couldnít scroll through it, and it would be shown completely on the screen. Also, the sizes of the single cells are not every time the same, and so, resizing one row or column would lead to a resize of the whole frame. Usually, you should place it in a JScrollPanel, so that you have full control over it by two scrollbars for horizontal and vertical. This didnít work for me, because I wanted 5 tables to be controlled by only one scrollbar. But influence the viewport is also very easy.

I spent a lot of time with thinking of how to show a fixed meeting in the tables. Java-tables donít give you the possibility to colour a special cell, or to paint a border around. So, it is very hard to different between successive meetings in the timetable. In the end, I painted my own backgrounds and strings, by modifying the paintComponent method of the JTable. I easily painted the cells of the table over, which contain meeting information. Instead of the cell-string, now you can see a box (Rectangle). Itís background-colour ranges, according to the priority of itís meeting, from yellow (low priority) to red (high priority). In front of this, the strings of the respective cells are printed.

Cells, which donít contain meeting-information are also painted over by a box. Itís background colour ranges from white to blue, according to itís priority, set by the preferences. This boxes have a smaller size, than the cells, so that you can still see, if they are selected or not (selections are painted directly to the JTable and not on the boxes, with which I painted it over).

Now, there is the question, why to take a JTable at all, if all itís cells are painted over anyway? The answer is the great possibility of tables, to handle data, and to react on mouse-clicks by the user. Even, if the whole table is printed over, it can still receive user inputs.

To react on user-inputs like this, Java contains the so-called Listener-Interfaces, which can be found in the Java.awt.event-classes. E.g. you have the ActionListener, to react on mouse button clicks, selections in a combo-box,..., or the ComponentListener, that reacts on the resizing of a component e.g. . The only thing, you have to do is, to implement this Interfaces in your class and to register the components, you want to be observed. Than, the methods of the implemented interface are called automatically.

1.2.2. Calendar

With the GregorianCalendar class of Java1.2. (java.util.Calendar), itís very easy to implement calendar-data. Calling its constructor leads to an instance, that contains the actual year, month, day, hour, minute and second. Itís also possible, to change its values by adding or subtracting an offset to the wanted value. Itís realised by itself, if a handed over value fits, or not. E.g. a handed over month value of 13 will lead to an increase of the year-variable and to a month-value of 2 (month are counted from 0 to 11).

The program uses a lot of GregorianCalendar-instances:

1.2.3. Data-classes

To store the working data, I needed several classes:

  1. default settings
  2. meeting-data
  3. a possible time-slot
  4. a list of all possible time-slots
  5. a list of all fixed meetings of one day
  6. a list of all fixed meetings of one year/of all years
  7. a list, to store the meeting, that should be scheduled, all possible time-slot of the host-agent and of all invitees
  8. a list of still unfixed meetings
  9. the identification-values (for the rooter)
  10. an array to store all information of the agentís directory
Many of them are arrays, or lists. If the data had fixed borders, I used arrays, of course. But if you donít know them, Java gives you the following three possibilities:
  1. Vector: extends the java.util.AbstractCollection class. It is something like a growable array, because its objects can be called by an index. But, as it tries to optimise the storage management, every vector has itís own capacity, which is at least as large as the size of the vector. So, every time, a new object is added, this capacity has to be calculated new, and may replaced onto another place in the memory. Therefore, for very large lists, itís not the favourite solution
  2. ArrayList: extends the java.util.AbstractList class. You can also call it a growable array. Like at the Vector, you can get the objects you want, by handing over an index. But in contrast to it, it contains all optional list operations. Its advantage is, that you have a fast access to all itís elements. But, with the disadvantage of long needed times to add or remove an element, if the list gets bigger. It is only suitable for small lists.
  3. LinkedList: extends the java.util.AbstractList class, too. But in difference to the ArrayList, this is a real double-chained list. It doesnít matter, how large the list becomes, the times to add or delete elements is every time the same short. But, the longer a list is, the longer is the access time, to get a special element.

a) Default Settings

During the runtime, the user can set several preferences-settings. These are than stored in the DefaultSettings-instance. It is a simple class, which contains only the different variables to store the values. Also it implements the Serializable-Interface (, to allow a load and save mechanism. The single values are:

b) Meeting-Data

The Meeting-class contains also the Serializable-Interface, and it can hold all the following information:

Besides this, it contains a method to clone itself. Java gives you the interface Cloneable, to do it automatically, but I had a lot of trouble with it. So I wrote my own clone-methods for most of the objects.

The finalize-method is been called, when the meeting is scheduled. Here all final values, like the starting- and ending-time are set.

c) store a possible time-slot

    A Ąpossible time-slot" means not, a slot that automatically fits for all meeting-members. It usually contains only a slot of one user, that has lower priority (set by the preferences) than the meeting, to be scheduled. In fact, it can store, the beginning and ending time of the slot, its day, month and year, its priority and the name of the agent, which created it.

    Also, it can contain a combination of two or more slots. Then it holds all priorities of the comprised time slots and the belonging proportions. Both are store in arrays, and can be set by the addTimeAndPriority-method which calculates the new proportions (See VI.1. Elementary parts).

    The Serializable-Interface allows the instances of this class to be stored, too.

d) a list of possible-time-slots
    Of course, a user normally has not only one time slot, that fits. To store all possibleTimes-instances, I wrote the PossibleTimeList, which extends the LinkedList (java.util.) by the some additional methods.

    The correctList-method combines two or more successive possibleTimes, if both are able to accommodate the meeting. This works like this: If the list has the size x, it runs x time through it, and combines a slot with its following one, if the ending-time of the one is the starting-time of the others. In fact, it sets the ending time of the first slot, to the ending time of the second and adds the secondís priority and time to the first one. After that, the second slot is been deleted.

    Finally, it takes all the slots that are between the userís preferred hours and places them at the beginning of the list. So if the calculation-module seeks for fitting slots, it first tries these one.

    The removeToShortPeriods-method is called, after the correctList-method. If there are still slots left, that are shorter than the meeting-duration, they will be deleted.

    The extra times before/after the meeting are private values of every agent. They have nothing to do, with the scheduling-process in the true sense of the word. So, the removeExtraTime-method subs them from every (still combined) slot. After a meeting has been scheduled, they are added again, so that they are only seen in the agent-owned timetable.

e) a list of all fixed meetings of one day

After a meeting has been fixed, it has to bee shown in the timetable, which contains columns for every day. So, it seemed the best way to me, not to store all fixed meetings in a large list, but first store them in a smaller day-list. This is implemented in the LinkedListDates-class.

It will contain only meetings that still have been finalised (see above). Its only method is the addMeeting-one. Before adding a meeting to the list, it first searches for the right place, so, that in the end the list is always sorted by the beginning-times of the meetings.

f) a list of all fixed meetings of one year/all years

The ArrayListYears-class finally is the instance, which contains all fixed meetings. It holds one LinkedListDates-array with the size 12 and 31 for every year. So it contains the LinkedListDates-instances, sorted by day and month. It extends the ArrayList, and to add a new element, the addYear-method is called. As a new year is only added, if necessary, it checks, if the interval, to place the meeting, stretches over more than one year and if all the needed years are still added to the list. If not, it creates a LinkedListDates[12][31]- array and adds it. Here, itís important, that the first year of the list is 1999, which has the index 0. So, if any year has to be added, its index is the number of the year minus 1999.

For all other methods of this class see 1.3.Calculation Module

g) a list, that stores a meeting, that should be scheduled, all possible time-slot of the host and of all invitees

    An instance of the Proposals-class can store one meeting and an array of PossibleTimeList-instances, which usually contains all proposals (PossibleTimes) of all meeting-members. Every array-element represents one member.

    If a member replies, the addPossibleTimeList-method is been called. To avoid errors, it first checks if this member hadnít already replied. If no, itís proposals are added at the first free position of the array. By holding the number of meeting-members and the number of how much already replied, it returns true, if all members replied and false else.

    The second important method is setBackNumberOfReplies. It is called, if the agent needs more proposals from the invitees, because it couldnít find a fitting slot for all members. It deletes all objects of the array and sets the number of replies back to 0.

h) a list of still unfixed meetings
    All Proposals are hold in the LinkedListUnfixed-instance (extends LinkedList). If the agent needs to access to one of the meetings, again, mostly, it has only got the meeting number, which identifies it. To get the entire meeting, the getMeeting-method can be called, by handing over a meeting instance, that only holds the number. To find the right place in the list, it calls the getMeetingIndex-method, which runs through all held elements and compares the meeting-number.

    The removing of a meeting is much easier, because you can call the remove(Object o)-method of the LinkedList, that searches the right object by itself and removes it.

    The class contains also a load- and a save-method, which are called at the start of the agent and on every change of the list.

i) the identification-values (for the rooter)
    the IdentificationSettings-instance holds all information, that are necessary to connect and register at the router. It is loaded at every start of the agent. It the corresponding file is not available, it has to be set new.
j) an array to store all information of the agentís directory

all data of the agents-private directory is hold in a simple Object-array. It is loaded every-time, the directory is been opened, and saved, or if it is closed again.

1.2.4. Calculation Module

The calculation module will be responsible for the calculation of the agents fitting time slots, if a meeting should be scheduled. In fact, it takes the whole time-interval, in which the meeting is going to be scheduled, than sub all fixed meetings form it and finally all slots, that are smaller than the meeting-duration. The majority of all calculations, done with the agents-private meeting-data is done by the ArrayListYears-class. To schedule a meeting (as invitee, or host), first the following methods are called:

  1. getPossibleTimes: returns a list of all time-slots, the meeting, that should be scheduled, fits in; but only looking to its priority. Therefore, it first checks if the interval, in which the meeting should be scheduled, stretches over more than one year and it adds a new one, if necessary. After that, it gets all time-slots, set in the DefaultSettings-instance, for every weekday of the interval, converts them into PossibleTimes-instances and adds them to a PossibleTimeList-instance.
  2. subFixedMeetings: subs all that time-slots from the list, that still hold meetings. First, it checks, if the list really contains any slots. If yes, it runs through every single day of the given interval, and gets every fixed meeting. Than it checks:
(for more information and illustrations, see VI. Negotiation Strategies)
  1. correctList: of the PossibleTimeList. This method corrects the list, by combining two or more time-slots, if the ending-time of one is the starting-time of the next, and day, month, and year of both are the same. After this, it calls the removeTooShortPeriods-method and finally, it gets the preferred-time-slots for the meeting and adds them to the beginning of the list, so, when this list is taken to schedule a meeting, first itís been tried to schedule it in this hours.

  2. But this preferred slots are not removed from its original positions, because than, you maybe would split up time-slots, what would lead to an error. The only disadvantage is, that the preferred hours are now two times in the list, what leads to an increased work-intensity for the calculation-module.
  3. removeTooShortPeriods: also of the PossibleTimeList. It checks, if the handed-over list contains any PossibleTimes-instance, that contains a time, that is shorter than the meeting duration. If true, they are deleted.
  4. subExtraTime: of the PossibleTimeList. If you hand over a list of all slots of the wanted interval, that can take up meetings with priorities equal or larger than the current one, and also, itís durations are larger than the meeting-duration, it will sub the extra time for this meeting from the slots. This is necessary, because every invited agent has its own different extra-times for this meeting. So, before an agent can send itís possible time slots, it has to sub the extra time, so, if the meeting finally is scheduled, it could add them again.
Now, you have all possible time-slots for this meeting. If the agent is the only member of the meeting (e.g. a private free time of the user), the meeting can be scheduled yet. If not, these list will be handed over to the negotiation-module.

Instead of calling all these methods, you can also call the addDate method, which checks out the right conditions: is the agent invitee or host-agent? Is it the only participant of the meeting? Then it calls every single method (see above) and replies a message to the sender, depending on the condition.

The tryToFix-method first gets the LinkedListDates-list of the belonging day of the handed-over meeting. There it checks if the slot, to fix the meeting is still free. Therefore it runs through the list, and checks every single meeting. Actually, you have to check the list, only until one meeting-starting-time is larger than the handed-over-meeting-ending-time, because the list is ordered. But to make it safer, I wanted to check the whole list. The loss of time is not very much, because the list contains only the meetings of one single day, so it will never held more than 10 or 15 elements.

If the slot is still free, it calls the finalize-method of the Meeting-instance (see above) and then the addMeeting-method of LinkedListDates, which simply adds the meeting at the correct position in the list. The update2-method of CentralLayout is responsible for the graphics. Finally, to remove the meeting from the LinkedListUnfixed-instance, its removeMeeting-method is called.

The getDayMeetingTimeFor-method gets the LinkedListDates-list of the day of the handed-over PossibleTimes-instance. There it adds all duration of the fixed meetings and returns this number.

The cancelMeeting-method gets the LinkedListDates-list of the belonging day of the handed over meeting and calls itís remove-method with the meeting. After that, it checks, if it was the host-agent of the meeting. If yes, it sends a cancel-instruction to all participants. If not, it sends it only to the host-agent.

The findFutureMeeting- and findPastMeeting-methods run through all LinkedListDates-list of ArrayListYears from the actual day on, in the future/past, until a meeting-number equals with the handed-over meeting ones. If a correspondence is found, it returns the meeting, otherwise null.

1.2.5. Negotiation-module

Most of the negotiation-actions of the agent are done by the ProcessMessages-class. Its instance is called, always when a new message arrives.

If the agent is invited to a meeting, at first, the newInvitaion-method will be called, which at first adds the default-priority for the sending-agent and the default extra time (both taken from the saved SelectParticipantsTable-class) to the meeting. After that, it creates a new Proposal for this meeting, where it stores the meeting data and itís first ten best fitting slots, that it gets by calling the addDate-method of the ArrayListYears-instance. Also, every slot contains the priorities of every of its elementary slot (set by DefaultSettings, see 1.2.4. Calculation module, correctList, above). addDate also sends a reply to the host-agent, that contains these ten best slots, with their priorities and the belonging meeting-number.

The Proposal is then added to the LinkedListUnfixed, where it stays, until the meeting is scheduled.

The newMore-method is called, when the host-agent wants more proposals. First, it converts the handed-over meeting number into a meeting, by getting the right Proposals and then calling its getMeeting-method. Then, actually, it calls only the same method, than the newInvitation-method. The different is, that the numberOfTries-variable of the meeting has increased. This means that the agent now search and replies the first e.g. 20 best fitting-slots.

The newChoose method is called with a handed-over meeting and a PossibleTimeList-instance. Like the newMore-Method, it converts the meeting (which usually holds only the meeting-number) into a real meeting. Then it calls the getPreferencesForSlots, that returns for every slot (handed over as a PossibleTimeList) a number, that shows how well the meeting fits, paying attention to its priority, and how well it fits, noticing the whole day of the belonging slot. The higher the returned number, the better the meeting fits.

The result-PossibleTimeList, containing the slots together with their relative numbers is then sent back to the host-agent. The relative numbers are saved in the priority-variable of the single PossibleTimes-instances.

The fix-method is called with a PossibleTimeList-instance, which contains only one time when the host-agent gives the command to fix the meeting. Then it calls the tryToFix-method of ArrayListYears, that returns true, if it had success. If not, it sends the cancel-message back to the host-agent. Otherwise the method ends here.

If the agent is the host-agent, it receives from every invitee a PossibleTimeList, which holds their favourite time-slots for this meeting. If this happens, the newCounterProposal-method is called. Like the other methods, it first gets the belonging meeting out of its UnfixedMeetingList (see above). Then, it adds the sent PossibleTimeList to the Proposals-instance of this meeting. If the replying agent, was not the last invitee, the method finishes here.

Else it calls the solutions-method, that simply returns all slots, that fits for all agents, and after that the findBestSolution-method, that returns the first x best-slots.

If there was no return, which means, that there was no time slot, that fitted for all agents, it send another message to all invitees, to get more proposals. Also, it calls the setBackNumberOfReplies of the Proposals-instance, to wait again, until everyone had replied. The first Ąreply" is of course done by itself. By calling getPossibleDates and getFirstPossible of ArrayListYears it gets the still known fitting-slots plus five additional ones. The list of them is the added again to the Proposals.

If there was only one return, it calls the addExtraTime-method of PossibleTimes, and then tryToFix of ArrayListYears, to fix the meeting in itís private timetable. If this returns a success (maybe another meeting had fixed for the slot, in between), it subs the extra-time before/after again (itís not interesting for the other agents) and sends the slot to all invitees, so that they can fix the meeting, too.

If their had been more than one possible fitting-slot, it calls the getPreferencesForSlot-method (see below, or newChoose, above), and adds the new list to the Proposals, where all PossibleTimeLists of the other agents, have been deleted, before. After that the fitting slots are sent to the invitees, so that everyone can choose itís preferred ones.

As soon as an agent returns its preferred ones of the fitting slots, the newFinalPreferences-method is called. First it gets the meeting, belonging to the handed-over meeting-number. Then it calls the addPossibleTimeList of Proposals, which returns, if the reply was the last one or not. If yes, it will add the sent relative-numbers of every participant for every slot. Finally, it creates a PossibleTimeList, that only contains the slot (as a PossibleTimes-instance), with the highest number (the best one).

Finally it calls the tryToFix-method of ArrayListYears (handing over the slot, with the extra-time before/after added to) to fix the meeting in its own timetable. On success, it sends the Ąsolution-slot" (without the extra-time) to the invitees, so that they can fix the meeting, too.

The newDelete-method will be called, if the host-agent wants to tell, that this agent has to delete the handed-over meeting from its unfixedMeeting-list. This can have two causes:

  1. The meeting can not be fixed
  2. The meeting can take place, but only without this agent
In both cases, it gets the whole meeting (see above) and calls the remove-method of unfixedMeeting-list, handing over the meeting.

The newCancel-method can also be called because of two cases:

  1. A host-agent sends a cancel-instruction to all participants of a meeting
  2. This agent is the host-agent, and one of the invitees send the cancel-instruction
In both cases, it gets the whole meeting (see above) and calls the cancelMeeting-method of ArrayListYears, but in case 2, it first checks, if the sending-agent-user is indispensable for the meeting. If yes, the meeting is been cancelled.

The solution-method is called with a Proposals-instance. In every of itís loops, it runs through one of the Proposals-PossibleTimeList-lists and compares it with another one. The result is a new list, that contains all corresponding-slots. Therefore, it compares all beginning and ending times. If a slot of one list is a part of a slot of another list, it takes the shorter one. If a slot of one list starts earlier and ends earlier, too, than another one, it takes the latest starting- and the earliest ending-time. In the end, it returns a list, which contains all slots, that fits for every list (for every meeting participant) (see VI. Negotiation module).

The findBestSolution-method is called with a Proposal-instance and the belonging PossibleTimeList, which contains all the slots, that fits for all meeting-participants (calculated by the solution-method). It first checks the takeFirst-Value of Default-Settings.

  1. takeFirst is true: this means, that the earliest fitting slot is the best one. As the PossibleTimeList is still ordered, it simply gets its first element (a PossibleTimes-instance) and returns it.
  2. takeFirst is false: this means, that takeBest is true. So, it has to calculate that slot of the fitting ones, that fits the best for all meeting participants (the solution). Therefore, it does the following steps:
The getPriorityForHost-method is called, when the agent is an invitee. It loads the participant-table-values (see 1.2.8. directory) as an array. The third row contains the agent-names, so compare the handed-over hostname with this row, until you find it. Than take the tenth value of this row, (which contains the priority for this agent). Because this is a string, you have to convert it into an integer.

The getAverageForPriority-method returns the average priority of all elementary-parts, the handed-over PossibleTimes-instance contains. The difference to findBestSolution (see above) is, that this method is only for the agents-private values.

At first, it calculates the day-of-week of the PossibleTimes-instance with a GregorianCalendar-instance. Then, it looks in the DefaultSettings-instance for the belonging day-priorities- and belonging time-intervals-lists (elementary parts). After that, it gets all elementary parts that fit into the PossibleTimes-intervall (maybe the first and last parts have to be adjusted). Finally, it takes for every part the belonging priority, multiples it with the times and adds all results. The sum divided with the whole time is the average-priority, which is returned.

The relativeFitting-method returns a relative number, that says, how well the meeting would fit in the handed over slot. It does not look at the priority, but looking, how many meetings are still fit on the belonging day and how much time do they take.

Itís called with a list of all solution-slots (PossibleTimeList) and the number of the slot, to be looked at. After it gets the current slot out of the list, it calculates the total meeting-time of belonging day by adding all durations of the still fixed meetings (held in the LinkedListDates-list) and the total number of meetings. The second step is, to get a sum of all meetings and a sum of all meeting-numbers of every solution-slot-day.

Now, it divides the whole meeting-time with the meeting-time of the current-slot-day and multiples it with 4. So, it gets a relative number (float) ranging from 0-4. The higher the complete meeting-time of this day in relation to the complete meeting-time of all solution-slot-days, the lower is this number (called timeRelation).

The second number represents the relative meeting-number of the current-slot-day. The steps are like above, only that you take the meeting numbers instead of itís times. The range of the result is also 0-4 (called numberRelation).

Finally it adds the timeRelation two times to the numberRelation and divides the result with 3, so that the importance of the time is double of the number, in the result. At last, the result is returned.

The getPreferencesForSlot-method is called with the respective meeting and all solution-slots. It runs through every slot, and calculates a number, that represents, how well the meeting would fit in every slot. Therefore it calls for every slot the averagePriority- and the relativeFitting-method and multiples their results. The outcome is then multiples with 1000 to get an integer-number that is as exactly as possible. All results are than saved by calling the setPriorityAndPercent-method of every slot (PossibleTimes-instances).

If it is not possible, to fix a meeting, because there are no slots, that fit for all participants, you can try to get better results by leaving one or more of that participants out, that are not really indispensable for the meeting. In such cases, first the checkMeetingPossible-method is called with all names of the indispensable participants.

As the names of the participants are held by every PossibleTimes-slot of the PossibleTimeList (handed over as a Proposals-instance), it simply gets the name of the first element of every list and compares it with the handed-over list of names. If there is a correspondence, it copies this complete list into a new array of PossibleTimeList. Finally, it creates a new Proposals-instance, which contains the meeting and the array and returns it.

So, now the meeting is tried to be fixed, again. But this time only with the indispensable participants. If there is success, the agent tries to add as most as possible of the other participants again.

1.2.6. Communication-module

For the techniques of sending and receiving messages, see I.2. JATLite

1.2.7. Preferences

All preferences are stored in a DefaultSettings-instance (see I.1.3. Data-classes). The user can manipulate the values during the runtime of the agent in the Preferences-interface.

What is interesting, is the SetDayDefaults-component. Here, the user can create small slots for every weekday. On the top of the component is a JComboBox, where s/he can select the day, to be manipulated. To set the time of the slots, there are nine JSliders and to set the priority (which means that these slots will only accommodate meetings, that have an equal or higher priority than the one of the slot) there are JComoBoxes, too. Their use is as usual.

To make it easier, the user can also set slots by default for every working- and every free day. To set the slots of a weekday back to itís defaults, on the bottom is a button.

The sliders have a range from 0-1440, what represents the minutes of a day. If the constructor of the component is called, the DefaultSettings will be loaded, and the sliders will be set to their positions. If one of the sliders is moved, the stateChanged-method of the ChangeListener-class is called automatically. It then calls the updateTimes-method, which prints out the new state of the slider (which is the new ending-time of the slot).

The important thing is, that the ending-time of one slot is always the starting-time of the next one (except the last slot). The first slot always starts at minute 0, the last ends at 1440. So, moving one slider can lead to a change of time of many slots. This is calculated by the updateTimes-method. Therefore, it starts with the first slider and runs to all. If now slider x is set to a lower value, than slider (x-1), it will be set to the value of that one. The result of this is, that slider x in the end always has an equal or larger value than slider (x-1), so slot x is always earlier as slot (x+1) and there are no overlappings.

If the Preference-interface is closed, all values are saved on the HD and in the DefaultSettings-instance. The values of the slider of SetDayDefaults are the values of the dayTimes-array- and the values of the priority-boxes are the dayTimePriorities-array of the (also in SetDayDefaults) selected day.

1.2.8. Directory

The address-table of the agent implemented in SelectParticipant, SelectParticipantTable, SelectParticipantRouter and SelectParticipantRouterTable.

If the user wants to schedule a meeting, s/he can select the participants in the agent-private directory. If itís opened, the SelectParticipant-instance is initiated, what lead to a new JFrame, which contains several buttons and a table, implemented in SelectParticipantTable. Also, the directory-data is loaded from HD (file: participant.adms).

The table itself contains a TableModel, which is implemented in the SelectTableModel-class. Here all settings of the table are held: The number of columns, their names, their preferred size, and a boolean, that says, if they are editable or not. Also it holds the complete data (in an array) of the table with methods, to modify it.

The table has the following columns

  1. a button to select/deselect a participant for a meeting
  2. a button to select the participant as indispensable/dispensable for the meeting
  3. the agent-names
  4. the names of the agent users
  5. the first names
  6. the company
7-10. combo-boxes to select he default extra time (hours/minutes, before/after a meeting), which will be taken, if this person is scheduling a meeting and the agent-user is invited

11. a combo-box to select the default priority, which will be taken, if this person is scheduling a meeting

  1. a button to delete the persons from the directory
If the user wants to add a new name in the directory, a new JFrame is opened (SelectParticipantRouter), which contains another table (SelectParticipantRouterTable), which has only two columns. One to select/deselect and the other containing the agent-names. Before the data can be shown, first the agent sends a message to the router (see I.2. JATLite), that it wants a list of all currently registered agents. After receiving, the names are put into the table.

Every time, a new name is added, or an old one is deleted, the directory data is saved to HD.

2. JATLite: Java Agent Template Light

JATLite is a package of JAVA-classes. Itís created for an easy way of creating agent-systems. You have interfaces, that can be implemented and classes, of which you can derive subclasses.

Figure 3. set-up of a JATLite-agent-system

2.1. Set-up of a JATLite-agent-system

As a main difference to its precursor JAT, JATLite uses a router instead of a nameserver (ANS). The advantage of this is, that agents can be implemented as applets, because through it, they comply all safety-rules of WWW and Java. An agent can be started on a client and it does all its communication above its home-server.

The main disadvantage is that you now have strong centralisation, what can lead to loss of scalability and an increased susceptibility, because of the weak-point server.

2.2. Communication via router

If an agent wants to communicate with another one, first, it will have to authorise itself at the router. Usually, this happens by handing over a password and identification.

All messages are sent via the router, which float-charges them (like an email-server). In that way, no message will get lost, if an agents isnít available for a time. This is very important for my agent-system, because maybe a businessman takes his laptop with him, when he travels to his next meeting. In such cases, the laptop isnít online the whole time. So, using the usual Java-communication would lead to a loss of messages and the agent could not work correctly. Using JATLite has the advantage, that all messages are stored in the buffer of the router, which sends them to the agent, as soon it is available, again. Now the agent can answer all incoming messages.

2.3. class-hierarchy

The JATLite architecture is organised as a hierarchy of increasingly specialised layers, so that developers can select the appropriate layer from which to start building their systems. Thus, a developer who wants to utilise TCP/IP communications but does not want to use KQML can use only the Abstract and Base layers.

Figure 4: the JATLite layers

a) Abstract Layer

the abstract-layer gives you a collection of abstract classes to implement JATLite. All connections are TCP/IP. If you want other protocols (like UDP) you have to upgrade the layer.

b) Base Layer

The base layer makes the TCP-IP-basic-communication available

c) KQML Layer

The KQML layer provides parsing and saving of KQML-messages. It contains protocols for registration, connection set-up, connection tear-down, etc.

d) Router layer

The Router Layer provides name registration and message routing and queuing for agents. All agents send and receive messages via the Router, which forwards them to their named destinations. As soon as an agent intentionally disconnects, or accidentally crashes, the Router stores incoming messages, until the agent is reconnected. The Router is particularly important for applet agents, which can only initiate socket connections with the host that spawned them, due to WWW and Java security restrictions.

e) Protocol Layer

The Protocol layer, on top, supports different standard Internet services such as SMTP,FTP,POP3,HTTP, etc. for stand-alone applications and applets.

2.4. KQML

One of the most important things, that distinguishes an agent, is its ability to interact and interoperate with other agents. For this communication, a kind of protocol is required. Using JATLite, KQML (Knowledge Query and Manipulation Language) is recommended to be the best, because it is most supported.

KQML is a language and protocol for exchanging information and knowledge. It can be used as a language for an application program to interact with an intelligent system or for two or more intelligent systems to share knowledge in support of co-operative problem solving.

Using it, agents communicate by passing so-called Ąperformatives" to each other. KQML is offered to the agent community as an extensible language with an open-ended set of performatives, whose meaning is independent of the propositional content language.

A Performative classifies a messages. You can say, that it contains the kind of the message

It is based on an extensible set of well-defined performatives. You can define different classes of Performatives:

Core Performatives: A small set of primitive performatives formally defined to define others

Standard Performatives: Reserved names for performatives that most agents will want to handle

Extended Performatives: Groups of agents can define and use extensions


      Figure 5 KQML-Performatives

Examples for KQML Performatives are:

Basic query performatives:

ask-if: asks, if the contents of the message are available at the receiver

ask-all: asks for instances that can take over a sent task. As a result, a list is sent back.

ask-one: almost similar to ask-all. The difference is, that not a list is returned, but only one agent-name that is arbitrary picked out of the list

Multi-response query performatives:

stream-all: like ask-all, but the result isnít a list, but every asked agent sends back its own answer

Response performatives:

reply, sorry

Generic information performatives:

tell: send back the belonging answer to the agent, which has asked (right)

untell: the answer to question isnít written in the message (don't know)

achieve, cancel, unachieve

Generator performatives:

standby: the receiver is told to collect answers to a questions and sent them back to the sending-agent one by one, if it asks for them

next: sender wants the next answer (see standby)

rest: tells the receiver to end the stand-by and sent back all its answers

discard: tell the sender just to end the stand-by

ready, generator

Capability-definition performatives:

advertise: tells the receiver, which inquiries the sending-agent will accept

subscribe: the result is, that the sending-agent will receive an answer to a question, every time, this answer changes

minitor, import, export

Networking performatives:

register, unregister, forward, broadcast, route

A second important term, if you use KQML, will be "onthology"

An Onthology categorizes objects in that way, that they get a sence for an agent

Ultimately, every KQML message is a simple String with the following Syntax:

<performative>::= (<word> {<whitespace> :<word> <whitespace> <expression>}*)

<expression> ::= <word> | <quotation> | <string> |

(<word> {<whitespace> <expression>}*)

<word> ::= <character><character>*

<character> ::= <alphabetic> | <numeric> | <special>

<special> ::= < | > | = | + | - | * | / | & | ^ | ~ | _ |

@ | $ | % | : | . | ! | ?

<quotation> ::= '<expr> | `<comma-expr>

<comma-expr> ::= <word> | <quotation> | <string> | ,<comma-expr> |

(<word> {<whitespace> <comma-expr>}*)

<string> ::= "<stringchar>*" | #<digit><digit>*"<ascii>*

<stringchar> ::= \

The language itself is splitted up in three parts:

The technical part is used as a kind of protocol, and contains all data, that is important for the communication. This includes the sender, the receiver and an identification-number for every message.

The specification part contains the performative, which holds the information about how the sender has to process the incoming message. E.g. this instruction can tell the receiver to add the new information, the message contains, into its knowledge base, it can be an inquiry for the existing of a sent data.

The data, that is sent, is stored in the contents-part. This is usually coded in KIF (a language to describe simple data, palliations, NOT operations, OR operations, rules and meta-data) but it can also be coded in KRSL or even SQL. You can say, that KIF, KRSL or SQL are the inner languages of KQML. A complete message is a KQML-term includes a KIF/KRSL/SQL-part embed.

Usually, this three parts are called content layer, message layer and communication layer.

2.5. This agent and JATLite

This agent uses the Router Layer, because it communicates, using KQML and also there was a need of the routers full advantages, to make the exchange of messages as safety as possible. As I didnít work with any other kind of sendings, I didnít have to use the Protocol Layer.

All communication-actions are done by the instance of the Communication-class, which extends the RouterClientAction-class of JATLite.

2.5.1. Start of the agent

For a connection to the router, you need:

  1. The name of the router (here ADMSRouter)
  2. The complete address of the router (here:
  3. The ports, the router uses to receive/send messages (here: 4444)
  4. The registrar-name, -address and -port (here: ADMSRegistrar,,4445)
To registrar at the router, you have to send:
  1. Your identification
  2. Your password
  3. Your IP-address
  4. Your port-number, that you want to use to exchange messages with the router
You have to registrar only once. Every time, you send these data to the router again, it only registers, that your agent is online, again. If the router received messages, during your agent has been disconnected, it will send them immediately.

If the agent is started, the constructor of the communication-class is called. Here, all identification-data is loaded from the Ąid.adms"-file and handed over to the belonging variables. The file does not contain the router-address, because it is fixed in the program-code (you have only one router, usually, so it isnít necessary to load it every time).

By calling the JATLite-methods setMyAddress(address), setRouterAddress(address) and setRegistrarAddress(address), you set the several addresses. After this, you can call the registrar()-method. Now, the router knows, that a new agent wants to registrar, or rather a known agent wants to reconnect. To open the connection to the router, you have to call the connect()-method. This can lead to a connection-exception, so you have to catch it. Now, your agent is able, to send and receive messages to/from the router.

2.5.2. Receiving messages

For an example of a KQML-message, send by an agent, see 2.5.3. Sending messages.

If the agent receives a message from the router, automatically the Act-method is called with the received object. As the agents only send KQML-messages, firstly, the object is converted into a string, and then into the JATLite-object KQMLmail. This has the advantage, that you can add it to the _mailQueue, which is important, if the agent hasnít still computed one message, and still receiving another one. With the mail queue, you can avoid troubleshooting.

After that, you can convert the KQMLMail into a KQMLMessage. Now you can get every single String of the KQML-message simply by calling the getValue(name of the string)-method of KQMLMessage.

Every message, one agent of the system receives, contains an instruction. At first, this instruction gives the Act-method the information, what kind of message has arrived. You can difference between three major kinds of messages.

  1. The first one contains only every needed information of a Meeting-instance. This is used, to invite an agent, to tell it to delete a meeting from his list, to cancel a meeting or if the host-agent wants more time-proposals.
  2. The second one contains all data of a PossibleTimeList-instance, additionally to the Meeing. It is used to send a proposal, to fix a meeting on a special date, if the host-agent wants its invitees to choose their preferred slots for a special meeting out of a sent list or if an invitee wants to send back these preferred slots.
  3. The third type of message is needed for the directory of the agent. It can ask the router to send a list of all currently registered (not necessary connected!) agents. The returning-message then contains all names of the wanted agents.
In the first and second case, the getMeetingValues(KQMLMessage)-method is called. By using the getValue()-method of the KQMLMessage-instance it gets all meeting information as Strings. After converting them into the right forms, a new Meeting-instance is created, set to the sent values and returned.

If the message was from the second type, a new PossibleTimeList is created. The message then also contains a number, that represents the number of sent PossibleTimes. Every String of the KQML-message is marked with its belonging name (e.g. day, month), but also with its number. So in the end the message will look like

:day1 (12) :month1(11) ...

:day2 (13) :month2(11) ...

Like the Meeting-values, the PossibleTime-values are get by calling the getValue()-method, and then converting the Strings into the right forms. Every PossibleTimes-instance is finally added to the PossibleTimesList.

At last, the ProcessMessages-methods (see above) are called, that belongs to the instruction of the message (instruction Ąchoose" leads to method newChoose, Ąfix" to newFix, etc).

If the message was from the third type, which means, that it contains a list of agent-names, the convertKQMLToAgentNames-method is called. As the router sends more than only the agent names (e.g. the port-number or the IP) this method filters out the important information and gives it back.

2.5.3. Sending Messages

For every message, an agent receives, there must be a counterpart, that has been sent by another agent (or rather the router). To realise the three types of messages (see above), I implemented two different sendMessages-methods.

The first one realises the sending of messages to invite an agent, to tell it to delete a meeting from its list, to cancel a meeting or if the host-agent wants more time-proposals. It is called, by handing over:

Creating a KQML-message is very simple. You can create a usual String and add the data pairs. E.g. the name of the meeting is added as

: meetingname (meeting-name)

After creating this string, you can hand it over to the sendKQMLMessages-method of JATLite, which sends then sends it to the wanted receiver.

For a full example of a kqml-message, that contains meeting-data, see the following figure:

Figure 6: KQML-message of a PosibleTimeList

Using the second version of the sendMessage-method premises, that the receiver still received the Meeting before and stored it in its LinkedListUnfixed. It only sends the meeting-number, so that the receiver is able to seek out the right meeting of its list (the meeting-number identifies a meeting 100%).

Also, the values of a PossibleTimeList are sent. It can be

  1. proposals of the invitees
  2. a list of all fitting slots, with a number, that presents the slot-priority of all participants (send by the host-agent)
  3. the fitting slots with a relative number, representing, how well the slot would fit in the time-table of the sending-agent (send by the invited-agents)
  4. the final slot, where the meeting will be fixed in (send by the host-agent)
In any case, it will be a number of PossibleTimes. So, the sender firstly has to convert all values in Strings of data-pairs. A pair is created, exactly as above.

The first number says, how many PossibleTimes will follow. So, it is easier for the receiver, to parse the strings back to a PossibleTimeList. Than, the wanted data follows.

The counterpart to the message that is sent to the router, leading him to send back the list, is a simple call of the JATLite listUsers()-method.

Every time, you send a message, you have to catch a possible connection exception by a try-catch-construct.

To make the messages visible, I created for every agent a frame with one part for outgoing- and one for incoming messages. Ever message (received or sent) is converted in a String and formatted. After that it is handed over to the ShowMessages-instances, which prints it in its JTextArea.

3. Problems

I underestimated the time, spending to create a user-friendly interface. As I worked with Java the first time, I was proceeding on the assumption that a user-interface would be easy to create. But truth is, that Java may be a very good language, to create agents and to realise their interactions, but on the other side, looking on itís possibilities of fast creating, well looking graphical interface, it cannot reach on products like Delphi or the C++-Builder, while the JBuilder still have some problems.

Another point is, that the promise, using the Java-swing-classes to create the user interface, would lead a, on every machine the same looking and working interface, isnít 100% true. I worked on a Windows NT and a Windows95 computer, what led to some confusion, during creating the interface. E.g. while JDialogs worked correctly on the Windows NT-computer, it led to an abort of the program of the Windows95-machine, in some cases.

V. Features

1. User-input-autonomous

    Following the idea, that the typical user of these agent is a businessman/-woman, that does not sit in front of his/her computer the whole day, the agent has to be as user-input-autonomous as possible. Of course, if the user wants to schedule a meeting, s/he has to input several values, like the meeting-duration, participants, etc., but, as far as possible, this should be the only input, the agent requires.

    So, the user can concentrate on more difficult jobs than scheduling his/her meetings. The only thing s/he has to do, is looking on the timetable from time to time, to see what are the next meeting, s/he has to join.

    In fact, if the user doesn't want to be a meeting-host at all, the agent will be able to work without any user input all the time it runs.

    The priorities for the incoming meeting-proposals are taken out of the agentís directory. There, the agent seeks out the name of the host-agent and gets its belonging priority. The same with extra-time before/after. So, if the user wants an agent up to date, s/he has to update the directory, from time to time. But even without any input in the directory, the agent runs without problems. In such a case, or if the host-agent isnít found in the directory, the priority and extra-times for the meeting is taken out of the default-settings of the agent.

    The default-settings will also be taken, if the agent seeks out the best slots for a meeting, because, there, the settings for every weekday are held.

    If a meeting is finally fixed, the agent visualises it in the timetable, without any unnecessary popups or messages for the user.

2. Priority orientated

If a meeting has to be scheduled, the agents of the system donít look to the number of participants, the size of the interval, the meeting should be scheduled in, or the length of the meeting, to find out itĎs importance for themselves. They absolutely most important thing is the priority. What lead me to this solution, were the following points:

The problem is, that the agent can only look to the priority of the host-agent and not to the priorities of the other invitees. So, it doesnít take care, if the host-agent is Ąunimportant", but one of the participant is Ąimportant". Of course, you would get the best results, if you want the user to input a priority for every incoming meeting-proposal. So, you could avoid any misunderstandings. But this would be against point 1 (user input-autonomous)

I think, it would also be important to let the number of cancels of a meeting flow into the determination of its priority. This means, if the agent cancelled a meeting sometimes before (because of another meeting with a higher priority), it will get a higher priority, the next time it is getting to be scheduled. This would avoid total disappointed partners. I didnít implement this only because of the missing time.

3. User-friendliness

    As the possible user is a very busy person, the handling of the application should be fast to learn; the way of doing actions should be as easy as possible. Therefore, I tried to do the surface clearly arranged.

    The major part is the timetable. It allows the user to get allimportant information with only a single short view. It is arranged like a usual paper-timetable, so that the user needs no time to get used to a new display format. Usually, the actual day is the very left one. So, if the user wants to know, what is the next meeting, s/he only has to look to that day. But showing only the actual day, could be not enough, in some cases, because some times, the user also wants to know the meetings of the next days. Therefore I chose the way to present five days at the same time.

    Figure 7 timetable

    Another feature of the timetable is, that every meeting gets a colour, belonging to its priority. Yellow means priority one. The higher the priority of a meeting, the more red gets the colour. This has the advantage, that the user can see all important meetings in a very short time. The blue colour shows the priority of every slot (e.g. a slot with priority 5 can only accommodate meeting with priority equal or larger 5). Like the meeting colours, the darker the colour, the higher the priority. This is not very important for the user. It just visualises the settings for every weekday.

    Sometimes, not all of the meeting data can be shown in the timetable, because there is not space enough (happens if you have very short meetings). Than, the user can get the fully information just by clicking on the meeting.

    I didnít use a menu, because there are not many actions, the user can call. Of course, improving the agent with more features, would make a menu necessary, but at the current status, I think it would confuse more than it could help. Instead of this, the user can call every function by clicking the belonging button. No matter to the kind of action, in the end, you will always come back to the mainframe automatically.

    Every button and every other component has a tool-tip, which helps to explain. Also I tried to arrange components, that belongs to the same type of action/information, together in one part of the screen.

    Also, I tried, to give the user the possibility to do as much as possible inputs with the mouse, so that s/he donít have to change between the input-devices very often (this saves a lot of time). But, because of the missing time, I couldnít realise this for every input, e.g. inputting a datum can only be done by using the keyboard; opening a calendar-component, to choose the day by the mouse instead of this, would be much better.

    Another important point, to make the agent user-friendly, is to implement a directory. As the agent only works with other agent-names, to send messages, the user would have to know all belonging users-names of the different agents. By using a directory, s/he has to input the belonging user-names to the agent-names, only once. The following times, s/he can select the names of his/her partners, and the agent can seek out the belonging agent-name.

    A list of all actual registered agent-names can also be required.

    I left out any function for saving or loading the timetable. As there can be only one user for one agent, you can have only table-data of one person. So, it would only lead to confusion, if the user could modify the data in that way. Instead of this, the agent loads and stores the data automatically.

4. Large amount of different settings
    The agent gives its user a large number of possibilities to adjust its settings. So a user can modify his/her agent in that way, that it completely met his/her requirements.

    The most powerful tool is the Set-Day-Defaults-box. With it, the user has a total control over every weekday. S/he can set the working-hours, free-days, lunch-break, etc.

5. Security measures

Using JATLite gives the agent a high level of safety, because no message can get lost. This is very important for this system, because loosing a time-proposal of an invited agent would lead the host-agent to wait until the deadline of the meeting, and then maybe the meeting cannot be fixed any more.

Also, to avoid any loss of data, if an agent is run down, or aborts, the following lists are stored on HD, every time they change:

(until the agent is in test, I switched this function off) Every new year takes ca. 6kbyte and every meeting ca. 170 byte, additionally. So the loading times are not very large. And I think a possible user would like it more to have an agent, that is some msec slower than to miss an important meeting.

The other security measures are as usual: call the users attention, if wants to schedule a meeting in the past, by mistake, remind the user to input a priority for a meeting, etc.

VI. Negotiating-strategies

1. Elementary Parts

    The user can create 9 different time slots each weekday, using the SetDayDefaults-component. Each of this slots has itís own priority, which means, that is can only accommodate meetings that have equal or higher priorities, than itself. In the following section, this will be called Ąelementary slots", because they will be the basics for the agent, if it seeks out the fitting slots for a meeting.

    Figure 8 elementary parts

    If the user wants to schedule a meeting, the agent gets all the inputs and seeks out its best fitting slots. Also, it sends messages to every invited agent, to do the same and to send them back.

2. Best fitting slots of one agent

The following values are important for this step:

Finding the best fitting slots, is divided into several steps:

Step1: the agent gets all elementary parts of the interval, which would fit, without looking

at still fixed meetings.

Therefore, it starts at the first day of the interval, only paying attention, which weekday it is. Then finding out every elementary-part of these weekday that has a priority lower or equal the one of the meeting.

Step2: if two elementary-parts are timely-coherent, it combines them. By doing, this, it has to take care on the different priorities. So, it creates a list of all combined parts, containing every priority together with the time of the part in percent of the total time.

If an elementary part, or rather a combination of elementary parts has a time, smaller

than the meeting duration, it will be erased out of the list.

Figure 9, Fitting slots of one day

Step 3: Now the still fixed meetings have to be subtracted. Eventually, combined-slots have to

be erased, or shortened, always taking care of the contained elementary slots

Now you have every fitting slot of this day. At last, the agent has to subtract itís extra-time before and after the meeting. This is important, because the extra-time is a private value. Every agent has itís own one. So, it has to send intervals that are short enough, to add the extra-time again, later, without getting in trouble with still fixed meetings or elementary slots with higher priority.

Figure 10. subtracting already fixed meetings
This will be done for every day of the interval. The final results are stored in a list.

Step 4: Finally, the agent has to find out, which ones are the best slots (by default, it gets the

10 bests). The best simply means, the combined slots with the lowest average priority:

average Priority of a combined slot:

(with: es: elementary slot

p(i): priority of elementary

slot i

t(i): time of elementary slot i)

Now, the agent has a list of its best fitting slots for the current meeting, and sends it back to the host-agent.

3. Fitting slots of all agents

    The host-agent does the same than all invitees and waits, until every invited agent has replied a proposal. Then, it compares every slot of every participant of every day. If there are any corresponding intervals, it stores them in a new list.

    Figure 11 Corresponding slots of all participants of one day

    If there are no corresponding slots, the host-agent asks the invitees for more proposals, until a fitting slot is found. If no invited agent has any more proposals and still, there is no corresponding, the host agent eliminates all slots of those agents, whose user is not indispensable for the meeting (this can be selected by the user of the host-agent, when s/he starts the scheduling).

    If there are no correspondings yet, the meeting cannot be scheduled, and the host-agent does a popup to inform its user. Also, it sends a message to every invited agent, to delete the message from their lists of unfixed meetings.

    This is not a very good way, but because of the missing time, I chose that solution. Actually, it should send a message to all invited-agents, to look for meeting with lower priorities than the current one. The agent that sends the lowest priority than would be asked to cancel this meeting, and the current meeting would be scheduled instead of it. Of course, than the cancel meeting has to be re-scheduled again, automatically.

4. Find best fittings slots for all agents

For the final scheduling you can choose between two strategies.

4.1. ĄFirst Possible"-strategy

    This first strategy is very simple. The host-agent simply takes the beginning time of the first fitting slot and adds the meeting duration. Then, it sends this-solution slot to all invitees. After this, it adds its extra time for this meeting again, and fixes it. All invited agents do the same. If any agent has taken this solution-slot for another meeting, in between, it sends a cancel-message to the host-agent, which starts the scheduling process again.

    At first, I wanted it, just to take the second-best slot to fix the meeting, in such cases. But between the first time, the user starts the scheduling process, and the current time, lots of time could have passed (maybe one agent wasnít online for a period of time). A sign for this is, that (at least) one agentís timetable has changed in that way, that one of itĎs proposed times isnít available anymore. So, maybe the second, third or fourth best slot would lead to a solution, but you can not be sure, if there are some better ones yet. During the passed time, one of the agents could also have cancelled one or more meetings, so maybe, now there are earlier corresponding slots. Starting the scheduling process from the beginning on again, doesnít take a lot of time, so it seemed to be better, to do this, instead of taking just the next best corresponding slot.

4.2. ĄTake Best"-strategy

This second strategy is more complicated. Usually, the found fitting slots are larger than the meeting-duration.

First, the agent calculates for every slot a number, which represents, how well this slot fits, looking at all participants as a totality.

Figure 12 Difference between meeting-duration and duration of a slot

So, the question is: what is the "best" part of the found slot? To find the solution, the agent does the following:

step 1: Usually, the time-slot, an agent has sent as a proposal, does not fit completely for all

other agents (see figure 11), but only a part of it. So, the host-agent calculates for this fitting part for every participant the elementary parts with their priorities. As the invited agent has sent itís slots together with the information of the contained elementary-parts, the host-agent now only has to sub the not-fitting elementary-parts and to short those ones, that donít fit completely (see figure 13). step 2: The agent creates elementary-parts for the fitting slot. Therefore it starts with the first (maybe in step 1 corrected) elementary-part of the first participant and gets itís starting time (it could be any other participant, too, of course, because the starting time of the first elementary part is now the same for every agent). This is the starting time of the first elementary-part of the for-all-fitting slot.

The ending-time is the earliest ending-time of any first elementary-part of the agents. Now, its priority has to be calculated, which is simply the sum of all priorities of the elementary-slots of the participants.

The starting time of the next elementary-part is the ending time of the previous. The ending time is the next earliest ending time of any elementary-part of the agent-time-slots, and so on.

Figure 13 elementary-parts of the corresponding slots

step 3: Now, for every possible combination of elementary-parts, that is just large enough to

take the meeting, the average priority has to be calculated. This is important, to find out, which is the Ąbest" part of this fitting slot.

The agent runs through ever fitting (usually to large) slot, checks for the starting time of every elementary-part, if the meeting could start on this point (the slot has to be at least as large as this starting-time + the meeting duration). If it is possible, it adds the priorities of every elementary part, the meeting would include.

Figure 14 priority of every time-interval, the meeting would include
Of every slot, the agent takes the two best possibilities (if available) and stores them in a list. Iíve chosen this small value, because usually, a time slot will not cover a large time-interval, so there will not be a lot of different possibilities. Of course, the agent has to do this for every slot of every day in the interval. After all, the slots with the lowest average priorities are the best ones.

The 10 best time-slots are then sent to every invited agent, so that every agent (the host-agent too, of course) can find out the best one for itself. Until now, every agent influenced the search for the best time-interval, by sending the time-slots that would fit in their timetable. Also, by looking to the elementary-parts of every agent, now the time-intervals are found, that fit best for the totally of the participants. But the problem, you still have is, that these slots are the best for an average timetable of all participants. So, it could happen, that a found time-slot fits very well for 9 of 10 participants on the one hand, but on the other very bad for the other one. The question now is, if this is really fair! Maybe, another time-slot would be better, even if it is not the best one for average-time-table.

Also, until now, the agents only paid attention to the priorities. As this is a priority-oriented agent system, this is of course the most important feature, but other influences should not be held out. So, after receiving these 10 best time-slots, every agent tries to calculate a number for every slot, which represents, how well it would fit in the timetable.

At first, the agent adds itís extra-time to every time-slot again, because it belongs to the meeting-time, and attention has to be paid to it, as well as to the pure meeting-duration. Than, it calculates again, how well it fits, with its priority. Therefore it subtracts the average priority of the included elementary parts of the meeting duration and multiplies it with 1000.

The second number pays attention to the number of still fixed meetings of the belonging days and their total duration.

First it creates the sum of the number of meetings of every day of the interval. Then it divides it with the number of meetings of the belonging days of every time-slot. The result is a number for every time-slot, which represents, how many meetings are fixed one the belonging day, relative to the number of meeting per day of every time-slot. So, the more meetings are fixed on one day, the higher is these number for this day.

Secondly, it adds the total meeting duration of days that belongs to a time-slot and divides the sum with every total meeting duration of a day of a time-slot, so that it get a number for every time slot, that is higher, the belonging day contains more meeting-time.

As I wanted the agent to pay more attention to the number of meetings than to their durations, the first part of this second number is worked in with the factor 2, and the number of the second part with the factor 1.

time slot
number of meetings of 
total meeting duration of
the belonging day
the belonging day
200 min
220 min.
290 min
120 min
170 min.
total: 1000

Without paying attention to the priority, which slot is the best one?
time slot
number x , that represents, how well it fits 
x=(2*(10/3*1000) + (1000/200*1000)) / 3 = 3889
x=(2*(10/1*1000) + (1000/220*1000)) / 3 = 8182
x=(2*(10/2*1000) + (1000/290*1000)) / 3 = 4483
x=(2*(10/3*1000) + (1000/120*1000)) / 3 = 3000
x=(2*(10/1*1000) + (1000/170*1000)) / 3 = 8627

number x is calculated as:

The final result r for this time slot now is the product of the average priority of this slot and x.

r= (meeting priority - average priority) * x

After finishing this calculation for every fitting time slot, the agent sends back a message, containing all time-slots, the host-agent sent, and additional the result r for every slot.

As soon as the host-agent received this message from every invitee, and also calculated its own results, it checks, which is finally the best time slot.

The calculation is simple. The agent adds up all sent numbers for every slot. The slot with the highest result finally is the best, and is sent back to all invitees, together with the instruction, to fix the date in this slot.

Now, every participate-agent adds its extra-time for this meeting again, and places it in its timetable.

5. Comparison of the two negotiation-strategies

Ątake first"


disadvantage: Ątake best"



6. Example

To show the differences of the two strategies, I chose the following example, which I tested once with Ątake first" and once with Ątake best":

The following meetings had been scheduled:
priority for agent
of the meeting
meeting A
meeting B
meeting C
meeting D
meeting E
meeting F
meeting G
meeting H

The resulting timetables of the agents looked more or less the same, so I chose AgentA, to show the different results.

Ątake first"-strategy

Figure 15 Ątake first"-strategy

As you can see, almost all meetings have been scheduled for one day. The only little gaps between two meetings result from lunch breaks of Agent B/C. As the user joins lots of meetings on his/her work days, this strategy is very good, because it uses the available time as well as possible. But, it only checks, if a time-slot is free and possible for all agents. It does not care about, if there are any later time-slots, that would have lower priorities, or that would fit better, because of the lower number of meetings of the belonging day. It just takes the first fitting slot.

On the other hand, if you donít have to join a lot of meetings, this result wouldnít satisfy you. In such cases, the Ątake best"-solution would be better.

Figure 16 Ątake best"-strategy

Now, the meetings are more spread over the table. Every agent could input more of its preferences, which led to a situation like shown above. The agent tries on the one hand, to find out the time-slot, that has the lowest priority for all invitees, and on the other hand not to pack a day full of meetings.

It also takes care, to fix a meeting on days as early as possible. This is realised in that way, that only the first 10 fitting slots are sent back to the invited agents, to let them choose their favourite slots. The result of this technique is, that even if you took a longer interval to place the meeting, the final timetable would have looked more or less the same.

VII. Handling

1. Identification

    If the agent is started the very first time on a system, it must be registered at the router. To ease it for the user, s/he only has to call the usual instruction to start the agent. It realises by itself, if this is its first start and, if yes, it opens a new window. There, the user has to input a name and a password for the agent, and also itís complete address and the port, to send/receive messages. After pressing the OK-button, the agent hides this window and tries to registrar itself. Also, the main frame is opened.

    Every time, the agent is started again, it connects automatically with the router, using its name and password, and the main frame is the first frame, that is opened.

2. Main Frame

Figure 17 main frame

In figure 17 you can see the main frame of the agent, in the typical situation, that some meetings are still fixed. These are painted in a colour, ranging from yellow (low priority) to red (high priority). E.g. above you can see, that meetingx with priority 5 is more light than meeting abc9, with priority 7.

The duration of a meeting defines, how big the box for a meeting is painted. This has the effect, that very short meetings get a very small box, where not all information of it can be printed. A meeting duration of 15 min, e.g. would lead to a box, with a height of only one table row. In such cases, only the name of the meeting can be shown. If the user wants the full information about a meeting, s/he can simply click the meeting (see. 3. Show/Cancel a meeting).

The other boxes, which colours range from white (low priority) to blue (high priority) show free times. Their priority means, that these slots cannot take up meetings with lower priorities than their owns. E.g. on Sunday from 12:15-13:15 oíclock, the time slot has the priority 9 (darker blue). So, it can only schedule meetings for this time interval, which has a priority of 9 (or above, but 9 is the highest possibility).

Also, you can see, that the user of this agent has set the Friday as a complete free day. This darkest available blue shows, that no meeting can be scheduled for this time-interval, no matter its priority. The other days are very different. On Sunday, you can see a lunch-break from 12:15-13:15 oíclock, and also a very long workday. On the other days the user wants to finish his/her work earlier, but therefore without any breaks in between (at least in the visible part of the table).

There are five days shown, every time. The very left one usually is the actual day. Every row of every day is click an selectable, to fix Ąprivate" meetings (see 6. fix a private meeting).

But this is only one part of the timetable, ranging from 12:00 oíclock to 20:45 oíclock. You can change the visible time by moving the slider on the very left. Every line of the time groin, next to the slider, represents a quarter of an hour.

The top of the main frame can be used, to scroll through the calendar. On the upper left side, the user can input a datum. After clicking return, the very left shown day will be set to the inputted datum and the others to the following days.

If the user wants to scroll day by day, or week by week, s/he can click the buttons in the top middle:


for moving one week forward/backwards, or


for moving one day forward/backwards

After scrolling, the calendar can be set back to the current day, by clicking the button on the top right.

The bottom part of the main frame also contains several buttons. Their functions are the following:

the user wants to schedule a new meeting. For the exact handling of this, see 5. Fix A Date Frame

to cancel a meeting. See 4. Find/Cancel a meeting

to search a still fixed meeting. The agent only searches from the current day on (meetings, that didnít take place, until that day). See 4. Find a Meeting.

almost same than above, but now, the agent searches for a meeting, that still took place (from the actual day into the past)

the time table will move to the next free day

opens a frame, that shows all messages, the agent sends or receives. This is only necessary for testing the agent.

opens a new frame, where the user can set his/her preferences. See 5. Preferences

Other features of this main frame:

The tables actually donít change their size, too. Only their visible parts change. The result of this is, that the rows of the table always have the same height, so that it is always possible, to read the information, printed in. So, after resizing the frame, you can see more/less hours of every day. 3. Show/Cancel a Meeting
    If the user clicked on a meeting in the timetable, a new frame is opened. It shows the clicked meeting with all its available data.

    None of the shown fields are editable, because a change of meeting data would change the data of all other participant agents, too. This may could lead to the need of a new scheduling.

    So, if the user really want to change some data (e.g. the duration of the meeting, s/he has to cancel and refix it.

    To cancel it, you can press the Ącancel the meeting" button. If this agent has been the host-agent, it will send a message to all invited agents, to cancel the meeting in their timetable, too. If the agent was an invitee, it sends the cancel-message to the host-agent, which decides, if the meeting should really be cancelled or not. This depends on, how important you are for this meeting.

    Figure 18 Show a meeting

    Anyway, your agent cancels it in its own timetable in any case.

    If you just wanted to see the information without changing them, you can click the OK-button, to return to the main frame.

4. Find/Cancel a meeting

After a find- or the cancel-button of the main frame is been pressed, the agent also opens a new frame. It looks almost the same than the one of 3.Show/Cancel a meeting. The differences are, that you have an additional Ąfind"-button on the bottom and that the textfield of the meeting name is editable.

At first, the user has to input the name of the meeting, s/he wants to find. After clicking Ąfind", the agents searches for it. If the Ąfind >"- or Ącancel"-button was pressed, to open this frame, it searches only in the future, if it was the Ąfind<"-button, it only searches in the past.

If there is no such meeting in the table, the agent deletes the inputted name and does a popup, to inform the user. In the other case, it shows the meeting with its complete data. Clicking the Ącancel the meeting" button works exactly like above.

The distinction between finding past meetings and future meetings is not done, to ease the work for the agent. To search a meeting between the very first day, the agent was online, and the last day, that contains a meeting, would be more or less the same algorithm. The idea to do that was, that a potential user could have two main reasons, to search for a meeting:

a) s/he forgot, when a certain meeting exactly takes place. Maybe the user wants to prepare for this meeting and needs the exactly time-interval. Or s/he has to contact some other participants (future meeting)
b) a user want to know, when s/he joint a meeting with a certain person, the last time (past meeting)
So, for the user, it is more comfortable to have such a difference in the searching methods.

To take the meeting name as a key for the search is only one possibility. You could improve this algorithm by the possibilities to take any other meeting-information as the key, too.

5. Preferences

Figure 19 Preferences

In this frame, you can set all adjustments. It is the most important interface between the user and the agent. The functions on the left side are as following:

The user has to think about, how many past month are important for his/her work. Of course, it depends on the user and the kind of his/her work, on which value this variable is set. The better strategy is Ątake best", so, in the end, it would be better, to delete this selection and work always with this one. But, during the test-phase, it is a nice feature, to see the differences between the strategies. On the right part of the frame, you can set the default for every weekday. On the top. you can select for every day, if it should be a free- or a workday by default.

The big component in the middle, called SetDayDefaults, can be used, to set the elementary parts (see VI.1.) of each day. The text fields on the left show the current time-interval of the belonging slot. It can be changed, by moving the slider on the right of it. The slider have a range from 0 to 1440 (0 h - 24 h) and give the user a very exactly control over the intervals. Of course, every time-interval has to be unique, which means that overlapping of two intervals is not allowed. Otherwise, it would lead to confusion for the agent, and the scheduling-process could not work perfectly. To avoid this, this component includes a mechanism that allows every time-interval x only to have a starting time equal or later than the ending time of time-interval x-1. If the user tries to move slider x to a later position than slider x-1, it will be corrected automatically. In the end, interval 1 starts at 0 h and ends at y1 h. Interval 2 starts at y1 h and ends at y2 h Ö the last interval ends at 24 h.

There are 9 sliders available, so the user can set up to 9 different intervals. As the last interval always ranges from the ending time of the second last to 24 h, its slider is actually unnecessary, but I didn't delete it, because of the better view. If the user wants less then the 9 available possibilities, s/he can simply set the starting and ending time of one or more intervals to the same values (usually you should use the first or the last intervals for such actions to avoid confusions).

On the right part, you can set the priorities for the intervals (which means, that this interval can only take meetings with an equal or higher priority).

Of course, if you want and effective meeting-scheduler, you have to set those intervals for every weekday. To do so, you can change the current processed day, by selecting one of the list on the top. As you can see there are also the two helping days "default working day" and "default free day", which will ease your work, if you have fixed working times that are almost the same, every weekday, or rather your free days will look all the same. In such cases the component to set the weekdays as free or workdays (see above) is very important. After setting the two helping days, you can simply select "set back to default working day" or "set back to default free day", to set these days to the same values than the belonging helping day. The button of each day automatically changes its text and its function, if you change the belonging day to free-/workday.

The SetDayDefaults-component is one of the most powerful tools of this agent, and the user should take care on the values s/he sets. As it is the most important interface to allow the user to input his/her preferences for every day, the agent will focus most of its attention to the values of this component, if it negotiates with other agents.

6. Fix a Ąprivate" meeting

    A "private" meeting means, that the user wants a free time on a special day between special hours (e.g. for a date with his/her doctor). Therefore you can simply scroll the timetable to the specific day (or rather input the datum) and then click in the table on the starting time of your wanted interval. By holding down the mouse button and drawing down, until you reached your wanted ending time, you can select your time. After releasing the button, a frame opens, where you can input the name of the meeting, a text and the priority. As it is private, you cannot select any other participants, but any special information can be placed in the text field.

    Also, you cannot change your time interval anymore in this frame. The reason for this is, the following: If you select your time in the timetable, you are not allowed to select any still fixed meetings. If you do, the agent will abort this process. Also, if you selected any time-slot (every slot is 15 min), but another meeting still take up e.g. 5 minutes of it, too, your private meeting will be shortened automatically. So, the agent guarantees, by controlling your selection, that your wanted meeting time is correct and fits into the timetable. This means, that a once selected interval cannot be changed anymore. The only thing you can do is, to abort the process and select a new interval.

    If you want to fix a private meeting instead of a still fixed meeting, you first have to cancel this one.

    Also, you have to take care with the priority. As it is a private meeting, you can place it everywhere you want, except on still fixed meetings. The agent will not pay attention, if the priority is higher or at least equal the priority of the selected elementary-part. It simply fixes the meeting. This makes sense, because you know where you place the meeting, and so, you don't need anybody, who takes care of the priorities.

    But don't forget, that meetings with lower priorities can be cancelled, to schedule others with higher priorities. In such cases, the agent does not distinguish between a private and a "usual" meeting. The reason for this is, that you can set a high priority for your private meeting if it is important, or a low one, if not. So, you can set on your own, how important a meeting is, no matter if private or not.

7. Fix A Date-frame

Figure 20 Fix a Date - frame

The FixADate-frame is opened every time you want to schedule a meeting. Here, you have to do all necessary inputs for your agent (which will be the host-agent in such cases).

These values are private. They are not sent to the invited agent, but your agent needs them, to schedule the meeting on the right place. If you don't input anything, the extra time is 0. If you only input the first day, the last day will be the sum of the first one and the default interval, set in the preferences.

If you only input the last day, the first day will automatically be set to the current day + 1 (+ 1, because meetings should not be fixed on the current day, to avoid, that the user doesn't see a new meeting right in time.

Feel free in the way to input the datum. The following methods are allowed

But you should really take care, to give a meeting a priority as high as its importance. As this agent is priority oriented, before scheduling a meeting, you should equate it with a priority (ranging from 1-9). If the priority is higher than the importance of the meeting, it will devalue other high priorities, and maybe, if will take the place in your timetable, that may is needed later to fix really important meetings.

If it is to low, on the other hand, you decrease the chance, that there are free fitting slots for that meeting in your timetable. And even if there are some, the meeting can be cancelled automatically by the agent, if a meeting with a higher priority has to be fixed, and there are no other time-slots left.

The priority, you set, has no effect on any other invited agent, but only on the one of your own.

8. Directory

If you want to schedule a meeting, you can select the participants in your directory. It can be opened by clicking the "Select Participants"-button of the FixADate-frame. If you do so, the following frame will be opened:

Figure 21Directory

If you want to add a new participant to the current list, you can simply select it, by pressing in the very left field of the belonging row. The second column ("indispensable") can be clicked, if this person is very important for your meeting. Your agent will now pay more attention to the proposed time slots of the agents of those persons. If it cannot find any slot, that satisfies any agent, it erases as long "unimportant" agents, until a fitting slot for the rest is found. So, in the end, a meeting can only be fixed, if all "indispensable" agents agree with a fitting slot.

If you want to add new names to your directory, you can do this only with agents, that are registered at the router. To get a list of those, you first have to press the "select from router"button. Your agent then asks the router to send a list, and, after receiving it, it will be shown in a new frame.

Figure 22 select from router

Here you can see all currently registered agent names. By selecting them, you can add them to your directory. Of course, at first you can see only the agent name. All other values, you have to add by your own:

If you want to delete a name again, you can simply do so by clicking on the delete-field of the belonging row.

VIII. Improvement proposals

  1. Incomlete Implementation: Because of the missing time, I could not implement every function, I planed. The most important is, that if a meeting cannot be scheduled, because of the non-existance of fitting slots, usually the agents have to negotiate, which one has the most "unimportant" meeeting (in relation to the importance of the current one) that could be canceled, to fix the new and more important meeting. Instead of this, the scheduling process aborts and the user of the host-agent gets a message, that the meeting cannot be scheduled.

  2. Of course, now the user can try to use a higher priority or a different scheduling-interval, to schedule again, but this isn't a very well way, because of the agent's autonomy, that it should keep.

  3. The user interface isn't as user friendly as it could be. More tool tips would be fine. Also, the directory has to be available not only in the FixADate-frame, but also on the main frame.

  5. The negotiation-procedure could be more agent-specific. At the moment, every agent only send its best slots, and the host-agent seeks out the best ones. Of course, the invited agents can choose their preferred slots, after that, but the negotiation, until a fitting slot is found could be improved.

  6. This could e.g. be in that way, that every agent sends only one time-slot at first, and the host agent picks out that slots, that would fit for two or more invitees. It could send these slots back to that agents, that sent slots didn't fit, and ask them for for their free slots in that section.

    Anyways, I think, that this agent system is fair at least. Also the negotiation-strategy has success in the end, but what misses, are some of the typical agent actions (like negotiation), for which I didn't pay attention at first.

  7. If would have been better, to summarize some more parts of the code in classes. E.g. There is no "real" calendar-call, which does all calendar-calculations. The reason of this is, that the GregorianCalendar-class of Java is very powerful, and at the beginning, I didn't beliefe, in the need of an own class. But now, in the end, some classes do the same calculations, like calculating the current weekday (which is different from the GregorianCalendar). Tasks like this could have been implemented in an own class.

  9. During some tests, I changed the numer of best-time-slots, that an invited agent sends back to the host-agent. At last, I set it to 10. But as I only tested with 2, 3, or 4 different agents in the system, this value will not be optimal, if the number of agents increase. To find out the best solutions, more test-activities are required



  1. First European Agentsystem

  2. Summer School, July 26-30,1999
    University of Utrecht, The Netherlands
    Edited by Gerhard Weiss, Wiebe von der Hoek, Michael Wooldridge
  3. Intelligente Agenten,

  5. Borghoff U., Schlichter J.: Rechnergestützte Gruppenarbeit (Springer)

  7. Intelligent Distributed Scheduling

  9. Technologie und Anwendung Intelligenter Agenten als Mittler in Elektronischen Märkten Diplomarbeit in der Fachgruppe Informationswissenschaft Fakultät Verwaltungswissenschaft an der Universität Konstanz

  11. JAFMAS, JATLite, JAT: Java Agent Frameworks

  12. Hannes Schmidt, Michael Kaufmann, Olaf Karatschai
  13. UMBC KQML Web



1. Agent Activities

2. Agent Host

3. Set-up of a JATLite agent system

4. the JATLite layers

5. KQML-Performatives

6. KQML-message of a PossibleTimeList

7. Timetable

8. Elementary parts

9. Fitting slots of one day

10. Substracting already fixed meetings

11. Corresponding slots of all participants of one day

12. Differences between meeting duration and duration of a time-slot

13. Elementary parts of the corresponding slots

14. Priority of every time interval the meeting would include

15. "take first" strategy

16. "take best" strategy

17. Mainframe

18. Show a meeting

19. Preferences

20. Fix a Date

21. Directory

22. Select from Router