일부 일반 의견
요즘에는 여러 가지API는 슬롯 시스템과 상호작용하는 가장 효율적이고 우아한 방법입니다. 이는 데이터의 효과적인 통신을 허용하고 매개변수화된 슬롯 실행을 수행합니다. 이 장 전체에서는 다양한 환경에서 슬롯 실행 파일을 호출하여 슬롯의 훨씬 더 기본적인 상호 작용을 설명합니다. 이는 여전히 유용할 수 있습니다. 특정 대상 언어(예: VBA)에 사용할 수 있는 객체 지향 API가 없는 경우.
슬롯 실행 파일을 호출하는 원칙은 모든 운영 체제에 적용되지만 이 장에서는 Windows 플랫폼에 초점을 맞추는 경우가 많습니다.
Windows 환경에서 슬롯EXE를 생성할 때 직면하게 되는 흥미로운 문제 중 하나는 멀티스레딩입니다. 예방 조치를 취하지 않으면 Shell(VB 함수) 또는 CreateProcess(Win32 API 함수)를 호출하면 슬롯가 비동기적으로 실행됩니다. 즉, 슬롯가 계속 실행되는 동안 함수가 반환됩니다. 결과를 읽으려면 슬롯 작업이 완료될 때까지 기다려야 합니다. 이를 위한 기계에는 약간의 Windows 트릭이 필요하며 Visual Basic 버전 6 및 Delphi 버전 4에 대해 이 작업을 수행하는 방법을 보여주는 몇 가지 작은 예제를 구현했습니다.
해결해야 할 또 다른 문제는 슬롯에 스크래치 파일을 저장할 장소가 필요하다는 것입니다. 기본적으로 이는 현재 디렉터리이며, 윈도우 환경에서는 이 개념이 항상 명확하지는 않습니다. 이를 처리하는 좋은 방법은 슬롯 작업을 실행하기 전에 현재 드라이브와 현재 디렉터리를 모두 설정하는 것입니다. 슬롯에는 쓰기 권한이 필요하다는 점에 유의해야 합니다. 예제에서는 이를 위해 Windows TEMP 디렉터리를 사용하지만 실제 응용 프로그램에서는 지정된 디렉터리를 사용할 수 있습니다. Windows TEMP 디렉터리는 API 함수 GetTempPath를 호출하여 찾습니다.
슬롯 아키텍처
슬롯 자체는 콘솔 모드 애플리케이션입니다. 실제로 이는 단일 프로그램이 아니라 슬롯 언어 컴파일러(GAMSCMEX) 또는 솔버 중 하나를 실행하는 드라이버 프로그램(Windows의 경우 슬롯EXE, 그렇지 않으면 슬롯)입니다. 단일 해석 문이 있는 모델의 경우 슬롯EXE는 먼저 GAMSCMEX를 호출하여 슬롯 모델을 컴파일합니다. 그런 다음 GAMSCMEX는 컴파일러에서 생성된 내부 코드 실행을 시작합니다. SOLVE 문에 속한 명령에 도달하자마자 모델 인스턴스가 생성되고 GAMSCMEX가 종료됩니다. 그런 다음 슬롯EXE는 모델을 해석할 수 있는 솔버를 생성합니다. 솔버가 완료되자마자 슬롯EXE는 GAMSCMEX를 다시 실행하여 솔루션을 읽고 명령 실행을 계속할 수 있습니다.
VBA에서 슬롯 생성
VBA(Visual Basic for Application)는 대부분의 Microsoft Office 응용 프로그램에 내장된 프로그래밍 언어입니다. 엑셀과 액세스. VBA 프로그램에는 파일에서 가져올 수 있는 모듈이 포함될 수 있습니다. 즉, VBA 편집기에서 메뉴 "파일"→"파일 가져오기"를 선택할 수 있습니다. 슬롯 배포판에는 다음에서 찾을 수 있는 일부 VBA 모듈이 포함되어 있습니다.
<슬롯 시스템 디렉토리>\apifiles\VBA\api, 예: "C:\슬롯\win64\24.5\apifiles\VBA\api"
- 주의
- 문제를 방지하려면 최신 버전의 모듈, 즉 최신 슬롯 릴리스에 있는 모듈을 사용하는 것이 좋습니다.
예를 들어, 다음 모듈을 찾을 수 있습니다:
- gamsglobals.bas: 다른 모듈에서 사용되는 전역 상수
- gdxvba.bas: 슬롯 데이터 교환 객체
- idxvba.bas: 슬롯 IDX 개체
-
optvba.bas: 슬롯 옵션 개체
자세한 내용은 참조전문가 수준 API. API를 사용하는 VBA 프로그램은 다음에서 찾을 수 있습니다.
<슬롯 시스템 디렉터리>\apifiles\VBA, 예: "C:\슬롯\win64\24.5\apifiles\VBA"
모델은 슬롯 Studio -> 슬롯 -> 모델 라이브러리 탐색기 -> 슬롯 데이터 유틸리티 모델을 통해서도 검색할 수 있습니다.
Excel에서 슬롯 생성
Excel에서 슬롯를 호출하려면 단순한 작업보다 더 많은 작업이 필요합니다.Microsoft Excel과의 데이터 교환. Excel에서 슬롯를 호출하는 애플리케이션은 다음을 수행해야 합니다.
- 슬롯 시스템 디렉토리를 찾고 이에 따라 시스템 경로를 조정하십시오.
- 슬롯 모델을 임시 디렉터리(기본적으로 Windows의 임시 디렉터리)에 복사합니다.
- 스프레드시트에서 모델 데이터를 슬롯 판독 가능 형식(gdx)으로 추출
- 슬롯 실행(모델 해결, 슬루션을 다시 gdx 파일에 쓰기)
- 모델 결과를 gdx 파일에서 스프레드시트로 다시 가져오기
- 스프레드시트 업데이트(그래픽, 표)
사용 중응용프로그램용 VisualBasic(VBA)이것은 몇 줄의 코드로 구현할 수 있습니다:
하위 해결()
Dim WorkDir As String
WorkDir = TempDir()
ClearSolution 호출
If (AddGAMSPath() 아님) 그러면 ' gdxcclib64.dll 및 슬롯exe를 찾는 데 필요함
구독 종료
끝나는 경우
ExportGDXFile(WorkDir) 호출
WriteGAMSModel(WorkDir & "portfolio.gms") 호출
RunGAMS 호출(WorkDir & "portfolio.gms", WorkDir)
ReadListing(WorkDir & "portfolio.lst") 호출
ImportGDXFile(WorkDir) 호출
Sub 종료
자세한 내용은 아래 예제의 VBA 부분을 확인하세요.
간단한 예
이 매우 간단한 예는 Excel 스프레드시트에서 슬롯를 호출하는 방법을 보여줍니다. "예제 스프레드시트"에는 슬롯가 c:/tmp에 저장된 trnsport.gms 모델을 실행하게 하는 버튼이 있습니다. 데이터 교환이 없습니다.
더 완전한 애플리케이션은 슬롯 모델에 대한 포함 파일을 작성하고 실행이 완료되면 결과와 함께 쉼표로 구분된 파일을 가져올 것입니다. 이러한 완전한 애플리케이션의 예는 다음에서 설명됩니다./mccarl/excelgams.pdf.
스도쿠 예
이 스프레드시트는 GDX 파일을 사용하여 정보를 교환하고 CPLEX를 사용하여 25x25 스도쿠 문제를 해결하는 완전한 예입니다. 슬롯 배포판과 함께 제공됩니다.apifiles/VBA/sudoku.xlsm. 스프레드시트를 실행하려면 슬롯/CPLEX 라이선스가 필요합니다. MIP 모델은 매우 쉽게 해결됩니다. 해결 방법은 사전 해결 단계에서 찾을 수 있습니다.
참고: 이 스프레드시트가 제대로 작동하려면 배포판 22.6 이하가 필요합니다.
문제
해결책
효율적인 국경의 예
이 예는 일련의 NLP를 해결하여 포트폴리오 최적화 문제의 효율적인 경계를 만듭니다. 슬롯 배포판과 함께 제공됩니다.apifiles/VBA/portfolio.xlsm.
참고: 이 스프레드시트가 제대로 작동하려면 배포판 22.6 이하가 필요합니다.
C에서 슬롯 생성
아래 예는 C 프로그램에서 슬롯를 호출하는 최소 버전을 보여줍니다.
#include <stdio.h>
int 메인(
intargc,
문자** argv)
{
시스템("슬롯 trnsport lo=2");
반환0;
}
int main(int argc, char *argv[])
보시다시피 슬롯 실행 파일 슬롯exe는 system()의 간단한 호출을 통해 호출됩니다. 추가 명령줄 매개변수lo=2로그 파일이 화면(기본값)에 기록되지 않고 파일에 기록됨을 나타냅니다.모델.로그.
응용 프로그램에서 일부 데이터를 생성하려는 경우(예: 매개변수수요), 애플리케이션에서 작성한 포함 파일을 사용할 수 있습니다. 결과는 PUT 파일에서 읽을 수 있습니다. 이제 슬롯 파일은 다음과 같습니다.
세트
i 통조림 공장 / 시애틀, 샌디에고 /
j 마켓 / 뉴욕, 시카고, 토피카 / ;
매개변수
a(i) 경우에 따라 공장 i의 생산 능력
/시애틀 350
샌디에이고 600 /
b(j) 다음과 같은 경우 시장 j의 수요
/
$include 수요.inc
/ ;
테이블 d(i,j) 거리(천 마일)
뉴욕 시카고 토피카
시애틀 2.5 1.7 1.8
샌디에고 2.5 1.8 1.4 ;
스칼라 f 운임(1,000마일당 케이스당 달러) /90/ ;
매개변수 c(i,j) 운송 비용(케이스당 수천 달러) ;
c(i,j) = f * d(i,j) / 1000 ;
변수
x(i,j) 케이스의 배송 수량
z 총 운송 비용(단위: 수천 달러);
양수 변수 x ;
방정식
비용 정의 목적 함수
공급(i) 공장 i의 공급 제한을 준수합니다.
수요(j)는 시장 j의 수요를 충족시킵니다.
비용 .. z =e= sum((i,j), c(i,j)*x(i,j)) ;
공급(i) .. sum(j, x(i,j)) =l= a(i) ;
수요(j) .. sum(i, x(i,j)) =g= b(j) ;
모델 전송 /all/ ;
z 를 최소화하는 lp를 사용하여 전송을 해결합니다.
x.l, x.m 표시 ;
파일 fout /results.txt/;
fout를 넣어;
루프((i,j),
x.l(i,j):17:5/를 입력하세요.
);
닫아두다;해당 C 프로그램은 다음과 같습니다:
#include <stdio.h>
#M 2 정의
#N 정의 3
문자* 거리[M] ="시애틀", "샌디에고"};
문자* 도시[N] ="뉴욕","시카고", "토피카"};
더블수요[N] = 325.0, 300.0, 275.0 ;
더블선박[M][N];
int 메인(
intargc,
문자** argv)
{
파일 *f;
inti,j;
f = fopen("demand.inc","wt");
if(f == NULL)
오류("fopen");
출구(1);
}
for(i=0; i<N; ++i)
fprintf(f,"%s %g\n",도시[i],수요[i]);
fclose(f);
시스템("슬롯 trnsport lo=2");
f = fopen("results.txt","rt");
if(f == NULL)
오류("fopen");
출구(1);
}
for(i=0; i<M; ++i)
for(j=0; j<N; ++j)
fscanf(f,"%lg",&(배[i][j]));
fclose(f);
for(i=0; i<M; ++i)
for(j=0; j<N; ++j)
프린트프("%s->%s %g\n",거리[i], 도시[j], 선박[i][j]);
반환0;
}
Visual Basic에서 슬롯 생성
이 예는 VB 프로그램에서 슬롯를 호출하는 방법을 보여줍니다.
실행되면 슬롯 모델을 지정할 수 있고 다른 명령줄 옵션이 가능한 간단한 창이 나타납니다. [슬롯] 버튼을 누르면 모델이 실행됩니다.
일반 디스플레이를 사용하면 콘솔 창이 열립니다. 완료 시 프로세스 창 닫기 확인란을 선택한 경우 실행이 끝나면 이 콘솔 창이 자동으로 닫힙니다. 최소화는 창을 표시하지 않지만 작업 표시줄에 아이콘이 나타납니다. 작업 시간이 오래 걸리는 경우 사용자는 이 아이콘을 클릭하여 콘솔 창을 표시할 수 있습니다. 숨김 옵션을 사용하면 슬롯 관련 창이나 아이콘이 표시되지 않습니다.
참고: 이 프로그램이 작동하려면 슬롯 시스템 디렉토리가 경로에 있어야 합니다. 그렇지 않은 경우 -1 오류 코드가 반환됩니다.
주요 프로그램은 아래에 첨부되어 있습니다.
속성 VB_Name = "vbGAMS"
옵션 명시적
' ------------------------------
' 모듈 이름: VBGams
' 파일: 슬롯bas
' 버전: 1.1
'
'
' 기능:
' VB_Gams32 - 프로세스 디렉터리, 매개변수 파일, 콘솔을 설정하고 관리합니다.
' 게임 컴파일러와 솔버의 루핑.
'
' --------
' 함수 VB_Gams32
' 프로세스 디렉터리, 매개변수 파일, 콘솔을 설정하고 관리합니다.
' 게임 컴파일러와 솔버의 루핑.
'
' 매개변수
' sParams 문자열 명령줄 인수
' nDisplayMode 정수 GAMS_NORMAL, GAMS_MIN 또는 GAMS_HIDDEN
' bCloseWin Boolean 게임 작업 완료 시 콘솔을 닫습니다.
'
' 반품
' 1000 누락된 입력 문자열
' 2000 16비트 생성 실패
' -또는-
' nCmexRC + 100 * nVB_GamsRC
'
' nCmexRC : 슬롯 컴파일/실행 모듈의 마지막 실행에서 반환된 코드
' (DOS/Win XX용)
' 0 : 정상복귀
' 1 : 해결이 다음입니다(발생하지 않아야 함)
' 2 : 컴파일 오류
' 3 : 실행 오류
' 4 : 시스템 제한
' 5 : 파일 오류
' 6 : 매개변수 오류
' 7 : 라이센스 오류
' 8 : 슬롯 시스템 오류
' 9 : 슬롯를 시작할 수 없습니다.
'
' nVB_GamsRC: vbGams 특정 오류 코드
' 0 : 정상복귀
' 1 : 프로세스 디렉토리를 생성할 수 없습니다.
' 2 : gamsparm 스크립트를 실행할 수 없습니다.
' 3 : 매개변수 스크래치 파일에 사용자 입력을 추가할 수 없습니다.
' 4 : gamscmex.exe를 생성할 수 없습니다.
' 5: "gamsnext" 스크립트를 종료할 수 없습니다.
' 6 : 프로세스 디렉터리를 삭제할 수 없습니다.
'
공개 함수 VB_Gams32(sParams As String, nDisplayMode As Integer, _
bCloseWin As Boolean) 오랫동안
긴 lAlloc, 긴 lRetAPI
nSpawn을 길게 어둡게
If nDisplayMode = GAMS_NORMAL 그러면 ' 콘솔 할당
lAlloc = AllocConsole()
Dim sConTitle As String, hWnd as Long, nTop as Long, nLeft as Long
sConTitle = "VB 슬롯 "
lAlloc = SetConsoleTitle(sConTitle) ' 찾을 수 있도록
' 콘솔 창을 계속 열어 두려면 콘솔 창 위치를 변경해야 합니다.
bCloseWin이 아니면
Sleep(100) 호출 ' 콘솔이 나타날 수 있도록 필요함
hWnd = FindWindow(vbNullString, sConTitle)
If hWnd <> 0 Then
n상단 = 20
n왼쪽 = 20
lAlloc = SetWindowPos(hWnd, HWND_BOTTOM, nTop, nLeft, 0, 0, SWP_NOZORDER + SWP_NOSIZE)
CloseHandle(hWnd) 호출
다음 경우 종료
끝나는 경우
끝나는 경우
nSpawn = Spawn("슬롯exe " & sParams, nDisplayMode)
nDisplayMode = GAMS_NORMAL이면
bCloseWin이 아니면
삐 소리
MsgBox "콘솔을 닫으려면 여기를 클릭하십시오.", vbOKOnly + vbInformation, "VB 슬롯"
끝나는 경우
lAlloc = FreeConsole()
끝나는 경우
VB_Gams32 = nSpawn
ShowWait 거짓
기능 종료
델파이에서 슬롯 생성
이것은 이전 단락에서 설명한 Visual Basic 응용 프로그램과 유사한 기능을 가진 Delphi 4 응용 프로그램입니다.
참고: 이 프로그램이 작동하려면 슬롯 시스템 디렉토리가 경로에 있어야 합니다. 그렇지 않은 경우 오류 코드 -1이 반환됩니다. 주요 코드는 아래에 첨부되어 있습니다.
유닛 메인;
인터페이스
사용
Windows, 메시지, SysUtils, 클래스, 그래픽, 컨트롤, 양식, 대화 상자,
StdCtrls;
유형
TMainForm = 클래스(TForm)
파일편집: TEdit;
FileOpenDialog: TOpenDialog;
파일 라벨: TLabel;
탐색버튼: TButton;
CmdLineOptionsEdit: TEdit;
CmdLineLabel: TLabel;
실행버튼: TButton;
반환 라벨: TLabel;
콘솔ComboBox: TComboBox;
콘솔 라벨: TLabel;
CloseConsole버튼: TButton;
BrowseButtonClick(Sender: TObject) 절차;
Procedure RunButtonClick(Sender: TObject);
Procedure FormCreate(Sender: TObject);
CloseConsoleButtonClick(Sender: TObject) 절차;
비공개
비공개 선언
함수 GSExec(const ProgName,ProgParams: 문자열;
const wShowWindow : 단어;
var rc: 정수): 정수;
함수 ExecuteGAMS(
const ProgName,ProgParams: 문자열;
wShowWindow : 단어; SW_NORMAL, SW_HIDE 또는 SW_SHOWMINIMIZED
자동 닫기: 부울; 마지막에 콘솔을 닫습니다
var rc: 정수): 정수;
공개
공개 선언
끝;
var
메인폼: TMainForm;
구현
$R *.DFM
함수 TMainForm.GSExec(const ProgName,ProgParams: 문자열;
const wShowWindow : 단어;
var rc: 정수): 정수;
프로그램 실행:
결과: 프로그램 시작에 대한 오류 코드
rc : 프로그램에서 반환된 오류 코드
var
명령어: 문자열;
프로세스정보 : TProcessInformation;
StartupInfo : TStartupInfo;
종료 코드 : dword;
시작
// 시작 정보를의 정보와 동일하게 초기화합니다.
// 애플리케이션 호출. 이것은 많은 것을 초기화하는 것보다 쉽습니다.
// 개별 시작 정보 필드이며 대부분 괜찮습니다.
//건.
GetStartupInfo(StartupInfo);
// StartupInfo.wShowWindow는 호출된 애플리케이션이 있는지 확인합니다.
// 처음에는 정상, 최대화, 최소화 또는 일부가 표시됩니다.
// 기타 미묘한 변형
StartupInfo.wShowWindow := wShowWindow;
StartupInfo.dwFlags := StartUpInfo.dwFlags 또는 STARTF_USESHOWWINDOW;
명령:= ProgName + ' ' + ProgParams;
만약 CreateProcess(가 아닌 경우
없음, 애플리케이션 이름
PChar(명령), lpCommandLine
없음, lpProcessAttributes
없음, lpThreadAttribute
false, bInheritedHandles
NORMAL_PRIORITY_CLASS, dwCreationFlags
없음, lpEnvironment
없음, lpCurrentDirectory
시작 정보, lpStartupInfo
프로세스정보 lpProcessInformation
)
그런 다음
시작
rc := 0;
결과 := GetLastError 실행 실패
끝
그밖에
시작
프로세스 정보 포함
시작하세요
WaitForSingleObject(hProcess,INFINITE);
GetExitCodeProcess(hProcess,exitcode);
CloseHandle(hThread);
CloseHandle(hProcess);
끝;
Rc := 종료 코드;
결과 := 0;
끝;
끝;
함수 TMainform.ExecuteGAMS(
const ProgName,ProgParams: 문자열;
wShowWindow : 단어; SW_NORMAL, SW_HIDE 또는 SW_SHOWMINIMIZED
자동 닫기: 부울; 마지막에 콘솔을 닫습니다
var rc: 정수): 정수;
var ok : BOOL;
시작
자동 닫기가 시작되면
이것은 쉬운 것입니다
결과 := GSExec(ProgName, ProgParams, wShowWindow, rc);
종료;
끝;
사용자가 창을 닫도록 하고 싶은 경우,
우리는 콘솔을 직접 할당해야 합니다
ok := AllocConsole();
결과 := GSExec(ProgName, ProgParams, wShowWindow, rc);
콘솔을 사용한 경우 제거하려면 버튼을 표시하세요
if (ok) 그럼
CloseConsoleButton.Enabled := true;
끝;
절차 CdTemp;
Windows 임시 디렉토리로 CD
const maxpath=260;
var 경로 : 문자열;
시작
setlength(경로,최대 경로);
GetTempPath(maxpath,Pchar(경로));
경로 := 확장파일이름(경로); 확실히 하기 위해
ChDir(경로); 드라이브도 변경됩니다
끝;
절차 TMainForm.BrowseButtonClick(Sender: TObject);
시작
팝업 파일 열기 대화상자
if FileOpenDialog.Execute then
FileEdit.text := FileOpenDialog.Filename;
끝;
TMainForm.RunButtonClick(Sender: TObject) 절차;
var
rc : 정수; 슬롯EXE의 반환 코드
결과: 정수; GsExe의 반환 코드
매개변수: 문자열; 슬롯EXE의 명령줄 매개변수
s : 문자열; 오류 메시지 조립용
wShowWindow: 단어;
자동 닫기: 부울;
시작
현재 디렉터리 설정
CdTemp;
편집 컨트롤에서 명령줄 매개변수 추출
파일 이름에 공백이 있을 수 있으므로 따옴표를 추가하세요
params := '"' + FileEdit.Text + '" ' + CmdLineOptionsEdit.Text;
wShowWindow 정보 얻기
case ConsoleComboBox.ItemIndex of
0, 1 : wShowWindow := SW_NORMAL;
2 : wShowWindow := SW_SHOWMINIMIZED;
3 : wShowWindow := SW_HIDE;
끝;
자동 닫기 := 아님 (ConsoleComboBox.ItemIndex = 1);
사용자에게 슬롯가 실행 중임을 알립니다.
ReturnLabel.Caption := '슬롯 실행 중...';
ReturnLabel.Font.Color := ClGreen;
새로고침;
슬롯EXE 실행
결과 := ExecuteGAMS('슬롯exe', params, wShowWindow, autoClose, rc);
결과 확인
if (결과 <> 0) 다음 시작
str(결과,s);
ReturnLabel.Caption := '실행 실패: 결과 = '+s;
ReturnLabel.Font.Color := ClRed;
다른 경우 종료(rc <> 0) 다음 시작
str(rc,s);
ReturnLabel.Caption := '슬롯 실패: rc = '+s;
ReturnLabel.Font.Color := ClRed;
끝나고 시작
ReturnLabel.Caption := '확인';
ReturnLabel.Font.Color := ClBlack;
끝;
끝;
절차 TMainForm.FormCreate(Sender: TObject);
시작
ConsoleComboBox.ItemIndex := 0;
끝;
TMainForm.CloseConsoleButtonClick(Sender: TObject) 절차;
시작
FreeConsole();
CloseConsoleButton.Enabled := false;
끝;
끝.
Visual C++에서 슬롯 생성
"이 예"에서는 간단한 Visual C++ 응용프로그램에서 슬롯를 호출합니다.
추가적인 우려는 슬롯 화면 출력을 가로채서 여러 줄의 편집 컨트롤에 쓸 수 있다는 것입니다. 사용된 기술에 대한 자세한 내용은 Microsoft 간행물: [HOWTO: 리디렉션된 표준 핸들을 사용하여 콘솔 프로세스 생성(Q190351)](https://learn.microsoft.com/en-us/windows/win32/procthread/setting-window-properties-using-startupinfo)(Microsoft 기술 자료).
C#에서 슬롯 생성
아래는 간단한 예입니다:
사용 중시스템.진단;
무효RunGamsModel()
{
프로세스 p =신규프로세스();
p.StartInfo.FileName = gamsexe;
p.StartInfo.WorkingDirectory = 임시 디렉터리;
p.StartInfo.Arguments ="\""+ 모델 이름 +"\" LO=0 --runid="+runid;
p.시작();
p.WaitForExit();
}
여기에 형성된 명령줄은 다음과 같습니다슬롯 모델 이름 LO=0 –runid=xxx. 옵션LO(logoption)은 로그 쓰기를 비활성화하며 옵션은–runid매개변수를 슬롯 모델에 전달합니다(모델 내부에서 다음을 통해 액세스할 수 있습니다.%runid%).
자바에서 슬롯 생성
Java에는 클래스가 있습니다.런타임Exe() 메소드를 사용하여 프로세스 생성을 구현합니다. 이는 응용 프로그램에서 사용하기에는 매우 간단하지만 애플릿에서는 기본 보안 설정으로 인해 이 작업이 일반적으로 허용되지 않습니다. 로컬 드라이브에서 애플릿을 로드하거나 서명된 애플릿을 사용하여 문제를 해결할 수 있습니다. 마찬가지로 Java 클래스가 데이터베이스 내부에서 로드되는 경우 이 작업에는 추가 권한이 필요할 수 있습니다. 예를 보려면 Java 저장 프로시저를 사용하여 Oracle에서 슬롯를 호출하는 이전 섹션을 참조하세요. 관련 코드는 다음과 같습니다.
가져오기java.io.파일;
클래스RunGAMS
System.out.println("시작");
문자열[] cmdArray =신규문자열[5];
cmdArray[0] ="<경로/대상/슬롯>"+ 파일.구분자 +"감";
cmdArray[1] ="<경로>"+ 파일.구분자 +"trnsport.gms";
cmdArray[2] ="WDIR=<PATH>"+ 파일.구분자 +"TMP";
cmdArray[3] ="SCRDIR=<경로>"+ 파일.구분자 +"TMP";
cmdArray[4] ="LO=2";
시도해 보세요{
프로세스 p = Runtime.getRuntime().exec(cmdArray);
p.waitFor();
}
잡기(java.io.IOException e )
{
System.err.println(">>>>"+ e.getMessage() );
e.printStackTrace();
}
잡기(InterruptedException e )
{
System.err.println(">>>>"+ e.getMessage() );
e.printStackTrace();
}
System.out.println("완료");
}
}
다음은 모델에 긴 화면 로그가 있는 경우(버퍼가 채워지고 실행이 잠김) 문제를 방지하는 또 다른 예입니다. 이는 슬롯가 위와 같이 파일에 로그를 기록하지 않으면 발생할 수 있습니다. 이 예는의 제안을 기반으로 합니다.에드슨 발레.
가져오기java.io.파일;
가져오기java.io.BufferedReader;
가져오기java.io.InputStreamReader;
클래스RunGAMS
System.out.println("시작");
문자열[] cmdArray =신규문자열[5];
cmdArray[0] ="<경로/대상/슬롯>"+ 파일.구분자 +"슬롯exe";
cmdArray[1] ="<경로>"+ 파일.구분자 +"trnsport.gms";
cmdArray[2] ="<경로>"+ 파일.구분자 +"tmp";
cmdArray[3] ="LO=3";
시도해 보세요{
프로세스 p = Runtime.getRuntime().exec(cmdArray);
BufferedReader stdInput =신규버퍼 리더(신규InputStreamReader(p.getInputStream()));
문자열 s =널;
그동안((s=stdInput.readLine()) !=널){
System.out.println(s);
}
p.waitFor();
}
잡기(java.io.IOException e )
{
System.err.println(">>>>"+ e.getMessage() );
e.printStackTrace();
}
잡기(InterruptedException e )
{
System.err.println(">>>>"+ e.getMessage() );
e.printStackTrace();
}
System.out.println("완료");
}
}
Java 기반 서버 환경의 슬롯 사용 예는 Alexander Sokolov를 참조하세요.발트해의 영양염류 감소를 위한 의사결정지원시스템의 정보환경 및 아키텍처, 스톡홀름 대학교 시스템 생태학과.
웹 서버에서 슬롯 생성
웹 기반 씬 클라이언트 아키텍처를 사용하여 원격으로 슬롯를 실행하려면 슬롯가 웹 서버 또는 HTTP 서버에서 직접 또는 간접적으로 실행되어야 합니다. 이를 수행하는 간단한 방법은 CGI 프로세스를 이용하는 것입니다.공통 게이트웨이 인터페이스(CGI) 프로그램은 C, Perl 또는 Delphi와 같은 다양한 언어로 작성될 수 있습니다. CGI는 상대적으로 느립니다. 가장 단순한 상호작용이라도 프로세스를 시작해야 하기 때문입니다. 대안은 다음과 같은 CGI 확장 형식으로 존재합니다.빠른CGI또는 DLL 또는 공유 라이브러리를 사용합니다. CGI 스크립트의 기본 알고리즘은 다음과 같습니다.
- 고유한 디렉토리를 생성하고 해당 디렉토리에 CD를 넣으세요.
- 사용자 양식에서 정보를 가져와 슬롯 판독 가능 파일로 저장합니다.
- 슬롯를 실행하여 화면에 로그를 쓰지 않도록 하세요(예: LO=2(파일에 로그) 또는 LO=3(stdout에 로그) 옵션 사용).
- 모델이 PUT 문을 사용하여 텍스트 파일에 솔루션 정보를 쓰도록 합니다.
- 솔루션을 읽고 형식화된 HTML을 생성하여 사용자에게 다시 보냅니다.
- 임시 파일 및 디렉터리를 제거합니다.
그래픽을 표시해야 할 때(파일을 어딘가에 저장하고 잠시 후 삭제해야 함), 작업을 완료하는 데 오랜 시간이 걸릴 때(나중에 사용자가 결과를 선택할 수 있는 기능을 추가해야 함) 또는 서버 리소스가 고갈될 수 있는 경우(예: 많은 수의 동시 사용자 또는 대형 모델로 인해) 합병증이 발생합니다.
위 목록에서 중요한 복잡한 문제는 완료하는 데 더 많은 시간이 걸리는 작업입니다. 웹 서버는 짧은 시간 내에 사용자에게 응답하기를 원하며 작업에 오랜 시간이 걸리면 시간 초과 오류가 발생합니다. 해결책은 대기열 기반 접근 방식을 사용하는 것입니다. 사용 가능한 실제 구현은 다음과 같습니다.NEOS 서버- NEOS에 대한 슬롯 인터페이스도 있습니다:KESTREL - NEOS 서버에서 원격 솔버 실행.
PHP에서 슬롯 생성
최소한의 예
index.html
<html>
<본문>
<form action="calling_gams.php" method="post">
f = <select name="f">로 운송 문제 해결
<옵션>70</옵션>
<옵션>80</옵션>
<옵션>90</옵션>
<옵션>100</옵션>
</select>
<input type="submit" value="슬롯 호출"/>
</form>
</body>
</html>
calling_gams.php
<?php
$f = $_POST['f'];
$모델파일 ='trnsport_php.gms';
$city = 배열('뉴욕','시카고', '토페카');
$수요 = 배열(325.0, 300.0, 275.0);
$fh = fopen('./demand.inc', 'w+');
for($i=0; $i<count($city); $i++)
fwrite($fh, $city[$i]." ".$수요[$i]."\n");
}
fclose($fh);
$fh = fopen('./f.inc', 'w+');
fwrite($fh, $f);
fclose($fh);
시스템('</path/to/슬롯>/슬롯 '.$모델파일.' lo=2');
$fh = fopen('./results.txt', 'r');
에코'<p><b>'의 결과.$모델파일.' (f='.$f.') :</b></p>';
그동안(!feof($fh))
$line = fgets($fh);
에코'<p>'.$line.'</p>';
}
fclose($fh);
?>
trnsport_php.gms
세트
i 통조림 공장 / 시애틀, 샌디에고 /
j 마켓 / 뉴욕, 시카고, 토피카 / ;
매개변수
a(i) 경우에 따라 공장 i의 생산 능력
/시애틀 350
샌디에이고 600 /
b(j) 다음과 같은 경우 시장 j의 수요
/
$include 수요.inc
/ ;
테이블 d(i,j) 거리(천 마일)
뉴욕 시카고 토피카
시애틀 2.5 1.7 1.8
샌디에고 2.5 1.8 1.4 ;
스칼라 f 화물(1,000마일당 케이스당 달러) /
$include f.inc
/ ;
매개변수 c(i,j) 운송 비용(케이스당 수천 달러) ;
c(i,j) = f * d(i,j) / 1000 ;
변수
x(i,j) 케이스의 배송 수량
z 총 운송 비용(단위: 수천 달러);
양수 변수 x ;
방정식
비용 정의 목적 함수
공급(i) 공장 i의 공급 제한을 준수합니다.
수요(j)는 시장 j의 수요를 충족시킵니다.
비용 .. z =e= sum((i,j), c(i,j)*x(i,j)) ;
공급(i) .. sum(j, x(i,j)) =l= a(i) ;
수요(j) .. sum(i, x(i,j)) =g= b(j) ;
모델 전송 /all/ ;
z 를 최소화하는 lp를 사용하여 전송을 해결합니다.
x.l, x.m 표시 ;
파일 fout /results.txt/;
fout를 넣어;
루프((i,j),
put i.tl:0 '->' j.tl:0 ': ' x.l(i,j)/;
);
'비용: 'z.l/;
닫아두다;