Providing Innovative Optimization Solutions

OptTime Software Development Kit

This software development kit (SDK) contains a minimum set of files to allow a user to develop applications for the Optwise Corporation OptTime scheduling environment.  The intent of this SDK is for a customer to use it to embed the functionality of OptTime within their application. Please contact Optwise Corporation if you are interested in a demonstration.

Double clicking on the OCSchedEnvSDK.msi, (MSI script) installs the needed files to the C:\Program Files\Optwise Corporation\OCSchedEnv SDK folder and registers the dll.

The files include:  OptwiseSchedEnv1.dll (within OptTimeSDK folder), OptTimeClient.exe, OptwiseLic.txt, OptTimeSDKHelp.html , 6T1r.dat and folder Microsoft.VC80.CRT. This final folder is also included in the OptTimeSDK folder. This duplication is intentional. It allows both the client and main dll to see the necessary Microsoft support library regardless of which windows operating system  (Windows XP, Vista ) the  SDK is installed on. This SDK is Certified for Windows Vista under the name OCSchedEnv1 SDK .

The core functionality of  OptTime is contained in a single COM dll which is registered in the setup process.  An example of how to use the dll is given later. The dll may be registered manually (without the supplied Msi script) using the command “REGSVR32  OptwiseSchedEnv1.dll”.

Part of the process of using the scheduling environment is calling a License check routine (most commands will be ignored until this is done successfully) a file  OptwiseLic.txt must be custom built for each machine. The test client (below) automatically generates the unique machine ID and displays it in the status box on startup. This ID is needed to generate run time licenses. Contact Optwise Corporation for details.

OCSchedClient.exe, a C++ WinForm client has been provided as an example of a simple client and as a test bench. 

IIt allows the user to load and edit a problem description and a solution string. 

The Run button executes the Solves he problem using the solution method and fills the result in the status and task assignment windows.

 

Output can be copied from the Task assignment window to the clipboard.

Whats in 6T1R.dat or a brief tour of the Input Schedule File Specification.

The Optwise scheduling model consists of task, resources within solution profiles, and task time slots. A task is schedule sometime during a time slot which has associated with it a solution profile and desirability.

The simplest example would be an input file with one task, one resource and one time slot (and associated) solution profile. However   6T1R.dat  is an example of a file with a little bit of complexity.  File  lines without a @ are ignored  ! does not need to be used as a comment marker  but makes them stand out. The pattern is @KeyWord parameters.  This file includes only about 5 % of the available keywords available.

Non file comments have been added in italic ; if the italic comments are included in the real file some input lines may not be parsed correctly

! File: 6t1r.dat
!
!------------------Schedule Info
@NumberTasks 6 number of tasks to be scheduled (int)
@NumberResources 1    number of resources that constraint the task assignments (int)
@NumberProfiles 1     number of solution profiles described further below (int)
@ScheduleStart 0      Schedule start time (almost always 0) (double)
@ScheduleStop 14      Schedule Stop time (double)
!
!------------------Task Info
!TaskIndex | TaskName
@TaskName 0 "job 0"   task name is optional
@TaskName 2 "job 2"
@TaskName 1 "job 1"
@TaskName 3 "job 3"
@TaskName 4 "job 4"
@TaskName 5 "job 5"
!
!Duration of individual tasks by index
!TaskIndex | min needed Duration | <maximum desired Duration>
@TaskDuration 0 2 2    task duration (double) if maximum duration is missing it is set to minimum
@TaskDuration 1 3      if a duration line is not specified for task the task duration defaults to 1
@TaskDuration 2 2
@TaskDuration 3 2
@TaskDuration 4 1
@TaskDuration 5 2
!
!TaskIndex | TaskPriority | Group# | Order#
@TaskPriority 0 1 0 0    task can have priority (int) 1 is most important
@TaskPriority 1 1 1 0    and can be part of groups with order with in the group
@TaskPriority 2 2 2 0    custom groups are used rarely priority often
@TaskPriority 3 3 3 0    if a task priority line is not present for a task priority = 1
@TaskPriority 4 3 4 0
@TaskPriority 5 3 5 0
!
!------------------Resource Info
!ResourceIndex | ResourceName
@ResourceName 0 "resource r0"   optional resource name
!
!ResourceIndex | ResourceCapacity
@ResourceCapacity 0 1.0 capacity of resource (double) default is 1.0
!
!------------------Time Slots Info
!TaskIndex | ProfIndex | NumTimeGroups | {Start, Stop, AssignmentDesirablity} ...
@TimeSlot 0 0 1 {0, 6, 1.0}                   one time slot available from 0 to 6 with desirability 1
@TimeSlot 1 0 2 {0, 6, 1.0} {8, 14, 1.0}      two possible time slots
@TimeSlot 2 0 1 {2, 6, 1.0}
@TimeSlot 3 0 1 {4, 6, 1.0}
@TimeSlot 4 0 2 {0, 2, 1.0} {9, 11, 1.0}
@TimeSlot 5 0 1 {7, 10, 1.0}
!
!------------------Profile Info
!ProfIndex | ProfName
@ProfileName 0 "r0"                 optional profile name
!
!ProfIndex | NumRes | {ResIndex, AmountResourceRequired}...
@ProfileResourceDefn 0 1 {0, 1.0}            this profile uses one resource (0) with capacity 1.0
!


