Routing Optimization with GraphHopper

This powerful new feature was introduced in March of 2020.

Prior to then, ServiceDesk offered routing-sequence optimization only, and even that was only via MapPoint and/or Google, and was a poor animal compared what's now offered.

In a nutshell, routing-sequence optimization is a relatively small issue. It arises when you've already decided which jobs a tech will be assigned on any day (typically tomorrow), and you simply need an outside geographic engine to determine the sequence that will minimize his driving time.  

There is a far more grandiose issue.  We call it Whole-Roster optimization.  This is where you want an outside AI engine to do the whole thing.  Specifically, you want it to look at your whole roster of appointments for a given day, along with your roster of available techs. You want it to look at the locations where each tech begins driving and ends driving. You want it to look at the skill sets of each tech, and compare to the skill requirements on each job. You want it to account for where one or more appointments must have a particular tech, versus those that can be freely assigned to any tech whose skills are sufficient for the job. You want it to account for where some appointments already have times or time-frames assigned, and where others do not. You want it to account for all this as a great and grand problem. Then, using super-powerful artificial intelligence, you want it to work out an optimum solution in regard to which techs do which jobs and in what sequence.

Prior to GraphHopper, we'd not come even close to connecting with an automated "engine" by which to solve this grand problem.  Neither MapPoint, Google nor Bing offer such ability.  Even in regard to the relatively small issue of mere routing-sequence optimization (and for a single tech's already-assigned route), those tools have been very limited:

  • MapPoint is a program you must buy and install; it's not been produced by Microsoft since many years ago, and is now very outdated.
  • Neither MapPoint nor Google can account for where one or more of your appointments already have a committed time or time-frame (which means their optimizations are only useful if the whole set of appointments begin as setup for all-day).
  • Neither takes as part of the problem-to-be solved an indication of when the tech will begin his route or amount of time expected on each job. Thus, neither calculates probable ETA for each stop.
  • Neither accounts for an independent lunch break.

Our purpose with GraphHopper is to: (a) provide a more powerful routing-sequence optimization that overcomes the above limitations; and (b) introduce that super-powerful Whole-Roster optimization that's been a dream for so many years.

Happily, these are all things that GraphHopper is uniquely able to do. This is your guide on how to implement.

Geocoding Every Job Address in ServiceDesk

While GraphHopper does a million times more (at least in regard to our subject of interest) than MapPoint or Google, it is also a bit more technical when it comes to "behind-the-curtain" machinations. One aspect of this is, while MapPoint and Google allow ServiceDesk to simply submit a series of addresses (e.g., "123 Main St, Anywhere, CA"), GraphHopper demands actual latitude and longitude info instead (hereinafter referred to as lat/lon).

So, how does ServiceDesk get this lat/lon info? 

This is now an added benefit of the address-verification system, described here.

As of SD Ver. 4.8.148 and forward, each instance of successful address verification will cause insertion into the applicable Callsheet or JobRecord's MoreInfo box of a little notation containing the applicable lat/lon info:

Precise lat/lon info is part of what comes back from Google in consequence of each successful address verification request. It's what has been in use to create or improve grid references to the DispatchMap, but, prior to now, we've been making no further use of that data.

From there, it's easily available for ServiceDesk to use when it assembles data for submission to GraphHopper. This does happen to mean, of course, that if you're going to use the GraphHopper optimization you must assure every one of your customer addresses are in each instance verified (it means, in particular, you ought to have automatic verification turned on). Of course, you'll also need to have been doing this for some period in advance of using the GraphHopper automation -- so as to assure that the appointments that GraphHopper is seeking to optimize already have lat/lon info available.

Don't worry about breaking anything if you happen to have an occasional job that's not been geocoded. Where you've have asked for the optimization and ServiceDesk encounters one or more in such a circumstance, it will react gracefully, informing you of the issue, offer an option to proceed with the balance, etc.

Geocoding Technician EndPoints

What are "endpoints?"

Simply, for this context they are: (1) the location from which your tech begins his drive each day; and (2) the location at which he ends his drive.

