{----------------------------------------------------------------------------} { } { Program : UNITCOMM.PAS } { Last Revised : April 25, 1994 } { Version : 1.0 } { } { Author : David F. Gadberry } { Graduate Student - Electrical Engineering } { Rose-Hulman Institute of Technology } { 5500 Wabash Avenue Box #391 } { Terre Haute, IN 47803 } { (812) 235-9309 } { } { Purpose : Performs generation scheduling using dynamic programming. } { } {----------------------------------------------------------------------------} PROGRAM UNITCOMM; USES CRT, DOS, UTIL, UNITLIB, STRINGS, WINDOS; VAR A : REAL; { TEMP. WORK VARIABLE } AA : INTEGER; { TEMP. LOOP VARIABLE } B : REAL; { TEMP. WORK VARIABLE } BB : INTEGER; { TEMP. VARIABLE } C : REAL; { TEMP. WORK VARIABLE } CC : INTEGER; { TEMP. LOOP VARIABLE } CFG_PATH : STRING [40]; { PATH FOR CONFIG FILE } CHEAP : ARRAY [1..168, 1..12] OF REAL; { RECORD OF CHEAP SCHED} CHEAPEST : REAL; { CHEAPEST COST } CHOICE : CHAR; { USED FOR PROMPTS } CCHOICE : CHAR; { USED FOR PROMPTS } COL : ARRAY [1..10] OF INTEGER; { USED IN LIST_CREATE } COL_D : ARRAY [1..10] OF INTEGER; { USED IN LIST_CREATE } COL_T : ARRAY [1..10] OF INTEGER; { USED IN LIST_CREATE } COST : REAL; { ENERGY COST } COST_MAT : ARRAY [1..10, 1..4] OF REAL; { COST FUNCTION MATRIX } COST_MAT_ALL : ARRAY [1..10, 1..4] OF REAL; { COST FUNC FOR ALL GEN} COST_TOTAL : REAL; { TOTAL COST } D : REAL; { TEMP. WORK VARIABLE } DD : INTEGER; { TEMP. LOOP VARIABLE } DATAFILE : TEXT; { USED FOR SAVING DATA } DEF_PATH : STRING [40]; { DEFAULT FILE PATH } DOWN_TIME : ARRAY [1..9] OF REAL; { DOWN TIME RESTRICTION} E : REAL; { TEMP. WORK VARIABLE } EE : INTEGER; { TEMP. WORK VARIABLE } ENG_COST : ARRAY [1..9] OF REAL; { ARRAY OF ENG. COST } F : REAL; { TEMP. WORK VARIABLE } FC : INTEGER; { FLAG FOR FILE_CHECK } FILE_NAME : STRING [70]; { USED FOR SAVING DATA } FLAG1 : INTEGER; { FLAG FOR TEMP. WORK } FLAG2 : INTEGER; { FLAG FOR TEMP. WORK } FLAG3 : INTEGER; { FLAG FOR TEMP. WORK } GEN_TIME : ARRAY [1..9] OF INTEGER; { ON & OFF TIMES OF GEN} GEN_TIME_I : ARRAY [1..9] OF INTEGER; { INIT. GEN. TIMES } H1, M1 : WORD; { USED TO TIME PROC. } S1, SS1 : WORD; { USED TO TIME PROC. } H2, M2 : WORD; { USED TO TIME PROC. } S2, SS2 : WORD; { USED TO TIME PROC. } I : INTEGER; { LOOP VARIABLE } INIT_POINT : INTEGER; { INITIAL POINTER } INIT_COST : REAL; { INITIAL COST } J : INTEGER; { LOOP VARIABLE } K : INTEGER; { LOOP VARIABLE } KEEP : INTEGER; { # OF COMB. TO KEEP } L : INTEGER; { LOOP VARIABLE } LAST_STATE : ARRAY [1..9] OF INTEGER; { INITIAL SYSTEM STATE } M : INTEGER; { LOOP VARIABLE } LAMBDA : REAL; { SEARCH LAMBDA } LIST_STATE : ARRAY [1..512] OF CHAR; { STATUS OF EACH LIST } LIST_S_OLD : ARRAY [1..512] OF CHAR; { OLD STATE CONDITION } LL : INTEGER; { MAIN LOOP VARIABLE } LOAD_PAT_MAT : ARRAY [1..168, 1..2] OF REAL; { LOAD PATTERN MATRIX } ML : INTEGER; { MAIN LOOP VARIABLE } MAX_GEN : REAL; { MAX. GENERATION } MAX_LAM : ARRAY [1..9] OF REAL; { MATRIX OF MAX LAMBDAS} MAXP_MAT : ARRAY [1..9] OF REAL; { MAX POWER OF GEN UNIT} MAXP_MAT_ALL : ARRAY [1..9] OF REAL; { MAX POWER OF ALL UNIT} MAX_MIN : ARRAY [1..512, 1..2] OF REAL; { MAX-MIN GEN OF P LIST} MIN_GEN : REAL; { MIN. GENERATION } MIN_LAM : ARRAY [1..9] OF REAL; { MATRIX OF MIN LAMBDAS} MINP_MAT : ARRAY [1..9] OF REAL; { MIN POWER OF GEN UNIT} MINP_MAT_ALL : ARRAY [1..9] OF REAL; { MIN POWER OF ALL UNIT} NAME : STRING [12]; { USED FOR SAVING DATA } NF : INTEGER; { FLAG FOR NO_FILE } NUM : INTEGER; { # OF GEN IN LIST_CREA} NUM_DIS : INTEGER; { # OF GEN FOR DISPATCH} NUM_GEN : INTEGER; { TOTAL # OF GENERATORS} NUM_LIST : INTEGER; { # IN PRIORITY LIST } NUM_LOAD_PAT : INTEGER; { # OF LOAD PATTERNS } OFFSET : INTEGER; { OFFSET USED IN SHOW } ORIGMODE : INTEGER; { LAST STATE OF VIDEO } PAIRS : INTEGER; { COUNT VAR IN SORT } PATH_NAME : STRING [40]; { USED FOR SAVING DATA } PEN_FAC : ARRAY [1..9] OF REAL; { PEN. FAC. OF EACH UNI} PRI_LIST : ARRAY [1..512, 1..10] OF INTEGER; { PRIORITY LIST MATRIX } POW_GEN : REAL; { POWER GENERATED } POW_OUT : ARRAY [1..9] OF REAL; { POWER OUT OF EACH UNI} POW_REQ : REAL; { POWER REQUESTED } S : STRING [1]; { TEMP STRING VARIABLE } SCH_LIST : ARRAY [1..168] OF INTEGER; { RECORD OF SCHED. } SCOST : REAL; { COST + STARTUP COST } SDCOST : REAL; { SHUTDOWN COST } SEARCH : INTEGER; { # OF COMB. TO SEARCH } SM : REAL; { SCREEN MODE } SSTG : STRING [5]; { FILE VARIABLE } STARTUP_MAT : ARRAY [1..9, 1..3] OF REAL; { STARTUP COSTS & RESC.} STEMP1 : ARRAY [1..511] OF INTEGER; { SORT TEMP. VARIABLE } STEMP2 : ARRAY [1..511] OF REAL; { SORT TEMP. VARIABLE } ST : REAL; { SORT TEMP. VARIABLE } STI : INTEGER; { SORT TEMP. VARIABLE } TCOST : REAL; { TOTAL COST } TEMP : ARRAY [1..20] OF INTEGER; { TEMP. WORK MATRIX } TEMP1 : INTEGER; { TEMP. VARIABLE } TIME : REAL; { TIME OF COMPUTATIONS } TIME_OLD : ARRAY [1..511, 1..9] OF INTEGER; { OLD TIME ARRAY } TIME_NEW : ARRAY [1..511, 1..9] OF INTEGER; { TIME ARRAY } TOTAL : INTEGER; { TOTAL # OF LISTS } UP_TIME : ARRAY [1..9] OF REAL; { UP TIME RESTRICTIONS } VERSION : REAL; { CURRENT VERSION } XX : INTEGER; { LOOP VARIABLE } {----------------------------------------------------------------------------} { } { Procedure : DISPATCH } { Last Revised : April 12, 1994 } { Purpose : Performs economic dispatch for the given generators. } { } {----------------------------------------------------------------------------} PROCEDURE DISPATCH; VAR ACCUR : REAL; { DETER ACC OF ITER } DER_MAT : ARRAY [1..9, 1..3] OF REAL; { DERIV. OF COST MATRIX} GEN_STATE : ARRAY [1..9] OF CHAR; { STATUS OF EACH GEN. } LAM_STEP : REAL; { STEP VALUE OF LAMBDA } MAX_GEN : REAL; { TOTAL MAX. GENERATION} MAX_LAMBDA : REAL; { MAX LAMBDA FOR SEARCH} MIN_GEN : REAL; { TOTAL MIN. GENERATION} MIN_LAMBDA : REAL; { MIN LAMBDA FOR SEARCH} OLD_GEN_STATE : ARRAY [1..9] OF CHAR; { SAVES OLD GEN. STATES} OLD_LAMBDA : REAL; { SAVES VALUE FOR LAMBD} WORK_MAT : ARRAY [1..9, 1..4] OF REAL; { WORK MAT FOR DIS ROUT} BEGIN MIN_GEN := 0; MAX_GEN := 0; MAX_LAMBDA := 0; MIN_LAMBDA := 1000; FOR I := 1 TO NUM_DIS DO BEGIN POW_OUT [I] := 0; GEN_STATE [I] := 'R'; DER_MAT [I, 1] := 3 * COST_MAT [I, 1]; DER_MAT [I, 2] := 2 * COST_MAT [I, 2]; DER_MAT [I, 3] := 1 * COST_MAT [I, 3]; A := DER_MAT [I, 1]; B := DER_MAT [I, 2]; C := DER_MAT [I, 3]; WORK_MAT [I, 1] := 0; WORK_MAT [I, 2] := 0; IF A <> 0 THEN BEGIN WORK_MAT [I, 1] := - B / (2 * A); WORK_MAT [I, 2] := 1 / (2 * A); END; WORK_MAT [I, 3] := B * B; WORK_MAT [I, 4] := 4 * A; MAX_GEN := MAX_GEN + MAXP_MAT [I]; MIN_GEN := MIN_GEN + MINP_MAT [I]; D := MINP_MAT [I]; E := MAXP_MAT [I]; MIN_LAM [I] := A * D * D + B * D + C; MAX_LAM [I] := A * E * E + B * E + C; IF MIN_LAM [I] < MIN_LAMBDA THEN MIN_LAMBDA := MIN_LAM [I]; IF MAX_LAM [I] > MAX_LAMBDA THEN MAX_LAMBDA := MAX_LAM [I]; END; LAMBDA := (MIN_LAMBDA + MAX_LAMBDA) / 2; LAM_STEP := (MAX_LAMBDA - MIN_LAMBDA) / 4; ACCUR := 1000; WHILE ABS (ACCUR) > 0.001 DO BEGIN POW_GEN := 0; FOR I := 1 TO NUM_DIS DO BEGIN IF LAMBDA < MIN_LAM [I] THEN BEGIN GEN_STATE [I] := 'L'; POW_OUT [I] := MINP_MAT [I]; END; IF LAMBDA > MAX_LAM [I] THEN BEGIN GEN_STATE [I] := 'H'; POW_OUT [I] := MAXP_MAT [I]; END; A := WORK_MAT [I, 1]; B := WORK_MAT [I, 2]; C := WORK_MAT [I, 3]; D := WORK_MAT [I, 4]; E := DER_MAT [I, 3]; IF ( (DER_MAT [I, 1] = 0) AND (GEN_STATE [I] = 'R') ) THEN BEGIN POW_OUT [I] := (LAMBDA - DER_MAT [I, 3]) / DER_MAT [I, 2]; END; IF ( (DER_MAT [I, 1] <> 0) AND (GEN_STATE [I] = 'R') ) THEN BEGIN POW_OUT [I] := A + B * SQRT (C - D * (E - LAMBDA) ); END; POW_GEN := POW_GEN + POW_OUT [I]; OLD_GEN_STATE [I] := GEN_STATE [I]; GEN_STATE [I] := 'R'; END; ACCUR := POW_GEN - POW_REQ; OLD_LAMBDA := LAMBDA; IF ACCUR < 0 THEN LAMBDA := LAMBDA + LAM_STEP; IF ACCUR > 0 THEN LAMBDA := LAMBDA - LAM_STEP; LAM_STEP := LAM_STEP / 2; END; LAMBDA := OLD_LAMBDA; COST := 0; FOR I := 1 TO NUM_DIS DO BEGIN A := POW_OUT [I]; COST:= COST+A*A*A*COST_MAT[I,1]+A*A*COST_MAT[I,2]+A*COST_MAT[I,3]+COST_MAT[I,4]; GEN_STATE [I] := OLD_GEN_STATE [I]; END; END; {----------------------------------------------------------------------------} { } { Procedure : LOAD_GEN_DATA } { Last Revised : April 11, 1994 } { Purpose : Loads information from the data files. } { } {----------------------------------------------------------------------------} PROCEDURE LOAD_GEN_DATA; BEGIN WHILE CHOICE <> '9' DO BEGIN TITLE (VERSION); GOTOXY (1, 25); WRITE (' '); GOTOXY (1, 25); WRITE ('PATH: ', PATH_NAME); GOTOXY (1, 5); WRITELN ('LOAD DATA MENU:'); WRITELN; WRITELN (' 1 - Load generator data. *.GEN'); IF FLAG1 = 1 THEN BEGIN WRITELN (' 2 - Load priority list. *.LST'); END ELSE BEGIN WRITELN (' '); END; WRITELN (' 3 - Load pattern of loading. *.LDP'); WRITELN; WRITELN; WRITELN (' 8 - Change PATH.'); WRITELN (' 9 - Exit.'); WRITELN; WRITE ('Please enter your choice: '); CHOICE := READKEY; IF CHOICE = '1' THEN BEGIN SSTG := '*.GEN'; IF PATH_NAME <> 'C:\' THEN DELETE (PATH_NAME, (LENGTH (PATH_NAME) ), 1); CHDIR (PATH_NAME); FILE_NAME := SELECTFROMDIR (SSTG, 1, 3); IF PATH_NAME <> 'C:\' THEN PATH_NAME := PATH_NAME + '\'; TEXTCOLOR (LIGHTGRAY); IF FILE_CHECK (FILE_NAME, FC) THEN BEGIN ASSIGN (DATAFILE, FILE_NAME); RESET (DATAFILE); READLN (DATAFILE, NUM_GEN); FOR I := 1 TO NUM_GEN DO BEGIN READ (DATAFILE, MINP_MAT_ALL [I]); READ (DATAFILE, MAXP_MAT_ALL [I]); READ (DATAFILE, ENG_COST [I]); READ (DATAFILE, PEN_FAC [I]); READ (DATAFILE, UP_TIME [I]); READ (DATAFILE, DOWN_TIME [I]); READ (DATAFILE, STARTUP_MAT [I, 1]); READ (DATAFILE, STARTUP_MAT [I, 2]); READLN (DATAFILE, STARTUP_MAT [I, 3]); END; FOR I := 1 TO NUM_GEN DO BEGIN READ (DATAFILE, COST_MAT_ALL [I, 1]); READ (DATAFILE, COST_MAT_ALL [I, 2]); READ (DATAFILE, COST_MAT_ALL [I, 3]); READLN (DATAFILE, COST_MAT_ALL [I, 4]); END; CLOSE (DATAFILE); GOTOXY (1, 18); WRITELN (FILE_NAME, ' loaded.'); WRITELN; WRITE ('PRESS ANY KEY TO CONTINUE.....'); CHOICE := READKEY; GOTOXY (1, 18); WRITE (' '); GOTOXY (1, 20); WRITE (' '); CHOICE := ' '; FLAG1 := 1; FOR I := 1 TO NUM_GEN DO BEGIN COST_MAT_ALL[I,1]:=COST_MAT_ALL[I,1]*ENG_COST[I]*1/(1-PEN_FAC[I]); COST_MAT_ALL[I,2]:=COST_MAT_ALL[I,2]*ENG_COST[I]*1/(1-PEN_FAC[I]); COST_MAT_ALL[I,3]:=COST_MAT_ALL[I,3]*ENG_COST[I]*1/(1-PEN_FAC[I]); COST_MAT_ALL[I,4]:=COST_MAT_ALL[I,4]*ENG_COST[I]*1/(1-PEN_FAC[I]); END; END ELSE BEGIN NO_FILE (NF); END; END; IF CHOICE = '2' THEN BEGIN IF FLAG1 = 0 THEN BEGIN BELL (3500, 300); WINDOW (18, 9, 62, 18); STOREALPHAWINDOW; VIDEO (INV, FALSE); WINDOWFRAME (3); CLRSCR; WRITELN (' When the priority list data is loaded'); WRITELN (' into the program, calculations are'); WRITELN (' performed to determine the maximum and'); WRITELN (' minimum generation possible for each entry.'); WRITELN (' Since these calculations are based on the'); WRITELN (' generator specifications, the generator'); WRITELN (' data must be loaded first.'); WRITELN; WRITELN; WRITE (' PRESS ANY KEY TO CONTINUE...'); CHOICE := READKEY; VIDEO (LOW, FALSE); TEXTCOLOR (LIGHTGRAY); RELOADALPHAWINDOW (FALSE); WINDOW (1, 1, 80, 25); END ELSE BEGIN SSTG := '*.LST'; IF PATH_NAME <> 'C:\' THEN DELETE (PATH_NAME, (LENGTH (PATH_NAME) ), 1); CHDIR (PATH_NAME); FILE_NAME := SELECTFROMDIR (SSTG, 1, 3); IF PATH_NAME <> 'C:\' THEN PATH_NAME := PATH_NAME + '\'; TEXTCOLOR (LIGHTGRAY); IF FILE_CHECK (FILE_NAME, FC) THEN BEGIN ASSIGN (DATAFILE, FILE_NAME); RESET (DATAFILE); AA := NUM_GEN + 1; READLN (DATAFILE, NUM_LIST); FOR I := 1 TO NUM_LIST DO BEGIN FOR J := 1 TO AA DO BEGIN IF J < AA THEN READ (DATAFILE, PRI_LIST [I, J]); IF J = AA THEN READLN (DATAFILE, PRI_LIST [I, J]); END; END; CLOSE (DATAFILE); GOTOXY (1, 18); WRITELN (FILE_NAME, ' loaded.'); WRITELN; WRITE ('PRESS ANY KEY TO CONTINUE.....'); CHOICE := READKEY; GOTOXY (1, 18); WRITE (' '); GOTOXY (1, 20); WRITE (' '); END ELSE BEGIN NO_FILE (NF); END; END; CHOICE := ' '; FOR I := 1 TO NUM_LIST DO BEGIN MAX_MIN [I, 1] := 0; MAX_MIN [I, 2] := 0; END; MIN_GEN := 999999999; MAX_GEN := 0; FOR I := 1 TO NUM_LIST DO BEGIN FOR J := 2 TO AA DO BEGIN BB := J - 1; IF PRI_LIST [I, J] = 1 THEN MAX_MIN [I, 1] := MAX_MIN [I, 1] + MINP_MAT_ALL [BB]; IF PRI_LIST [I, J] = 1 THEN MAX_MIN [I, 2] := MAX_MIN [I, 2] + MAXP_MAT_ALL [BB]; END; IF MAX_MIN [I, 1] < MIN_GEN THEN MIN_GEN := MAX_MIN [I, 1]; IF MAX_MIN [I, 2] > MAX_GEN THEN MAX_GEN := MAX_MIN [I, 2]; END; END; IF CHOICE = '3' THEN BEGIN SSTG := '*.LDP'; IF PATH_NAME <> 'C:\' THEN DELETE (PATH_NAME, (LENGTH (PATH_NAME) ), 1); CHDIR (PATH_NAME); FILE_NAME := SELECTFROMDIR (SSTG, 1, 3); IF PATH_NAME <> 'C:\' THEN PATH_NAME := PATH_NAME + '\'; TEXTCOLOR (LIGHTGRAY); IF FILE_CHECK (FILE_NAME, FC) THEN BEGIN ASSIGN (DATAFILE, FILE_NAME); RESET (DATAFILE); READLN (DATAFILE, NUM_LOAD_PAT); FOR I := 1 TO NUM_LOAD_PAT DO BEGIN READ (DATAFILE, LOAD_PAT_MAT [I, 1]); READLN (DATAFILE, LOAD_PAT_MAT [I, 2]); END; CLOSE (DATAFILE); GOTOXY (1, 18); WRITELN (FILE_NAME, ' loaded.'); WRITELN; WRITE ('PRESS ANY KEY TO CONTINUE.....'); CHOICE := READKEY; GOTOXY (1, 18); WRITE (' '); GOTOXY (1, 20); WRITE (' '); END ELSE BEGIN NO_FILE (NF); END; CHOICE := ' '; END; IF CHOICE = '8' THEN BEGIN DEF_PATH := READ_PATH (PATH_NAME); PATH_NAME := DEF_PATH; END; END; CHOICE := ' '; END; {----------------------------------------------------------------------------} { } { Procedure : READ_CONFIG } { Last Revised : January 4, 1994 } { Purpose : Reads information from the config file (UNITCOMM.CFG). } { } {----------------------------------------------------------------------------} PROCEDURE READ_CONFIG; VAR TFILE : STRING [40]; { TEMP STRING VARIABLE } BEGIN IF CFG_PATH [LENGTH (CFG_PATH) ] = '\' THEN BEGIN TFILE := CFG_PATH + 'UNITCOMM.CFG'; END ELSE BEGIN TFILE := CFG_PATH + '\' + 'UNITCOMM.CFG'; END; IF FILE_CHECK (TFILE, FC) THEN BEGIN ASSIGN (DATAFILE, 'UNITCOMM.CFG'); RESET (DATAFILE); READLN (DATAFILE, DEF_PATH); CLOSE (DATAFILE); END ELSE BEGIN DEF_PATH := 'C:\'; END; END; {----------------------------------------------------------------------------} { } { Procedure : CREATE_DATA } { Last Revised : September 19, 1993 } { Purpose : Creates data to be used in UNITCOMM.PAS } { } {----------------------------------------------------------------------------} PROCEDURE CREATE_DATA; VAR T_LIST : ARRAY [1..515, 1..13] OF INTEGER; { TEMP. PRIORITY LST MAT } BEGIN {$M 32768,0,655360} FC := 1; WHILE CHOICE <> '9' DO BEGIN TITLE (VERSION); GOTOXY (1, 25); WRITE (' '); GOTOXY (1, 25); WRITE ('PATH: ', PATH_NAME); GOTOXY (1, 5); WRITELN ('CREATE DATA MENU:'); WRITELN; WRITELN (' 1 - Create a priority list file. *.LST'); WRITELN (' 2 - Create a pattern of loading file. *.LDP'); WRITELN; WRITELN; WRITELN; WRITELN (' 8 - Change PATH.'); WRITELN (' 9 - Exit.'); WRITELN; WRITE ('Please enter your choice: '); CHOICE := READKEY; IF CHOICE = '1' THEN BEGIN TITLE (VERSION); FLAG2 := 0; GOTOXY (1, 5); WRITE ('Enter file name (Do not include .LST): '); READLN (NAME); FILE_NAME := PATH_NAME + NAME + '.LST'; IF FILE_CHECK (FILE_NAME, FC) THEN BEGIN GOTOXY (1, 5); WRITE (' '); GOTOXY (1, 7); WRITE (' '); NUM := 20; WHILE (NUM > 9) OR (NUM < 1) DO BEGIN GOTOXY (1, 5); WRITE ('Please enter the number of generators (MAX=9): '); READLN (NUM); GOTOXY (1, 5); WRITELN (' '); END; A := 999999; B := - 1; GOTOXY (1, 5); WRITE ('Filter priority list with max load? (Y/N): '); CHOICE := UPCASE (READKEY); GOTOXY (1, 5); WRITELN (' '); IF CHOICE = 'Y' THEN BEGIN GOTOXY (1, 5); WRITE ('Enter max load: '); READLN (A); GOTOXY (1, 5); WRITELN (' '); FLAG2 := 1; END; GOTOXY (1, 5); WRITE ('Filter priority list with min load? (Y/N): '); CHOICE := UPCASE (READKEY); GOTOXY (1, 5); WRITELN (' '); IF CHOICE = 'Y' THEN BEGIN GOTOXY (1, 5); WRITE ('Enter min load: '); READLN (B); GOTOXY (1, 5); WRITELN (' '); FLAG2 := 1; END; IF (FLAG2 = 1) AND (NUM_GEN <> NUM) THEN BEGIN NO_GENDATA; END ELSE BEGIN COL [NUM] := 1; FOR I := (NUM - 1) DOWNTO 1 DO BEGIN COL [I] := 2 * COL [I + 1]; END; FOR I := 1 TO NUM DO BEGIN COL_T [I] := COL [I]; COL_D [I] := 0; END; TOTAL := 2 * COL_T [1] - 1; FOR I := 1 TO NUM DO BEGIN COL_T [I] := COL_T [I] - 1; END; L := 1; FOR I := 1 TO TOTAL DO BEGIN FOR J := 1 TO NUM DO BEGIN IF COL_T [J] <> 0 THEN TEMP [J] := COL_D [J]; IF COL_T [J] = 0 THEN BEGIN IF COL_D [J] = 1 THEN BEGIN COL_D [J] := 0; END ELSE BEGIN COL_D [J] := 1; END; TEMP [J] := COL_D [J]; COL_T [J] := COL [J]; END; END; FOR K := 1 TO NUM DO COL_T [K] := COL_T [K] - 1; C := 0; D := 0; FOR AA := 1 TO NUM DO BEGIN IF TEMP [AA] = 1 THEN BEGIN C := C + MAXP_MAT_ALL [AA]; D := D + MINP_MAT_ALL [AA]; END; END; IF (A >= D) AND (C >= B) THEN BEGIN FOR M := 1 TO NUM DO BEGIN BB := M + 1; T_LIST [L, BB] := TEMP [M]; END; L := L + 1; END; END; ASSIGN (DATAFILE, FILE_NAME); REWRITE (DATAFILE); AA := L - 1; WRITELN (DATAFILE, AA); BB := NUM + 1; FOR I := 1 TO AA DO BEGIN WRITE (DATAFILE, I : 3, ' '); FOR J := 2 TO BB DO BEGIN IF J < BB THEN WRITE (DATAFILE, T_LIST [I, J], ' '); IF J = BB THEN WRITELN (DATAFILE, T_LIST [I, J]); END; END; CLOSE (DATAFILE); GOTOXY (1, 5); WRITELN (FILE_NAME, ' created.'); WRITELN; WRITELN (AA, ' acceptable schedule(s) saved.'); WRITELN; WRITE ('PRESS ANY KEY TO CONTINUE.....'); CHOICE := READKEY; GOTOXY (1, 5); WRITE (' '); GOTOXY (1, 7); WRITE (' '); GOTOXY (1, 9); WRITE (' '); END; END ELSE BEGIN NF := 1; NO_FILE (NF); NF := 0; END; END; IF CHOICE = '2' THEN BEGIN TITLE (VERSION); GOTOXY (1, 5); WRITE ('Enter file name (Do not include .LDP): '); READLN (NAME); FILE_NAME := PATH_NAME + NAME + '.LDP'; IF FILE_CHECK (FILE_NAME, FC) THEN BEGIN GOTOXY (1, 5); WRITE (' '); GOTOXY (1, 7); WRITE (' '); ASSIGN (DATAFILE, FILE_NAME); REWRITE (DATAFILE); NUM := - 1; WHILE (NUM > 100) OR (NUM < 1) DO BEGIN GOTOXY (1, 5); WRITE ('Please enter the number of loading periods (MAX=100): '); READLN (NUM); GOTOXY (1, 5); WRITELN (' '); END; WRITELN (DATAFILE, NUM); FOR I := 1 TO NUM DO BEGIN GOTOXY (1, 5); WRITE ('Please enter the load for period #', I, ': '); READLN (A); WRITE (DATAFILE, I, ' '); WRITELN (DATAFILE, A : 8 : 2); GOTOXY (1, 5); WRITELN (' '); END; CLOSE (DATAFILE); END ELSE BEGIN NF := 1; NO_FILE (NF); NF := 0; END; END; IF CHOICE = '8' THEN BEGIN DEF_PATH := READ_PATH (PATH_NAME); PATH_NAME := DEF_PATH; END; END; CHOICE := ' '; FC := 0; END; {----------------------------------------------------------------------------} { } { Procedure : SHOW_HEADER } { Last Revised : December 15, 1993 } { Purpose : Shows header information. } { } {----------------------------------------------------------------------------} PROCEDURE SHOW_HEADER; BEGIN TITLE (VERSION); GOTOXY (35, 4); TEXTCOLOR (YELLOW); WRITE ('MAXIMUM '); TEXTCOLOR (RED); WRITE ('MINIMUM '); TEXTCOLOR (WHITE); WRITE ('REGULATING '); TEXTCOLOR (LIGHTBLUE); WRITE ('OFF-LINE'); TEXTCOLOR (GREEN); GOTOXY (1, 6); WRITELN (' LOAD SCH '); WRITE (' # POWER # COST LAMBDA'); FOR AA := 1 TO NUM_GEN DO BEGIN BB := 30 + AA * 5; GOTOXY (BB, 7); STR (AA : 1, S); WRITE ('U ', S); END; TEXTCOLOR (LIGHTGRAY); END; {----------------------------------------------------------------------------} { } { Procedure : SHOW } { Last Revised : April 13, 1994 } { Purpose : Shows information from unit committment calculations. } { } {----------------------------------------------------------------------------} PROCEDURE SHOW; BEGIN COST_TOTAL := 0; FOR EE := 1 TO NUM_LOAD_PAT DO BEGIN COST_TOTAL := COST_TOTAL + CHEAP [EE, 2]; END; WHILE CCHOICE <> '9' DO BEGIN TITLE (VERSION); GOTOXY (1, 25); WRITE (' '); GOTOXY (1, 25); WRITE ('PATH: ', PATH_NAME); GOTOXY (1, 5); WRITELN ('OUTPUT MENU:'); WRITELN; WRITELN (' 1 - Send output to screen.'); WRITELN (' 2 - Send output to a file....'); WRITELN; WRITELN; WRITELN (' 8 - Change PATH.'); WRITELN (' 9 - Exit.'); WRITELN; WRITE ('Please enter your choice: '); CCHOICE := READKEY; IF (CCHOICE = '1') THEN BEGIN OFFSET := 0; ORIGMODE := LASTMODE; TEXTMODE (C80 + FONT8X8); SHOW_HEADER; FOR EE := 1 TO NUM_LOAD_PAT DO BEGIN AA := EE - OFFSET; BB := 2 * AA + 7; GOTOXY (1, BB); WRITE (EE : 2); GOTOXY (5, BB); WRITE (CHEAP [EE, 1] : 5 : 0); GOTOXY (12, BB); WRITE (SCH_LIST [EE] : 3); GOTOXY (17, BB); WRITE (CHEAP [EE, 2] : 8 : 2); GOTOXY (27, BB); WRITE (CHEAP [EE, 3] : 6 : 3); IF EE = NUM_LOAD_PAT THEN BEGIN GOTOXY (16, (BB + 1) ); WRITE ('----------'); GOTOXY (15, (BB + 2) ); WRITE (COST_TOTAL : 10 : 2); END; FOR CC := 1 TO NUM_GEN DO BEGIN DD := 29 + 5 * CC; GOTOXY (DD, BB); TEXTCOLOR (WHITE); IF ABS (CHEAP [EE, (CC + 3) ] - MAXP_MAT_ALL [CC]) < 0.5 THEN TEXTCOLOR (YELLOW); IF ABS (CHEAP [EE, (CC + 3) ] - MINP_MAT_ALL [CC]) < 0.5 THEN TEXTCOLOR (RED); IF CHEAP [EE, (CC + 3) ] = 0 THEN TEXTCOLOR (LIGHTBLUE); WRITE (CHEAP [EE, (CC + 3) ] : 4 : 0); TEXTCOLOR (LIGHTGRAY); END; A := NUM_LOAD_PAT / 19; IF ( (INT (EE / 19) ) = (EE / 19) ) AND ( (INT (A) ) <> A) THEN BEGIN GOTOXY (1, (BB + 5) ); WRITE ('PRESS ANY KEY TO CONTINUE...'); CHOICE := READKEY; SHOW_HEADER; OFFSET := OFFSET + 19; END; END; GOTOXY (1, (BB + 5) ); WRITE ('PRESS ANY KEY TO CONTINUE...'); CHOICE := READKEY; TEXTMODE (ORIGMODE); END; IF CCHOICE = '2' THEN BEGIN TITLE (VERSION); GOTOXY (1, 5); WRITE ('Enter file name: '); READLN (NAME); FILE_NAME := PATH_NAME + NAME; ASSIGN (DATAFILE, FILE_NAME); REWRITE (DATAFILE); WRITELN (DATAFILE, 'UNITCOMM V', VERSION : 2 : 1); WRITELN (DATAFILE, ''); WRITELN (DATAFILE, ' TIME: ', TIME : 5 : 2, ' SECONDS'); WRITELN (DATAFILE, ' INITIAL COST: ', INIT_COST : 10 : 2); WRITELN (DATAFILE, ' SEARCH: ', SEARCH : 3, ' (MAX = ', NUM_LIST, ')'); WRITELN (DATAFILE, ' KEEP: ', KEEP : 3, ' (MAX = ', NUM_LIST, ')'); WRITE (DATAFILE, ' INITIAL TIME: '); FOR EE := 1 TO NUM_GEN DO BEGIN WRITE (DATAFILE, ' ', GEN_TIME_I [EE] : 3); END; WRITELN (DATAFILE, ''); WRITE (DATAFILE, 'INITIAL STATE: '); FOR EE := 1 TO NUM_GEN DO BEGIN IF GEN_TIME_I [EE] > 0 THEN WRITE (DATAFILE, ' 1'); IF GEN_TIME_I [EE] < 0 THEN WRITE (DATAFILE, ' 0'); END; WRITELN (DATAFILE, ''); WRITELN (DATAFILE, ''); WRITELN (DATAFILE, ' LOAD SCH'); WRITE (DATAFILE, ' # POWER # COST LAMBDA'); FOR EE := 1 TO NUM_GEN DO BEGIN WRITE (DATAFILE, ' U ', EE); END; WRITELN (DATAFILE, ''); WRITELN (DATAFILE, ''); FOR EE := 1 TO NUM_LOAD_PAT DO BEGIN WRITE (DATAFILE, EE : 3); WRITE (DATAFILE, CHEAP [EE, 1] : 6 : 0); WRITE (DATAFILE, SCH_LIST [EE] : 5); WRITE (DATAFILE, CHEAP [EE, 2] : 10 : 2); WRITE (DATAFILE, CHEAP [EE, 3] : 8 : 3); FOR CC := 1 TO NUM_GEN DO BEGIN IF CC < NUM_GEN THEN WRITE (DATAFILE, CHEAP [EE, (CC + 3) ] : 5 : 0); IF CC = NUM_GEN THEN WRITELN (DATAFILE, CHEAP [EE, (CC + 3) ] : 5 : 0); END; IF EE = NUM_LOAD_PAT THEN BEGIN WRITELN (DATAFILE, ' ----------'); WRITELN (DATAFILE, ' ', COST_TOTAL : 10 : 2); END; END; CLOSE (DATAFILE); WRITELN; WRITELN (FILE_NAME, ' created.'); WRITELN; WRITELN; WRITELN; WRITELN ('PRESS ANY KEY TO CONTINUE.....'); CHOICE := READKEY; END; IF CCHOICE = '8' THEN BEGIN DEF_PATH := READ_PATH (PATH_NAME); PATH_NAME := DEF_PATH; END; END; CHOICE := ' '; CCHOICE := ' '; END; {----------------------------------------------------------------------------} { } { Procedure : GET_TIME } { Last Revised : April 18, 1994 } { Purpose : Gets initial conditions of each generator. } { } {----------------------------------------------------------------------------} PROCEDURE GET_TIME; BEGIN WHILE CHOICE <> '9' DO BEGIN TITLE (VERSION); GOTOXY (1, 20); TEXTCOLOR (WHITE); WRITE (' GEN. #: '); TEXTCOLOR (GREEN); FOR EE := 1 TO NUM_GEN DO BEGIN WRITE (' ', EE : 3); END; WRITELN; TEXTCOLOR (WHITE); WRITE (' INITIAL TIME: '); TEXTCOLOR (YELLOW); FOR EE := 1 TO NUM_GEN DO BEGIN WRITE (' ', GEN_TIME_I [EE] : 3); END; WRITELN; TEXTCOLOR (WHITE); WRITE ('INITIAL STATE: '); TEXTCOLOR (YELLOW); FOR EE := 1 TO NUM_GEN DO BEGIN IF GEN_TIME_I [EE] > 0 THEN WRITE (' 1'); IF GEN_TIME_I [EE] < 0 THEN WRITE (' 0'); END; WRITELN; TEXTCOLOR (WHITE); WRITE (' INITIAL COST: '); TEXTCOLOR (YELLOW); WRITELN (INIT_COST : 10 : 2); TEXTCOLOR (WHITE); WRITE ('SHUTDOWN COST: '); TEXTCOLOR (YELLOW); WRITELN (SDCOST : 10 : 2); TEXTCOLOR (LIGHTGRAY); GOTOXY (1, 5); WRITELN ('INITIAL CONDITION MENU:'); WRITELN; WRITELN (' 1 - Change the initial conditions of the generators.'); WRITELN (' 2 - Change the initial cost of the system.'); WRITELN (' 3 - Change the shutdown cost for the generators.'); WRITELN; WRITELN; WRITELN; WRITELN (' 9 - Exit.'); WRITELN; WRITE ('Please enter your choice: '); CHOICE := READKEY; IF CHOICE = '1' THEN BEGIN TITLE (VERSION); GOTOXY (1, 5); WRITELN ('+ UP-TIME'); WRITELN ('- DOWN-TIME'); FOR I := 1 TO NUM_GEN DO BEGIN GEN_TIME_I [I] := 0; WHILE GEN_TIME_I [I] = 0 DO BEGIN GOTOXY (1, 9); WRITE ('Please enter the intial condition for generator #', I, ': '); READLN (GEN_TIME_I [I]); GOTOXY (1, 9); WRITELN (' '); IF GEN_TIME_I [I] > 0 THEN LAST_STATE [I] := 1; IF GEN_TIME_I [I] < 0 THEN LAST_STATE [I] := 0; IF GEN_TIME_I [I] = 0 THEN BEGIN GOTOXY (1, 9); WRITE ('Initial condition for generators cannot equal 0!'); GOTOXY (1, 11); WRITE (' PRESS ANY KEY TO CONTINUE....'); CHOICE := READKEY; GOTOXY (1, 9); WRITE (' '); GOTOXY (1, 11); WRITE (' '); END; END; END; FOR AA := 1 TO NUM_LIST DO BEGIN TEMP1 := 0; FOR BB := 1 TO NUM_GEN DO BEGIN IF LAST_STATE [BB] <> PRI_LIST [AA, (BB + 1) ] THEN TEMP1 := 1; END; IF TEMP1 = 0 THEN INIT_POINT := AA; END; CHOICE := ' '; END; IF CHOICE = '2' THEN BEGIN TITLE (VERSION); GOTOXY (1, 5); INIT_COST := 0; WRITE ('Please enter the initial cost of the system: '); READLN (INIT_COST); GOTOXY (1, 11); IF INIT_COST < 0 THEN INIT_COST := 0; END; IF CHOICE = '3' THEN BEGIN TITLE (VERSION); GOTOXY (1, 5); SDCOST := 0; WRITE ('Please enter the shutdown cost for the generators: '); READLN (SDCOST); GOTOXY (1, 11); IF SDCOST < 0 THEN SDCOST := 0; END; END; CHOICE := ' '; END; {----------------------------------------------------------------------------} { } { Procedure : CHECK_FEAS_TIME; } { Last Revised : March 18, 1994 } { Purpose : Checks the feasibility of combination #LL with respect to } { power requirements and time constraints. } { } {----------------------------------------------------------------------------} PROCEDURE CHECK_FEAS_TIME; BEGIN FOR AA := 1 TO NUM_GEN DO BEGIN BB := AA + 1; IF (PRI_LIST [LL, BB] = 1) AND (GEN_TIME [AA] < 0) THEN BEGIN IF ABS (GEN_TIME [AA]) < DOWN_TIME [AA] THEN LIST_STATE [LL] := 'N'; END; IF (PRI_LIST [LL, BB] = 0) AND (GEN_TIME [AA] > 0) THEN BEGIN IF GEN_TIME [AA] < UP_TIME [AA] THEN LIST_STATE [LL] := 'N'; END; END; END; {----------------------------------------------------------------------------} { } { Procedure : UPDATE_TIME; } { Last Revised : March 11, 1994 } { Purpose : Updates generator times. } { } {----------------------------------------------------------------------------} PROCEDURE UPDATE_TIME; BEGIN FOR BB := 1 TO NUM_GEN DO BEGIN GEN_TIME [BB] := TIME_OLD [TEMP1, BB]; END; FOR BB := 1 TO NUM_GEN DO BEGIN CC := BB + 1; IF PRI_LIST [LL, CC] = 1 THEN BEGIN IF GEN_TIME [BB] > 0 THEN TIME_NEW [LL, BB] := GEN_TIME [BB] + 1; IF GEN_TIME [BB] < 0 THEN TIME_NEW [LL, BB] := 1; END; IF PRI_LIST [LL, CC] = 0 THEN BEGIN IF GEN_TIME [BB] < 0 THEN TIME_NEW [LL, BB] := GEN_TIME [BB] - 1; IF GEN_TIME [BB] > 0 THEN TIME_NEW [LL, BB] := - 1; END; END; END; {----------------------------------------------------------------------------} { } { Procedure : STARTUP_COST; } { Last Revised : April 12, 1994 } { Purpose : Checks for startup of generators and adds corresponding } { cost. } { } {----------------------------------------------------------------------------} PROCEDURE STARTUP_COST; BEGIN SCOST := 0; FOR AA := 1 TO NUM_GEN DO BEGIN IF (LAST_STATE [AA] = 0) AND (PRI_LIST [LL, (AA + 1) ] = 1) THEN BEGIN IF ABS (GEN_TIME [AA]) >= STARTUP_MAT [AA, 3] THEN BEGIN SCOST := SCOST + STARTUP_MAT [AA, 2]; END ELSE BEGIN SCOST := SCOST + STARTUP_MAT [AA, 1]; END; END; IF (LAST_STATE [AA] = 1) AND (PRI_LIST [LL, (AA + 1) ] = 0) THEN SCOST := SCOST + SDCOST; END; TCOST := COST + SCOST; END; {----------------------------------------------------------------------------} { } { Procedure : MOVE_GEN } { Last Revised : January 30, 1994 } { Purpose : Moves specified (by priority list) generators to COST_MAT } { for the DISPATCH. } { } {----------------------------------------------------------------------------} PROCEDURE MOVE_GEN; BEGIN NUM_DIS := 0; FOR AA := 1 TO NUM_GEN DO BEGIN BB := AA + 1; IF PRI_LIST [LL, BB] = 1 THEN BEGIN NUM_DIS := NUM_DIS + 1; FOR CC := 1 TO 4 DO BEGIN COST_MAT [NUM_DIS, CC] := COST_MAT_ALL [AA, CC]; END; MINP_MAT [NUM_DIS] := MINP_MAT_ALL [AA]; MAXP_MAT [NUM_DIS] := MAXP_MAT_ALL [AA]; END; END; END; {----------------------------------------------------------------------------} { } { Procedure : SHIFT_TIME; } { Last Revised : March 10, 1994 } { Purpose : Shifts references of generator up-times for DYN_COMMIT. } { } {----------------------------------------------------------------------------} PROCEDURE SHIFT_TIME; BEGIN FOR AA := 1 TO NUM_GEN DO BEGIN GEN_TIME [AA] := TIME_OLD [EE, AA]; IF GEN_TIME [AA] > 0 THEN LAST_STATE [AA] := 1; IF GEN_TIME [AA] < 0 THEN LAST_STATE [AA] := 0; END; END; {----------------------------------------------------------------------------} { } { Procedure : INIT_SHOW; } { Last Revised : April 13, 1994 } { Purpose : Initializes data to be used in SHOW. } { } {----------------------------------------------------------------------------} PROCEDURE INIT_SHOW; TYPE DATA_TYPE = RECORD D_COST : REAL; D_POINT : INTEGER; D_TCOST : REAL; END; VAR DATA : DATA_TYPE; D_FILE : FILE OF DATA_TYPE; NUM_GEN : INTEGER; NUM_LIST : INTEGER; NUM_LOAD : INTEGER; POINTERS : ARRAY [1..128] OF INTEGER; POS : LONGINT; BEGIN ASSIGN (D_FILE, 'UC_DATA.TMP'); RESET (D_FILE); READ (D_FILE, DATA); NUM_GEN := TRUNC (DATA.D_COST); NUM_LIST := TRUNC (DATA.D_TCOST); NUM_LOAD := DATA.D_POINT; POS := NUM_LIST * (NUM_LOAD - 1) + 1; CHEAPEST := 9999999; ML := NUM_LOAD_PAT; FOR AA := POS TO (POS + (NUM_LIST - 1) ) DO BEGIN SEEK (D_FILE, AA); READ (D_FILE, DATA); IF (DATA.D_TCOST < CHEAPEST) AND (DATA.D_TCOST <> - 1) THEN BEGIN CHEAPEST := DATA.D_TCOST; SCH_LIST [ML] := AA - (POS - 1); CHEAP [ML, 2] := INT (DATA.D_TCOST * 100 + 0.5) / 100; POINTERS [ML] := DATA.D_POINT; END; END; FOR ML := (NUM_LOAD_PAT - 1) DOWNTO 1 DO BEGIN POS := NUM_LIST * (ML - 1) + POINTERS [ML + 1]; SEEK (D_FILE, POS); READ (D_FILE, DATA); SCH_LIST [ML] := POINTERS [ML + 1]; CHEAP [ML, 2] := INT (DATA.D_TCOST * 100 + 0.5) / 100; POINTERS [ML] := DATA.D_POINT; END; CLOSE (D_FILE); FOR ML := 1 TO NUM_LOAD_PAT DO BEGIN LL := SCH_LIST [ML]; POW_REQ := CHEAP [ML, 1]; MOVE_GEN; DISPATCH; CHEAP [ML, 3] := LAMBDA; CC := 1; FOR AA := 1 TO NUM_GEN DO BEGIN BB := AA + 3; IF PRI_LIST [LL, (AA + 1) ] = 1 THEN BEGIN CHEAP [ML, BB] := POW_OUT [CC]; CC := CC + 1; END; IF PRI_LIST [LL, (AA + 1) ] = 0 THEN CHEAP [ML, BB] := 0; END; END; CHEAP [1, 2] := CHEAP [1, 2] + INIT_COST; END; {----------------------------------------------------------------------------} { } { Procedure : SORT; } { Last Revised : April 25, 1994 } { Purpose : Sort routine for keep part of dynamic programming. } { } {----------------------------------------------------------------------------} PROCEDURE SORT; VAR DONE : CHAR; BEGIN PAIRS := NUM_LIST - 1; DONE := 'F'; WHILE DONE <> 'T' DO BEGIN DONE := 'T'; FOR XX := 1 TO PAIRS DO BEGIN IF STEMP2 [XX] > STEMP2 [ (XX + 1) ] THEN BEGIN ST := STEMP2 [XX]; STEMP2 [XX] := STEMP2 [ (XX + 1) ]; STEMP2 [ (XX + 1) ] := ST; STI := STEMP1 [XX]; STEMP1 [XX] := STEMP1 [ (XX + 1) ]; STEMP1 [ (XX + 1) ] := STI; DONE := 'F'; END; END; PAIRS := PAIRS - 1; END; END; {----------------------------------------------------------------------------} { } { Procedure : DYN_COMMIT; } { Last Revised : April 25, 1994 } { Purpose : Performs unit commitment using dynamic programming. } { } {----------------------------------------------------------------------------} PROCEDURE DYN_COMMIT; TYPE DATA_TYPE = RECORD D_COST : REAL; D_POINT : INTEGER; D_TCOST : REAL; END; VAR COST_A : ARRAY [1..511] OF REAL; COST_B : ARRAY [1..511] OF REAL; DATA : DATA_TYPE; D_FILE : FILE OF DATA_TYPE; POINT_A : ARRAY [1..511] OF INTEGER; BEGIN ASSIGN (D_FILE, PATH_NAME + 'UC_DATA.TMP'); REWRITE (D_FILE); DATA.D_COST := NUM_GEN; DATA.D_TCOST := NUM_LIST; DATA.D_POINT := NUM_LOAD_PAT; WRITE (D_FILE, DATA); FOR ML := 1 TO NUM_LIST DO BEGIN LIST_S_OLD [ML] := 'F'; COST_A [ML] := 0; POINT_A [ML] := INIT_POINT; FOR AA := 1 TO NUM_GEN DO BEGIN TIME_OLD [ML, AA] := GEN_TIME_I [AA]; END; END; TITLE (VERSION); GOTOXY (1, 4); WRITE ('Enter the # of states (MAX = ', NUM_LIST, ') to search each period: '); READLN (SEARCH); WRITELN; WRITELN; WRITE ('Enter the # of strategies (MAX = ', NUM_LIST, ') to save each period: '); READLN (KEEP); TITLE (VERSION); GOTOXY (1, 4); WRITE ('Please wait...'); GETTIME (H1, M1, S1, SS1); FOR ML := 1 TO NUM_LOAD_PAT DO BEGIN GOTOXY (1, 6); WRITE ('Working on load #', ML, ' of ', NUM_LOAD_PAT, '.'); CHEAP [ML, 1] := LOAD_PAT_MAT [ML, 2]; POW_REQ := LOAD_PAT_MAT [ML, 2]; FOR LL := 1 TO NUM_LIST DO BEGIN LIST_STATE [LL] := 'N'; IF LL > (NUM_LIST - SEARCH) THEN LIST_STATE [LL] := 'F'; MOVE_GEN; IF (POW_REQ < MAX_MIN [LL, 1]) OR (POW_REQ > MAX_MIN [LL, 2]) THEN LIST_STATE [LL] := 'N'; STEMP2 [LL] := 9999999; STEMP1 [LL] := LL; DATA.D_COST := - 1; DATA.D_TCOST := - 1; DATA.D_POINT := - 1; CHEAPEST := 0; IF LIST_STATE [LL] = 'F' THEN BEGIN DISPATCH; CHEAPEST := 9999999; FOR EE := 1 TO NUM_LIST DO BEGIN LIST_STATE [LL] := 'F'; SCOST := 0; IF LIST_S_OLD [EE] = 'F' THEN BEGIN SHIFT_TIME; CHECK_FEAS_TIME; IF LIST_STATE [LL] = 'F' THEN BEGIN STARTUP_COST; IF (TCOST + COST_A [EE]) < CHEAPEST THEN BEGIN CHEAPEST := TCOST + COST_A [EE]; DATA.D_COST := TCOST + COST_A [EE]; DATA.D_TCOST := TCOST; DATA.D_POINT := EE; STEMP2 [LL] := CHEAPEST; IF ML = 1 THEN DATA.D_POINT := INIT_POINT; TEMP1 := EE; END; END; END; END; UPDATE_TIME; END; COST_B [LL] := CHEAPEST; WRITE (D_FILE, DATA); END; FOR AA := 1 TO NUM_LIST DO BEGIN LIST_S_OLD [AA] := 'F'; IF AA < (NUM_LIST - SEARCH + 1) THEN LIST_S_OLD [AA] := 'N'; COST_A [AA] := COST_B [AA]; IF (POW_REQ < MAX_MIN [AA, 1]) OR (POW_REQ > MAX_MIN [AA, 2]) THEN LIST_S_OLD [AA] := 'N'; END; IF KEEP <> NUM_LIST THEN BEGIN SORT; FOR XX := (KEEP + 1) TO NUM_LIST DO BEGIN STI := STEMP1 [XX]; LIST_S_OLD [STI] := 'N'; END; END; FOR AA := 1 TO NUM_LIST DO BEGIN FOR BB := 1 TO NUM_GEN DO BEGIN TIME_OLD [AA, BB] := TIME_NEW [AA, BB]; TIME_NEW [AA, BB] := 0; END; END; END; CLOSE (D_FILE); BELL (3500, 300); GETTIME (H2, M2, S2, SS2); TIME := (M2 * 60 + S2 + SS2 / 100) - (M1 * 60 + S1 + SS1 / 100); WRITELN; WRITELN; WRITELN ('Elapsed time in seconds : ', TIME : 5 : 2); WRITELN; WRITE (' PRESS ANY KEY TO CONTINUE....'); READKEY; INIT_SHOW; SHOW; CHOICE := ' '; END; {----------------------------------------------------------------------------} { } { Procedure : ECON_HEADER; } { Last Revised : December 16, 1993 } { Purpose : Header for ECON routine. } { } {----------------------------------------------------------------------------} PROCEDURE ECON_HEADER; BEGIN TITLE (VERSION); TEXTCOLOR (GREEN); WRITELN ('SCH # COST LAMBDA'); FOR AA := 1 TO NUM_GEN DO BEGIN GOTOXY ( (24 + 5 * AA), 4); WRITE ('U ', AA); END; WRITELN; WRITELN; TEXTCOLOR (LIGHTGRAY); END; {----------------------------------------------------------------------------} { } { Procedure : ECON; } { Last Revised : December 17, 1993 } { Purpose : Performs economic dispatch. } { } {----------------------------------------------------------------------------} PROCEDURE ECON; BEGIN POW_REQ := 1; WHILE POW_REQ <> 0 DO BEGIN TITLE (VERSION); WRITELN (' Max: ', MAX_GEN : 5 : 0, ' Min: ', MIN_GEN : 5 : 0); WRITELN; WRITE ('Enter power (0 to quit): '); READLN (POW_REQ); IF POW_REQ <> 0 THEN BEGIN ORIGMODE := LASTMODE; TEXTMODE (C80 + FONT8X8); ECON_HEADER; OFFSET := 0; FOR LL := 1 TO NUM_LIST DO BEGIN EE := LL - OFFSET; IF (POW_REQ < MAX_MIN [LL, 1]) OR (POW_REQ > MAX_MIN [LL, 2]) THEN BEGIN WRITELN (LL : 3, ' -------- -------'); FOR AA := 1 TO NUM_GEN DO BEGIN GOTOXY ( (24 + 5 * AA), (EE + 5) ); WRITE ('---'); END; GOTOXY (1, (EE + 6) ); END ELSE BEGIN MOVE_GEN; DISPATCH; WRITELN (LL : 3, ' ', COST : 8 : 2, ' ', LAMBDA : 7 : 4); CC := 1; FOR AA := 1 TO NUM_GEN DO BEGIN GOTOXY ( (24 + 5 * AA), (EE + 5) ); IF PRI_LIST [LL, (AA + 1) ] = 1 THEN BEGIN WRITE (POW_OUT [CC] : 3 : 0); CC := CC + 1; END ELSE BEGIN WRITE (' 0'); END; END; GOTOXY (1, (EE + 6) ); END; A := NUM_LIST / 40; IF ( (INT (LL / 40) ) = (LL / 40) ) AND (INT (A) <> A) THEN BEGIN WRITELN; WRITELN; WRITE ('PRESS ANY KEY TO CONTINUE...'); CHOICE := READKEY; OFFSET := OFFSET + 40; ECON_HEADER; END; END; WRITELN; WRITELN; WRITE ('PRESS ANY KEY TO CONTINUE...'); CHOICE := READKEY; TEXTMODE (ORIGMODE); END; END; CHOICE := ' '; END; {----------------------------------------------------------------------------} { } { Procedure : ABOUT; } { Last Revised : March 18, 1994 } { Purpose : About screen giving author information. } { } {----------------------------------------------------------------------------} PROCEDURE ABOUT; BEGIN WINDOW (18, 7, 62, 19); STOREALPHAWINDOW; VIDEO (INV, FALSE); WINDOWFRAME (3); CLRSCR; WRITELN (' UNITCOMM'); WRITELN (' Version ', VERSION : 2 : 1, ' - 1993, 94'); WRITELN; WRITELN (' Written by:'); WRITELN; WRITELN (' David F. Gadberry'); WRITELN (' Rose-Hulman Institute of Technology'); WRITELN (' 5500 Wabash Avenue, Box #391'); WRITELN (' Terre Haute, Indiana 47803'); WRITELN; WRITELN; WRITE (' PRESS ANY KEY TO CONTINUE...'); CHOICE := READKEY; VIDEO (LOW, FALSE); TEXTCOLOR (LIGHTGRAY); RELOADALPHAWINDOW (FALSE); WINDOW (1, 1, 80, 25); CHOICE := ' '; END; {----------------------------------------------------------------------------} { } { Procedure : MAIN } { Last Revised : April 25, 1994 } { Purpose : Ties all procedures together to solve the problem. } { } {----------------------------------------------------------------------------} BEGIN CHOICE := ' '; NF := 0; FC := 0; GETDIR (0, CFG_PATH); READ_CONFIG; PATH_NAME := DEF_PATH; FLAG1 := 0; FOR AA := 1 TO 9 DO BEGIN GEN_TIME_I [AA] := 1; LAST_STATE [AA] := 1; END; VERSION := 1.0; TEXTCOLOR (LIGHTGRAY); TEXTBACKGROUND (BLACK); WHILE CHOICE <> '9' DO BEGIN TITLE (VERSION); GOTOXY (1, 5); WRITELN ('MAIN MENU:'); WRITELN; WRITELN (' 1 - Load data files....'); WRITELN (' 2 - Create data files....'); WRITELN (' 3 - Enter initial conditions....'); WRITELN (' 4 - Perform unit commitment.'); WRITELN (' 5 - Perform economic dispatch.'); WRITELN; WRITELN; WRITELN (' 8 - About....'); WRITELN (' 9 - Exit.'); WRITELN; WRITE ('Please enter your choice: '); CHOICE := READKEY; IF CHOICE = '1' THEN LOAD_GEN_DATA; IF CHOICE = '2' THEN CREATE_DATA; IF CHOICE = '3' THEN GET_TIME; IF CHOICE = '4' THEN DYN_COMMIT; IF CHOICE = '5' THEN ECON; IF CHOICE = '8' THEN ABOUT; END; IF (PARAMSTR (1) <> 'ND') AND (PARAMSTR (1) <> 'nd') THEN BEGIN ASSIGN (DATAFILE, PATH_NAME + 'UC_DATA.TMP'); {$I-} RESET (DATAFILE); {$I+} IF IORESULT = 0 THEN ERASE (DATAFILE); END; CHDIR (CFG_PATH); CLRSCR; END.