An example of how to connect directly to the Optwise Scheduling Environment

Below is some C++ console example code that implements a minimum (even less than thin client above) interface. Optwise has examples for C#, VB6 , C++ Win32 as well. The example above was implemented in C#. After connecting to COM , problem1 is created

The interface is very simple with one command:


SchedCmd([in] BSTR cmdStr, [out] BSTR* returnStr, [out] SHORT* cmdReturnVal);

and one property, lRunStatus.

The input command string can be very complex in what it specifies but is just a string.
The output string must be deallocated by the calling program.

lrunStatus is used to monitor and control the worker thread that is created by the @Run command.

The user
1) Defines and scheduling problem input stream (here as a file but it can also be long string containing the same data as the file by using “@InitfFromStream string input” command,
2) defines a solve description string which specifies the algorithm and options to use for the run.
3) Runs the solver and waits for a solution
4) query the interface for results.



#include <stdio.h>
#include "stdafx.h"
#import "..\OptwiseSchedEnv1\Release\OptwiseSchedEnv1.dll" no_namespace named_guids
int _tmain(int argc, _TCHAR* argv[])
{
    printf("running Optwise simple c++ client example 11-27-07\n");
    BSTR bstrSolveDescrip;
    BSTR bstrFileInitDescrip;
    BSTR bstrDatStr;

    bstrFileInitDescrip = ::SysAllocString( L"@InitFromFile 6t1r.dat" );
    bstrSolveDescrip = ::SysAllocString(L"@SetupSolveProcedure @BeginTrial(2,1) @Sort1(List) @RunOPS @EndTrial" );

    int j=0; // use for timer
    CoInitialize(NULL);
    try
    {
         IProblemPtr Problem1(CLSID_CProblem);
         short nOut;
         bool bLicOk=false;
         BSTR bstrOut;
         Problem1->SchedCmd("@ValidateLicense Optwise", &bstrOut, &nOut); //optwise license check
         if(nOut < 0) //problem with license
         {
              LPCSTR lpsz = CW2A(bstrOut);
              printf("%s ",lpsz);
              bLicOk=false;
         }
         else bLicOk=true;

         SysFreeString(bstrOut);
         bool bInitOk = false;
         if(bLicOk ==true)
         {
            Problem1->SchedCmd(bstrFileInitDescrip, &bstrOut, &nOut);
            if(nOut < 0)
            {
                if(nOut ==-13) printf(" insufficient file permission\n");
               else printf("file or path missing\n");
               bInitOk = false;
            }
            else bInitOk = true;
            SysFreeString(bstrOut);

            //load solve descriptor
            if(bInitOk ==true)
            {
               Problem1->SchedCmd(bstrSolveDescrip, &bstrOut, &nOut);
               bInitOk = true;
               SysFreeString(bstrOut);
            }
         }
         if(bInitOk ==true)
         {
                long lVar;
                Problem1->SchedCmd("@RunSolveProcedure 0", &bstrOut, &nOut); //mode 0 default
                SysFreeString(bstrOut);
                //printf("back from alg start\n");

                // put client in wait loop
                if(nOut !=-1)for(int i=0;i<7200;i++) // 7200 sec run limit
                {
                       j=i;
                       if(i==7199 || (nState ==-1))
                       {
                              Problem1->SchedCmd("@Halt3", &bstrOut, &nOut);
                              SysFreeString(bstrOut);
                       }
                       Problem1->get_lRunStatus(&lVar);
                       if(lVar == 2)
                       {
                              printf("\nalg controller reports it has completed run\n");
                              break; //alg done
                       }
                       if(lVar <= -2)
                       {
                              printf("\nalg controller reports Halt cmd stopped run\n");
                              break; //alg done
                       }

                              printf("in client waiting for alg run to finish elasped time= %d sec\r",(i+1));
                              Sleep(1000);
                }
         } //end if(bLicOk==true)

         if(nState > -1) Problem1->SchedCmd("@GetAsTaskData best",&bstrOut, &nOut);

         if(nState > -1)
         {
                char lpsz[1024];
                SysFreeString(bstrOut);
                Problem1->SchedCmd("@GetFOM best",&bstrOut, &nOut);
                strcpy_s(lpsz, 1023,CW2A(bstrOut));
                printf("%s ",lpsz);
                SysFreeString(bstrOut);
         }

    }
    catch (_com_error& e)
    {
    printf(e.ErrorMessage());
    }

    SysFreeString( bstrFileInitDescrip );
    SysFreeString( bstrSolveDescrip);

    CoUninitialize();
    if(nState < 0) return -1;

    printf("done! console slept for %d sec\n",j+1);
    printf("5 sec delay in progress so screen can be read\n");
    Sleep(5000);
    return 0;
}