For many techs, those two locations are one and the same. Often they are the technician's home. Occasionally, one or both endpoints may instead be the company office. Whatever is the case, there is a beginning endpoint and an ending endpoint for each tech.

We've long had facility for you to specify each technician's endpoints. It's in the Technician Properties window as applicable to each tech, which appears when you click on a tech's name within the Tech-Roster section of the Settings form (Ctrl-F1). There are boxes there in which to place the technician's address, and radio buttons whereby you may indicate whether the beginning endpoint is his home or office, and whether the ending point is his home or office.

But again, whereas MapPoint and Google have accepted straight addresses when incorporating these endpoints into an optimization request, GraphHopper requires lat/lon info. For this reason, you must insert lat/lon info for each tech's home address along with lat/lon info for your office (at least assuming that you specify either as an endpoint for particular techs).

This is very easy.

First, in the Technician Properties window there are now boxes for insertion of the lat/lon that fits the tech's home address. Simply assure you first have the tech's address in place, then click on the label as instructed. Insertion of the address-corresponding lat/lon will be done for you (SD obtains this by making that same call to Google's Address Verification):

Incidentally, the underlying insertion process will also calculate the grid reference that fits with the lat/lon, and insert or correct that reference in the Technician Properties box that exists for that purpose.

Second, in the main part of the Settings form there is now a place for the lat/lon that pertains to the office address you've provided. Similar to above, simply click on the label, and the insertion will occur for you.

Building Your Tech-Info File

As background, ServiceDesk has long had mechanisms by which to "know" each of the things it must know about each technician for the sake of simple routing-sequence optimization.

As above-described, for example, in each tech's Technician Properties window there's a place to provide his address, and another to indicate whether it's the office or his home where he begins and ends his route each day:

For the more ambitious GraphHopper optimization, ServiceDesk needs to know much more. For this purpose, we could have created a very-much-expanded Technician Properties window (i.e., like the one above, but with many more places in which you'd fill-in added elements of information). However, because so many more details are needed, and because it would be a disproportionate investment for us to create a GUI that's dedicated to your management of those many added details, we've taken a shortcut.

The shortcut, specifically, is you put these added details into a simple file. As changes, additions and/or deletions are needed, you manage it all yourself via that file. ServiceDesk simply reads from the file when needing to know the particular details involved.

Though you could potentially do otherwise, we recommend you use Excel or similar to manage this file. A needed template in .xls format (and with one example "record" therein) is provided here.

Using the provided format, you'll simply make a record (or row) for each technician (of course you should delete or replace the example row in the provided template because it obviously does not describe any of your techs). The headers at top are quite explanatory, but we'll nevertheless show an illustration here and provide some further description:

The green section has four fields that involve information ServiceDesk must have in order to do routing-sequence optimization for jobs that you've already assigned to a particular tech (henceforth we'll call this "Stage-1" of GraphHopper optimization).

The pink section has two fields that involve information ServiceDesk must have in order to intelligently insert time-frames after a routing-sequence optimization completes.

We emphasize the word "intelligently" because this is far more sophisticated than the "auto-time-frame-estimator" feature ServiceDesk has long possessed. For one thing, there's no need for a pre-inquiry to obtain general parameters for the insertion -- because in this context that info is already provided via fields in this file. Far more significant is the fact that in this context the system is informed by actual and direct calculations of most probable ETAs for each location (which takes into account driving times between each, and all other relevant stuff). Thus, the insertions should be far more precise and helpful, as compared to older mechanisms.

The blue section contains five fields that are needed for what we'll henceforth call "Stage-2" of GraphHopper optimization, which is where GraphHopper optimizes your whole roster of appointments across your whole roster of techs. Additionally, some of the fields in this section can, where applicable, supersede more general settings in the green section.

As an example, suppose that in the green-section's Column B you've set 7:30 am as the time a tech normally begins his route. However, you happen to be routing him for work on a Saturday, and Column I in the blue section indicates that, on a Saturday, his more specific-to-that-day start time is 9:00 am. In this case, ServiceDesk will see that more specific start time, and that's what it will submit to the GraphHopper optimization engine.

Column L is where, if you're using special-skills (see here) you'll specify what are the special skills that each tech/any possesses. Basically, just list the single-digit identifier, for each such skill, separating each by a comma (or of there is just once such skill list its single digit only). If any tech has just your standard/default skills (and none that fit what you've defined in your SpecialSkills list), you should sensibly leave this box blank for that tech. Likewise, if you're not even using the special skills feature, please leave this column blank for all techs.  

Again, we recommend that you use Excel or similar for your active management of this file. Also, in each instance of editing or updating your file, please be sure to save in the format of the particular spreadsheet program you are using. This will preserve the formatting that makes review and editing easy.

Regardless, it's not the format that ServiceDesk will be using when seeking this information.

Specifically, ServiceDesk will be looking for the information in a comma-delimited file located in your \sd\netdata folder and with filename TechnicianExtraSpecs.csv.

Thus, while you'll want to do your active management of this information with the data opened in a spreadsheet program (Excel or similar), and with the special spreadsheet-program formatting that makes things clear and easy, you must as you complete your work do two things: (1) save for later use your work in the format of the spreadsheet you are using (e.g., .xls or .xlsx); and (2) save in comma-delimited format as TechnicianExtraSpecs.csv in the needed \sd\netdata location (if you do not do the latter, ServiceDesk will not have your latest work).

Do be sure, BTW, that the next time you open for editing, it's the spreadsheet-formatted version you open first. If you instead open from the .csv format instance of the file, you'll find things look much less pretty.

The reason we've picked this strategy is because these days people are using a lot of different spreadsheet programs. Back in the day, we could pretty much count on people using Excel, and we'd have simply coded SD to read directly from a user-managed Excel file. It's not so practical today. So, the solution is each of you can use whatever spreadsheet program you want, and just save separately to the common .csv format that can be produced via any such program.

A Twist on Departure Times and Subsequent ETAs

The above-described TechnicianExtraSpecs.csv file is designed, among other things, to let you specify the time each tech departs each day for his first job. By calculating driving time, GraphHopper can predict a rather precise ETA for each first job. But suppose, instead of having a fixed time for each tech's beginning departure, you instead want to have a fixed time for each tech's arrival at his first job.

To do that, you'll simply add another column to the above-described file. Put explanatory text in the header, and in each row/sub-row that corresponds with each tech, put in either "True" or "False" as is your preference for whether this "twist" controls or not:

When you've added the column and indicated "True" for any particular weekday and technician, ServiceDesk will see that value. After getting the normal optmization from Graphhopper, it will adjust the tech's departure and all ETAs by how ever many minutes are needed so as to make first arrival equal Column B.

Using Stage-1: the Routing-Sequence Optimizer

Again, a great benefit in this optimizer (in particular, over MapPoint and Google) is it can intelligently account for one or more of a tech's jobs already having a time or time-frame assigned. Likewise, it can account for the tech's lunch break, for the time expected at each stop, and provide back excellent predictions about the probable real course of the tech's day.

Regardless (assuming you've first done the above-described elements of setup), your own use is as simple as with using our longstanding (MapPoint and Google) routing-sequence optimizers (actually, it's more simple, but we'll get to that).

Just as with the longstanding optimizers, assign into a tech's list the particular set of jobs that you believe it is optimum for him to do. Then, do a Shift/Ctrl-Click on his name at the top of his list (alternatively, you may simply click on his name then pick the the option for "Quicklink to external mapping resources"). Either way, this options box appears, and you'll of course pick the new option that's indicated here:

The system will then do its work. Like magic, the route sequence will optimize according to all provided parameters, and ServiceDesk will give you a report. Please note in the report:

Please further note this element:

What that sentence means is your Windows clipboard now holds detailed information about the route, and if you simply paste (Ctrl-V or right-click and pick paste from the popup) into any text editor (e.g., NotePad, WordPad, etc.), you'll see something like this:

Please also notice that you may choose from the same dialog to directly open the optimized route in Google or Bing:

Much more importantly, you may choose to have ServiceDesk insert "intelligently-proposed" time-frames for you:

This is where the GraphHopper-based routing-sequence optimization is particularly more easy, as compared to MapPoint or Google.

And it's more effective to boot.

It's more easy because the offer to insert time-frames does not require separate action on your part. It's instead completely integrated into the sequence.

It's more effective because this insertion of time-frames uses all the more specific data. It can even insert a smaller time-frame (or even a single discrete time, if you've so specified, please see my example in the provided TechnicianExtraSpecs.xlsx file). It's also more intelligent because, if specifications permit, it will replace a larger, prior-provided time-frame with a smaller time-frame when circumstances allow. Thus, the list section for the tech of interest may go instantly from looking like this:

To looking instead like this:

There will of course be a dialog that asks if you wish to save with the proposed insertions.

It's powerful.

Embracing Stage-2: Whole-Roster-Optimization

As of late July 2020 (SD Ver. 4.8.172), we have achieved at least the currently-envisioned full-scope of this feature.

Earlier we'd rolled it out with one significant element remaining to be built: use of special skills. That very large element has now been added.

To briefly review, the basic concept is ServiceDesk takes the whole set of appointments you have setup for a particular day of interest, and the whole set of technicians that are available for that date. Employing all information that is relevant (e.g., some jobs already have a time or time-frame, some are "definitely" assigned to particular techs, some require particular skills that only some techs possess, each tech has unique beginning and ending locations, each has a particular portion of the day that he'll be working and a particular capacity, etc.) -- employing all of that, it presents the "problem" to GraphHopper for its resolution. Then the latter, using its super-sophisticated system of artificial intelligence ("AI"), churns through the data so as find an optimum solution in regard to which techs should do which jobs and in what sequence. It spits that solution back to ServiceDesk, which then arranges your appointments accordingly.

As you can see, it's big.

Regardless, implementation is not difficult.

  • Be sure you've setup so that your jobs are all being geocoded (as described here).
  • Be sure you've setup geocoding for each of your techs (as described here).
  • Be sure you've appropriately setup for each tech in your TechnicianExtraSpecs file (as described here).
  • For now (and assuming you are proceeding presently because you do not have requirement for this), don't worry about implementing any matching of skill sets between techs and jobs (again, we expect to provide facility for this a little bit later).
  • Display the date in your DispatchMap that you you wish to have whole-roster-optimized.
  • Hit "Alt-O" on your keyboard (the "O" is for "Optimize"), and follow the prompts (alternatively, you can pick "Invoke Whole-Roster Optimization via GraphHopper" from the menu/cheat-sheet).

In consequence of the above, you'll see the magic occur. After it's done, you'll immediately see the result in your DispatchMap, and you'll get a report that looks something like this:

If you accept the option to insert time-frames, the system will of course do so. More specifically, it will first show you the proposed insertions, and with dialog such as this:

If you consent to save, the system will of course do so.

Thus, with very little effort and time, you can achieve a very, very optimum tech-distribution and sequential arrangement of your appointments, along with very intelligent insertion of times or time-frames.

In particular, you may almost instantly transform from a dispatch/assignment layout that looks as confused and unhappy as this:

To one that instead looks rather more like this:

Some things you should understand:

Regarding which techs the system will reckon as available for the optimization process:

  • A technician must be appropriately geocoded.
  • A technician must be listed in your TechnicianExtraSpecs file.
  • If in Column H of the TechnicianExtraSpecs file you've listed particular days of the week that a tech works, the weekday that's applicable must be among the days so listed.
  • A technician must not have an "Unvlbl" entry in the ServiceDesk ScheduleList that effectively forecloses him from work on the day in question (an entry there merely forecloses him for a portion of the day is fine).
  • A dialog will inform as to any techs otherwise in your roster that are foreclosed from inclusion, for any of the above reasons.

Regarding when the tech may begin his work:

  • A tech's default start time is whatever such time as you have listed for him in Column B of the TechnicianExtraSpecs file.
  • If you have a specific-to-weekday start listed in Column I of the same file, and if the day that you're optimizing corresponds with that weekday, that start time will supersede what's found in Column B.
  • If there is an applicable-to-date "Unvlbl Until" entry in the ServiceDesk ScheduleList, that entry will supersede over both the above.

Regarding when a tech must finish his work:

  • A tech's default must-end time is calculated as whatever ends up (per above) as his start time, extended forward in time by whatever is his max-JobCount value (indicated in his Technician-Properties window of the ServiceDesk Settings form) times his average-minutes-per-JobCount as indicated in his Column C of the TechnicianExtraSpecs file.
  • The above will be superseded if for the applicable tech there is in his Column J of the TechnicianExtraSpecs file an entry that indicates a particular quantity of hours that the tech may work on the particular weekday in question.
  • Both of the above are superseded if there is an applicable-to-date "Unvlbl After" entry in the ServiceDesk ScheduleList (in which case, naturally, the tech is deemed as available to work up to such time as is indicated in that entry, and not longer).

Regarding which appointments are deemed suitable for inclusion in an optimization request:

  • The JobRecord that underlies any such appointment must be geocoded.
  • The appointment must be "real" (i.e., it cannot be either a pseudo or fake appointment).
  • It must not be a "Hlpng" type appointment that: (a) is not in "Definite"-assigned status to a working-that-day tech; and (b) does not specify a time or time-frame that is as small or smaller than the scheduling time-frame specified for the assigned tech (if otherwise, it's possible the GraphHopper engine would specify a sequencing and time-frame that is not a fit for the primary tech). Please note, if you do this, you should assure the primary tech is also "Definite"-assigned and with a time-frame that matches that of the "Hlpng"tech).
  • A dialog will inform of any "real" appointments where, per above, inclusion in the optimization request was not feasible.

Though these details may seem a trifle complex, we've worked hard to make it all happen for you logically in the background, and generally without much need for you to worry over the details. We simply need to share them with you, so that you'll understand should the need arise.

Try it.

You'll see.

It's, it's . . . well . . . it looks like magic when you see it happen!

At least we hope so.

Regardless, we provide a caveat.

If you constrain what GraphHopper can do by having a lot of jobs that are already "definite-status" assigned to particular techs; if you further constrain it by having a lot of jobs that already have a time or time-frame assigned. . . well . . . those things necessarily limit just how elegant it is that GraphHopper can otherwise make the optimization. Ultimately, it must work within the constraints you give it. If you can, give it a whirl with a whole roster that's unconstrained, and see how beautiful that looks. Regardless, if you see sequences and assignments that look less than optimum, we suggest you try your abilities by comparison. We doubt very much if you'll be able to do as well.

As a final note in this regard, when you're looking in ServiceDesk's very flat and relatively featureless DispatchMap, you do not have the same awareness of road routes that are available for actual travel by your technicians. You're basically just looking at straight lines for the routes, while GraphHopper is considering actual road paths on which each tech may drive. Because of this, a routing setup that on its face looks to you less than perfect may actually be very good. As a test if you're doubting, we suggest you do your own best eyeball optimization, then open applicable routes in Bing or Google to see distance and driving times. Then let GraphHopper do the work, and see if it does not in fact do better.

Incorporating Special-Skill Requirements

If each of your techs are qualified to do any of your jobs, there's no need to worry about either this section or its topic. Just skip over the matter.

If, on other hand, you have some jobs that only some techs are qualified to perform, this is a section you'll very much want to read and implement.

For context, when humans are deciding which jobs to have which techs do, it's likely those humans have an understanding of each tech's capabilities, along with some ability to judge what each job needs.

Where, by contrast, we're asking GraphHopper's AI to do to the work, GraphHopper has no such understanding -- unless, of course, that understanding is explicitly provided to it. That's what "Incorporating Special-Skill Requirements" is all about.

. . .

So, with that introduction handled, let's describe how it's done.

STEP 1: CREATE YOUR "SpecialSkillsList" FILE

As with creation of your TechnicianExtraSpecs file (see here), we suggest you use Excel or similar to create this, then save the functional output in the needed .csv format.

The spreadsheet you must make will consist of a simple two-column list that defines whatever are the various particular skill types that you want to employ in your setup. The first column is simply a single-digit numeric identifier for the skill type that's listed to its right, in Column B. In other words, your setup should something like this (albeit with whatever you want your own skill types to be):

You may define up to nine different skill types, and we want to provide a little suggestion in regard to what you choose.

Please consider it's likely to be easiest if you stick with only listing specialized skills, and do not define anything that equates to a default or standard skill set. This way, any job that does not require more than standard skills will not need to have a specification of skill requirements, and no techs will need to be designated as having that default standard. In other words, you can assume that all jobs need the default standard and all techs possess it, so there is need to make a definition of that.

The file must be saved in comma-delimited format and in your operative \sd\netdata folder (i.e., just like the TechnicianExtraSpec file). This one must be saved under the filename SpecialSkillsList.csv.

STEP 2: IN YOUR "TechnicianExtraSpecs" FILE, INDICATE WHICH OF THE LISTED SKILLS EACH OF YOUR TECHS POSSESS

Please see here for instruction on how setup is done in that file.

STEP 3: WITHIN ServiceDesk, INITIATE THE PRACTICE OF SPECIFYING REQUIRED SPECIAL SKILLS ON ANY APPLICABLE APPOINTMENT

The first version of ServiceDesk that is equipped to do as described here is 4.8.172 (thus, you'll need to be in that version or newer to implement as here described).

Several elements are introduced in this release:

First, the F6 ScheduleList interface has a new column wherein required skills for any appointment can be indicated

Second, there is a new option, in regard to AttentionNote types, that may be created from the F7 Current-JobRecords interface. Basically, when you exercise the standard option there to insert a specialized AttentionNote type (i.e., right-click on the "add AttnNote" button), there's a new option:

In particular, this type will work in a manner similar to those which indicate that a next appointment needs to have a particular above-1 JobCount, and similar to those that indicate a next appointment needs a second-man helper. Somewhat differently for this type, however, rather merely being able to indicate that a next appointment needs a particular kind of treatment, this new option allows you designate, in the alternative, that any appointment as made for the job will need such special treatment:

Much as with the other specialized-AttentionNote types, when an appointment is created from a JobRecord with this new type, the system will automatically populate that appointment's required skills as specified, plus will delete the note if appropriate, etc.

Third, there is now a new box in the Create-Job/Sale interface. You can click on it, during the Job-Creation process, to indicate either that the simultaneously-created appointment in particular needs special skills, or that any appointment that's made on the job needs such skills:

Where you're creating a job and know that any such skill requirement exists, just click in the box, then indicate accordingly.

Based on your indication of skills required on each appointment, along with your indication of which tech possess which skills, ServiceDesk provides that information to GraphHopper as part of its optimization request. GraphHopper then knows it can only assign jobs that have particular skill requirements to tech that possess those skills -- and of course it behaves accordingly.

Two Special Cases

1. Coping with Non-Standard Begin- and/or End-Nodes

There is, of course, provision directly within ServiceDesk where you may specify, for each tech, whether his/her begin-route location and/or end-route locations are at his/her home or at your main office (see here).

But what if, for one or more techs, you need to have either their begin and/or end nodes reckoned as at some other location?

Perhaps, for example, there are several techs that you expect to have checking in, each morning as they begin their work, at a remote parts depot.

The solution is to make use of two more optional columns in your TechnicianExtraSpecs file.

For context, we already contemplate potential use of a "first extra column" for the purpose described here.

For this purpose, you simply add two more extra columns, as illustrated here in yellow:

Please note that the heading you put at top of such columns is not relevant in regard to their function (it's solely to remind you what it is that you're placing there). What matters is that these columns are at positions N and O in the spreadsheet.

As for content in any cell where you want to specify a special, non-standard begin- and/or end-node, please put in the latitude and longitude separated by a comma (see above). You may, additionally if wanted, follow with bracketed text that provides a description of the location (again, please see above).

It's that simple.

2. Coping with Already-Set-Time, First-of-the-Day Appointments

This topic is relevant if you make some appointments for a discrete assigned time (e.g., 8:30 am), as opposed to a time-frame, and if you're doing so with intent that such an appointment is intended for a technician’s first stop of the day (this is of course the one stop in which it's relatively practical to provide your customer with the convenience and courtesy of a discrete assigned time).  

Hereinafter, we’ll call any such appointment an “ASTFA” (for Already-Set-Time, First-Appointment).  

Please note, where you are doing mere routing-sequence optimizations, ASTFAs are not an issue. It’s because there we are only asking for optimization regarding such jobs as are already assigned to a tech.  There is thus is no question about who does which job, so the problem of coping with ASTFAs is relatively simple.

Where, by contrast, it’s whole-roster-optimization that we are seeking, the problem becomes more complex.  

One reason: Even if you are not using the "Treat-Tech's-Nominal-Departure-Time-As-First-Job-Arrival-Time-Instead" option (see here), it’s possible you will not have any techs who are scheduled to begin their routes early enough to reach one or more ASTFAs by their scheduled time. If this occurs, any such ASTFAs will not be included by GraphHopper in its optimization solution.  

Perhaps even worse, it’s possible you’ll have a tech who is set with an initial departure time that is early enough, with driving time added, to make it to a particular ASTFA by its scheduled time, yet he is not one who should preferentially go there, because he actually lives far away. This could happen, for example, if that tech's designated departure time is very early, and techs who are more near to the ASTFA have relatively late starting times. If this indeed occurred, GraphHopper would unhappily end up sending that very remote (but early-starting) tech to the job in question, and it would not be good for your efficiency overall.   

Making it even worse, because GraphHopper would have already routed that early-starting (albeit more remote) tech to this particular ASTFA, it would likely then find it efficient to assign the same tech other appointments that are nearby, in spite of the fact they're far from the technician's home.  

The problem becomes even more apparently intractable if you are in fact using the "Treat-Tech's-Nominal-Departure-Time-As-First-Job-Arrival-Time-Instead" option.  In this case, after all, you will have set each tech’s apparent/fictional departure time as the same time that you have one or more ASTFAs already scheduled.  Thus, unless calculated driving time between the departure point and that ASTFA is zero (and unless other adjustments were made), it would be impossible for GraphHopper to calculate it as possible for the intended tech to reach his ASTFA by its scheduled time (hence, and, again, any such ASTFA would not be included in the optimization).  

So, that’s a brief description of the problem.  What is the solution?  

Fortunately, from a user perspective, the solution is much more simple than understanding the problem.

You must simply assure you “Definite”-assign each ASTFA to the particular technician whom you consider optimum for handling it.  

Please note: for any discrete-time appointment that is “Definite”-assigned to a working-that-day tech, ServiceDesk will look to see if the discrete time is within 90 minutes of the tech’s indicated begin-driving time.  If yes, ServiceDesk will treat that appointment as an ASTFA.

That’s all you must do.

Behind the scenes, ServiceDesk will do a little extra trick when it sees this circumstance. Specifically, it will make a separate inquiry, before submitting its main optimization request to GraphHopper. Simply, for each“Definite”-assigned ASTFA, it will request the driving time from the applicable tech’s departing location (likely his home) to the ASTFA address. Based on this, it will in its optimization request to GraphHopper indicate a starting time for the tech that is early enough to make it to the ASTFA on time, but not so early as to invite GraphHopper to potentially stick another job ahead of the ASTFA.

Specifically, it will calculate backward, from the appointment time, by the calculated driving time, plus 5 minutes. Thus, if you had a discrete and “Definite”-assigned appointment of 8:00 am, and if the calculated driving time from the assigned-tech’s departing location to that appointment was 23 minutes, ServiceDesk would submit to GraphHopper a begin-driving time for the tech of 7:32 am.

Like many good solutions, this one may seem in retrospect to be relatively simple and obvious. However (and also like many good solutions), it was anything but obvious in the first place.

As one more matter, please note that each and any “Hlpng”-type appointment must be “Definite”-assigned to a tech that’s otherwise included in SD’s roster-optimization for the day, and must be indicated for either a discrete time or a time-frame that is as small or smaller than the applicable tech’s planned/default time-frame size. Otherwise,a “Hlpng”-type appointment will not be included in the optimization request.  

Options to Set Priority Basis And Whether Tech/Zone Associations Control

Depending on your situation, there are a couple of things you might want to have GraphHopper handle differently, as compared to default.

As the first such item, by default, ServiceDesk configures its request to GraphHopper in a mode that asks, essentially: "Please provide the optimum technician assignments and sequencing wherein each of the available techs share with reasonable equality among such jobs as need to be assigned."

It's possible you'd instead prefer to absolutely minimize how much you're paying techs to drive around, even if it results (for any particular day) in some techs having few jobs and some having many.

If in fact that's your preference, you can say so in the Ctrl-F1 Settings form, as shown here:

Just pick "Absolute" instead of "Balanced." With that as your setting, instead of asking GraphHopper to keep jobs reasonably balanced between available technicians, ServiceDesk will instead essentially say: "Give me the optimization that results in least-possible windshield time, even if some techs are loaded to the max and some end up with few or no jobs."

As the second such item, it's possible you are using a WhchTechToWhchZone file (see here) to indicate which techs you want to have working in which zones. If yes, it's also possible you'd like to have GraphHopper honor those tech-to-zone associations. If yes again, here is the setting for you:

Just change from the default of "No" to "Yes" instead, and that's the result you'll get.

What Does it Cost?

In spite of having so much greater power, we are happily able to provide Stage-1 GraphHopper-based routing-sequence optimizations at the same price as Google's: just 1.5 cents per optimization.

For Stage-2 whole-roster optimizations, we've presently re-thought what we believe is ideal for a charge structure.

By way of background, GraphHopper prices its service to us based on a "credits" system. Each request consumes a quantity of credits based on the number of drivers multiplied by the total quantity of locations. Locations consist of each of your appointment sites, plus each techs' beginning and ending locations. So (and as an example), if you have 8 techs and 64 jobs, there would be 80 locations (64 for the jobs plus 16 for each tech's start and end points). By multiplying 80 times the 8 techs, it's evident an optimization request will will require 640 credits.

What we found is if we had a fixed price per credit (initially we'd contemplated making the price $0.001 per credit), the resulting fee would be disproportionately too large for bigger operations. This is because the quantity of needed credits rise exponentially with quantity of techs and jobs. Compared to the above described scenario, for example (where an optimization request with 8 techs and 64 jobs needs 640 credits), a request with 32 techs and 256 jobs needs 10,240 credits. If credits were priced at a fixed amount, the operation with four times as many techs would pay pay 16 times more for its needed optimization. Besides the fact that's too disproportionate, it's also true we get volume discounting from GraphHopper, so it makes sense that the larger operations which bring us into the volume realm should get some benefit from that.

For such reason, we now plan (when we begin charging for this; at present we plan on providing it to you for free through September) to use an algorithmic sliding scale for the per-credit fee. Based on the formula we've worked out, here are some examples of what you might expect to pay for an optimization event with the stated quantity of techs and jobs:

  • 4 techs and 32 jobs, $0.28  (request consumes 160 credits at $0.00178 per credit)
  • 8 techs and 64 jobs, $0.81  (request consumes 640 credits at $0.00127 per credit)
  • 16 techs and 128 jobs, $2.34  (request consumes 2,560 credits at $0.00091 per credit)
  • 24 techs and 192 jobs, $4.33  (request consumes 5,760 credits at $0.00075 per credit)
  • 32 techs and 256 jobs, $6.70  (request consumes 10,240 credits at $0.00065 per credit)
  • 40 techs and 320 jobs, $9.40  (request consumes 16,000 credits at $0.00059 per credit)
  • 50 techs and 400 jobs, $13.20  (request consumes 25,000 credits at $0.00053 per credit)
  • 60 techs and 480 jobs, $17.42  (request consumes 36,000 credits at $0.00048 per credit)
Just as with other incremental fee services that Rossware provides, this one will be tallied for you on a monthly basis, reported via email, and simply added as part of your total monthly fee.

If you were previously looking here, you may know that at an earlier point we'd planned to simply give each user their first 100 requests without fee. Ultimately, we decided that a limited period of unlimited free usage make more sense.