2.2 外部プログラムの例
Nuorium Optimizer部分は別プロセスとして起動するので,外部プログラムを実装するプログラミング言語としては別プロセスを起動することができるものであれば何でも構いません.ここではC言語とJavaを用いた外部プログラムの例を示します.
ここでは,モデルのb(制約式の上限)に相当するデータを1から30まで動かして繰り返し解くという手続きを作成します.
外部プログラム例(C言語)
//
// Numerical Optimizer実行形式を別プロセスとして
// 実行する例(C言語)
//
#include <stdio.h>
#include <stdlib.h>
void write(int n, double* a, double b, double* c, const char* input);
void read(int n, int* x, double* obj, const char* output);
int main(void)
{
int i, n = 5;
double a[] = {4, 2, 3, 6, 7};
double b;
double c[] = {6, 8, 4, 3, 4};
int x[5];
double obj[1];
int ret;
for(b = 1; b <= 30; b++){
write(n, a, b, c, "data.dat"); // 入力データの作成
ret = system("knapsack.exe data.dat"); // 別プロセスとして起動
read(n, x, obj, "result.txt"); // 出力データの読み込み
printf("ret = %d, b = %f, obj = %f, x =", ret, b, *obj);
for(i = 0; i < n; i++)
printf(" %d", x[i]);
printf("\n");
}
return 0;
}
// 入力データの作成関数
void write(int n, double* a, double b, double* c, const char* input)
{
int i;
FILE* fp = fopen(input, "w");
fprintf(fp, "a=\n");
for(i = 0; i < n; i++)
fprintf(fp, "[%d] %f\n", i + 1, a[i]);
fprintf(fp, ";\nb = %f;\nc=\n", b);
for(i = 0; i < n; i++)
fprintf(fp, "[%d] %f\n", i + 1, c[i]);
fprintf(fp, ";\n");
fclose(fp);
}
// 出力データの読込関数
void read(int n, int* x, double* obj, const char* output)
{
int i;
char buf[256];
FILE* fp = fopen(output, "r");
fgets(buf, 256, fp);
sscanf(buf, "%lf", obj);
i = 0;
while(fgets(buf, 256, fp) != NULL){
sscanf(buf, "%d", x + i);
i++;
}
fclose(fp);
}外部プログラム例(Java)
//
// Numerical Optimizer実行形式を別プロセスとして実行する例(Java)
//
import java.io.*;
class exeLoopJ{
public static void main(String[] args){
int n = 5;
double[] a = {4, 2, 3, 6, 7};
double[] c = {6, 8, 4, 3, 4};
int[] x = new int[n];
double[] obj = new double[1];
for(double b = 1; b <= 30; b++){
int ret = 1;
try{
write(n, a, b, c, "data.dat"); // 入力作成
ret = execute("knapsack.exe","data.dat"); // 別プロセス起動
read(n, x, obj, "result.txt"); // 出力読み込み
}catch(IOException e){
e.printStackTrace();
}
System.out.print("ret = "+ret+", b = "+b+", obj = "+obj[0]+", x =");
for(int i = 0; i < n; i++)
System.out.print(" "+x[i]);
System.out.print("\n");
}
}
// 入力作成メソッド
static void write(int n, double[] a, double b, double[] c, String input)
throws IOException{
FileWriter fw = new FileWriter(input);
fw.write("a =\n");
for(int i = 0; i < n; i++)
fw.write("["+(i+1)+"] "+a[i]+"\n");
fw.write(";\nb = "+b+";\nc =\n");
for(int i = 0; i < n; i++)
fw.write("["+(i+1)+"] "+c[i]+"\n");
fw.write(";\n");
fw.close();
}
// 別プロセス起動メソッド
static int execute(String exe, String input) throws IOException{
ProcessBuilder pb = new ProcessBuilder(exe, input);
Process p = pb.start();
InputStream is = p.getInputStream();
while(is.read() > 0);
try{
p.waitFor();
}catch(java.lang.InterruptedException e){
e.printStackTrace();
}
return(p.exitValue());
}
// 出力読込メソッド
static void read(int n, int[] x, double[] obj, String output) throws IOException{
FileReader fr = new FileReader(output);
BufferedReader br = new BufferedReader(fr);
obj[0] = Float.valueOf(br.readLine());
for(int i = 0; i < n; i++)
x[i] = Integer.valueOf(br.readLine());
br.close();
fr.close();
}
} C言語,Javaどちらの例においてもwrite関数(メソッド)を定義して,Nuorium Optimizerへの入力データをファイルとして出力しています.Nuorium Optimizerへの入力ファイルのフォーマットについては,Nuorium
Optimizer/C++SIMPLEマニュアルをご参照ください.
C言語の例ではsystem関数を使って,Javaの例ではProcessBuilderを使ったexecuteメソッドを定義してNuorium Optimizer実行形式を別プロセスとして起動しています.この際,write関数(メソッド)で作った入力データファイルdata.datを引数として与えています.
Nuorium Optimizer実行形式は求解結果(xとobj)をresult.txtに出力します.C言語,Javaどちらの例においてもread関数(メソッド)を定義して,Nuorium Optimizerの求解結果を読み込んでいます.
上に戻る
