首先需要安裝Cplex軟件,我安裝的版本是cplex_studio122.win-x86-32.exe
專業從事成都網站設計、成都網站制作,高端網站制作設計,微信平臺小程序開發,網站推廣的成都做網站的公司。優秀技術團隊竭力真誠服務,采用HTML5+CSS3前端渲染技術,自適應網站建設,讓網站在手機、平板、PC、微信下都能呈現。建站過程建立專項小組,與您實時在線互動,隨時提供解決方案,暢聊想法和感受。
詳解Java如何調用Cplex
2
下圖安裝后打開的Cplex自帶的IDE,看上去跟Eclipse差不多。
詳解Java如何調用Cplex
在Cplex的安裝目錄下有許多值得我們學習的東西,還有一些examples,可供我們參考。
詳解Java如何調用Cplex
我是在Eclipse中使用Java調用Cplex,所以先把一些Cplex依賴加上。
運行依賴:cplex.jar(在..\cplex\lib目錄下找到)和cplex122.dll(在..\cplex\bin目錄下找到)。將cplex.jar加到工程的Build Path中。
詳解Java如何調用Cplex
cplex122.dll可以設置到運行時的環境中(VM arguments),或者添加到項目的Native library location。
詳解Java如何調用Cplex
接下來我們求解一個具體的線性規劃問題。
詳解Java如何調用Cplex
例如,我們求解下面這樣一個線性規劃問題:
Maximize x1 + 2x2 + 3x3
subject to
-x1 + x2 + x3 ≦20
x1 - 3x2 + x3 ≦30
with these bounds
0 ≦x1 ≦40
0 ≦x2 ≦+∞
0≦ x3≦ +∞
先創建一個IloCplex對象,它是用來創建所有建模對象所需要的模型。此時會拋出一個異常:IloException,需要try\catch。
代碼如下:static public class Application {
static public main(String[] args) {
try {
IloCplex cplex = new IloCplex();
// create model and solve it
} catch (IloException e) {
System.err.println("Concert exception caught: " + e);
}
}
}
定義決策變量:double[] lb = {0.0, 0.0, 0.0};
double[] ub = {40.0, Double.MAX_VALUE, Double.MAX_VALUE};
IloNumVar[] x = cplex.numVarArray(3, lb, ub);
定義目標函數:
IloNumExpr expr = cplex.sum(x[0], cplex.prod(2.0, x[1]),cplex.prod(3.0, x[2]));
cplex.addMaximize(expr);
其中這個地方有許多寫法,大家在使用的時候可以注意一下。
定義決策的約束條件:cplex.addLe(cplex.sum(cplex.negative(x[0]), x[1], x[2]), 20);cplex.addLe(cplex.sum(cplex.prod(1, x[0]), cplex.prod(-3, x[1]),cplex.prod(1, x[2])), 30);
最后解決模型問題:if(cplex.solve()){....}
如果solve()返回true的話,我們可以獲取一些信息,例如問題的解決狀態、獲取方案的目標值、獲取數組中的所有決策變量的解值。
cplex.getStatus()返回值類型:Error、Unknown、Feasible、Bounded、Optimal、Infeasible、Unbouded、InfeasibleorUnbounded。
獲取方案的目標值:double objval = cplex.getObjValue();獲取數組中的所有決策變量的解值:double[] xval = cplex.getValues(x);
ConstrainedMax?年代這么久遠的函數,5.0版就淘汰了。我不得已查了4.0的幫助。發現你的代碼有兩點錯誤。
第一,ConstrainedMax的用法應該是ConstrainedMax[f, {inequalities}, {x, y, ... }],并沒有{x1-0,x2-0,x3-0}一項。所以應改作ConstrainedMax[3 x1 + 2 x2 + 2.9 x3, {8 x1 + 2 x2 + 10 x3 -300, 10 x1 + 5 x2 + 8 x3 -400, 2 x1 + 13 x2 + 10 x3 -420}, {x1, x2, x3}]。
第二,即使這樣改了,也不能得到結果,因為ConstrainedMax默認所有變量都是非負的。但這道題的結果實際算出來是負的。
所以,建議就不要用ConstrainedMax了。如果你用的是5.0以上的版本,可以用:
NMaximize[{3x1 + 2x2 + 2.9x3, {8x1 + 2x2 + 10x3 -300, 10x1 + 5x2 + 8x3 -400, 2x1 + 13x2 + 10x3 -420}}, {x1, x2, x3}]
結果是:
{-135.267, {x1 - -22.5333, x2 - -23.2, x3 - -7.33333}}
如果你用的是4.0以下的版本,那就建議你下載一個5.0以上的版本,然后還是用:
NMaximize[{3x1 + 2x2 + 2.9x3, {8x1 + 2x2 + 10x3 -300, 10x1 + 5x2 + 8x3 -400, 2x1 + 13x2 + 10x3 -420}}, {x1, x2, x3}]
因為4.0以下的版本線性規劃的函數都只認非負數。
#include stdio.h
#include stdlib.h
#define MAX 100
#define STP 100
int stop=1; //迭代記數變量
int status; //iterative迭代返回值:1唯一最優,0無界解,-1無窮多最優解 -2迭代超過限制次數
int step=1; //目前階段
double a[MAX][MAX],b[MAX],c[MAX],temp_c[MAX],max=0; //方程組相關系數
int num_x; //變量個數
int num_st; //約束方程數
int num_ar=0; //人工變量個數
int arti[MAX]; //人工變量下標
int base[MAX]; //基變量下標
int ma_mi; //1為求最大值,2為求最小值
void create(); //建立方程組
void iterative(); //單純型法迭代
void output(); //輸出結果
void banner(); //打印程序標題
void exchange(); //交換兩階段價值系數
void show(); //輸出方程組
void main() {
int i,j,k;
banner();
create();
//保存原價值系數,轉換為第一階段價值系數
for(i=1;i=num_x;i++) {
k=0;
for(j=1;j=num_ar;j++) if(i==arti[j]) k=1;
if(k==1) temp_c=-1;
else temp_c=0;
}
exchange(c,temp_c);
printf("\n\n第一階段問題為:\n\n");
show();
step++;
printf("\n\n按回車開始第一階段迭代");
getchar();
getchar();
iterative();
if(status==-2) {
puts("迭代超過限制次數強行終止!\n");
puts("\n按回車結束");
getchar();
exit(0);
}
output();
if(max!=0) {
puts("\n\n原問題無可行解。\n");
puts("\n按回車結束");
getchar();
exit(0);
}
//轉換為第二階段價值系數
exchange(c,temp_c);
//把人工變量列全設為0
for(i=1;i=num_ar;i++) {
c[arti]=0;
for(j=1;j=num_st;j++) a[j][arti]=0;
}
puts("\n\n第二階段問題為:\n\n");
show();
puts("\n\n按回車開始第二階段迭代");
getchar();
iterative();
switch(status) {
case 1:
output();
puts("\n\n原問題有唯一最優解。\n");
puts("\n按回車結束");
getchar();
exit(0);
case 0:
puts("\n\n原問題為無界解。\n");
puts("\n按回車結束");
getchar();
exit(0);
case -1:
output();
puts("\n\n原問題有無窮多最優解。\n");
puts("\n按回車結束");
getchar();
exit(0);
case -2:
puts("迭代超過限制次數強行終止!\n");
puts("\n按回車結束");
getchar();
exit(0);
}//switch
}
void banner() {
printf("\t\t****************************************\n");
printf("\t\t 單純型法解線性規劃問題\n");
printf("\t\t 作者:Thunder\n");
printf("\t\t****************************************\n");
printf("\n");
}
void show() {
//對方程組以自然的格式輸出,系數為零的x不顯示
//為1的不顯示系數1,-1系數只顯示負號
int i,j,k;
switch(step) {
case 1:
printf("min z= ");
printf("x[%d]",arti[1]);
for(i=2;i=num_ar;i++) printf(" + x[%d]",arti);
break;
case 2:
printf("max z= ");
printf("%lg x[%d]",c[1],1);
for(i=2;i=num_x;i++) {
if(c==1) printf(" + x[%d]",i);
else if(c==-1) printf(" - x[%d]",i);
else if(c=0) printf(" +%lg x[%d]",c,i);
else printf(" %lg x[%d]",c,i);
}
break;
}
printf("\nst:\n");
for(i=1;i=num_st;i++) {
k=0;
for(j=1;j=num_x;j++) {
if(a[j]!=0) {
if(a[j]==1k!=0) printf(" + x[%d]",j);
else if(a[j]==1k==0) printf(" x[%d]",j);
else if(a[j]==-1) printf(" - x[%d]",j);
else if(a[j]=0k!=0) printf(" +%lg x[%d]",a[j],j);
else if(a[j]=0k==0) printf(" %lg x[%d]",a[j],j);
else printf(" %lg x[%d]",a[j],j);
k=1;
}
}
printf(" == %lg\n",b);
}
printf(" x[1]~x[%d]=0",num_x);
}
void exchange() {
int i;
double temp[MAX];
for(i=1;i=num_x;i++) {
temp=temp_c;
temp_c=c;
c=temp;
}
}
void create() {
//輸入方程組系數,每個方程輸完后回顯確認
int i,j,k,re_st[MAX],tnum_x,num_addv=0,num_ba=0;
char confirm;
while(1) {
printf("請選擇:1、求最大值,2、求最小值:(1/2)");
scanf("%d",ma_mi);
if(ma_mi!=1ma_mi!=2) printf("輸入錯誤,重新選擇。");
else break;
}
while(1) {
printf("指定變量個數:");
scanf("%d",num_x);
printf("輸入價值系數c1-c%d:\n",num_x);
for(i=1;i=num_x;i++) {
printf("c%d=",i);
scanf("%lf",c);
}
if(ma_mi==1) printf("max z= ");
else printf("min z= ");
printf("%lg x[%d]",c[1],1);
for(i=2;i=num_x;i++) {
if(c=0) printf(" +%lg x[%d]",c,i);
else printf(" %lg x[%d]",c,i);
}
printf("\n正確嗎?:(y/n)");
getchar();
confirm=getchar();
if (confirm=='y') break;
else if(confirm=='n') continue;
}
printf("輸入約束方程組個數:");
scanf("%d",num_st);
for(i=1;i=num_st;i++) {
printf("st.%d:\n",i);
while(1) {
printf("請選擇:1、==,2、=,3、= :(1/2/3)");
scanf("%d",re_st);
if(re_st!=1re_st!=2re_st!=3) printf("輸入錯誤,請重新選擇。");
else break;
}
printf("輸入技術系數:\n");
for(j=1;j=num_x;j++) {
printf("a%d=",j);
scanf("%lf",a[j]);
}
printf("輸入資源擁有量:\nb%d=",i);
scanf("%lf",b);
printf("st.%i:\n",i);
printf("%lg x[%d]",a[1],1);
for(j=2;j=num_x;j++) {
if(a[j]=0) printf(" +%lg x[%d]",a[j],j);
else printf(" %lg x[%d]",a[j],j);
}
switch(re_st) {
case 1: printf(" == %lg",b); break;
case 2: printf(" = %lg",b); break;
case 3: printf(" = %lg",b); break;
}
while(1) {
printf("\n正確嗎?(y/n)");
getchar();
confirm=getchar();
if (confirm=='y') break;
else if(confirm=='n') {i-=1; break;}
}
}
//顯示輸入的方程組
printf("\n原問題為:\n\n");
if(ma_mi==1) printf("max z= ");
else printf("min z= ");
printf("%lg x[%d]",c[1],1);
for(i=2;i=num_x;i++) {
if(c==1) printf(" + x[%d]",i);
else if(c==-1) printf(" - x[%d]",i);
else if(c=0) printf(" +%lg x[%d]",c,i);
else printf(" %lg x[%d]",c,i);
}
printf("\nst:\n");
for(i=1;i=num_st;i++) {
k=0;
for(j=1;j=num_x;j++) {
if(a[j]!=0) {
if(a[j]==1k!=0) printf(" + x[%d]",j);
else if(a[j]==1k==0) printf(" x[%d]",j);
else if(a[j]==-1) printf(" - x[%d]",j);
else if(a[j]=0k!=0) printf(" +%lg x[%d]",a[j],j);
else if(a[j]=0k==0) printf(" %lg x[%d]",a[j],j);
else printf(" %lg x[%d]",a[j],j);
k=1;
}
}
switch(re_st) {
case 1:
printf(" == %lg\n",b);
break;
case 2:
printf(" = %lg\n",b);
break;
case 3:
printf(" = %lg\n",b);
break;
}
}
printf(" x[1]~x[%d]=0\n",num_x);
tnum_x=num_x;
for(i=1;i=num_st;i++) {
switch(re_st) {
case 1:
case 3:
num_x+=1;
break;
case 2:
num_x+=2;
break;
}
}
//化為標準形式
if(ma_mi==2) for(i=1;i=tnum_x;i++) c*=-1; //求最小值時,系數變相反數
for(i=1;i=num_st;i++) {
switch(re_st) {
case 1:
num_addv++;
num_ba++;
num_ar++;
c[tnum_x+num_addv]=0;
base[num_ba]=arti[num_ar]=tnum_x+num_addv;
for(j=tnum_x+1;j=num_x;j++)
if(j==tnum_x+num_addv) a[tnum_x+num_addv]=1;
else a[j]=0;
break;
case 2:
num_addv++;
c[tnum_x+num_addv]=0;
num_addv++;
num_ba++;
num_ar++;
c[tnum_x+num_addv]=0;
base[num_ba]=arti[num_ar]=tnum_x+num_addv;
for(j=tnum_x+1;j=num_x;j++)
if(j==tnum_x+num_addv-1) a[tnum_x+num_addv-1]=-1;
else if(j==tnum_x+num_addv) a[tnum_x+num_addv]=1;
else a[j]=0;
break;
case 3:
num_addv++;
num_ba++;
c[tnum_x+num_addv]=0;
base[num_ba]=tnum_x+num_addv;
for(j=tnum_x+1;j=num_x;j++)
if(j==tnum_x+num_addv) a[tnum_x+num_addv]=1;
else a[j]=0;
break;
}//switch
}//增加松弛變量、剩余變量、人工變量、確定基變量
//顯示標準化后的方程組
printf("\n化為標準形式后:\n\n");
if(ma_mi==1) printf("max z= ");
else printf("max z'= ");
printf("%lg x[%d]",c[1],1);
for(i=2;i=num_x;i++) {
k=0;
for(j=1;j=num_ar;j++)
if(i==arti[j]) k=1;
if(k==1) printf(" -M x[%d]",i);
else if(c==1) printf(" + x[%d]",i);
else if(c==-1) printf(" - x[%d]",i);
else if(c=0) printf(" +%lg x[%d]",c,i);
else printf(" %lg x[%d]",c,i);
}
printf("\nst:\n");
for(i=1;i=num_st;i++) {
k=0;
for(j=1;j=num_x;j++) {
if(a[j]!=0) {
if(a[j]==1k!=0) printf(" + x[%d]",j);
else if(a[j]==1k==0) printf(" x[%d]",j);
else if(a[j]==-1) printf(" - x[%d]",j);
else if(a[j]=0k!=0) printf(" +%lg x[%d]",a[j],j);
else if(a[j]=0k==0) printf(" %lg x[%d]",a[j],j);
else printf(" %lg x[%d]",a[j],j);
k=1;
}
}
printf(" == %lg\n",b);
}
printf(" x[1]~x[%d]=0",num_x);
}
void iterative() {
int i,j,k,k_a,k_f,l; //k_a,k_f值為0或1,記錄當前下標在arti[]或base[]里的搜索結果
int base_elem;
int base_out,base_in;
double sigma[MAX],temp;
double value_be; //高斯消元里保存主元素值
printf("\n\n第%d次迭代:\n\n",stop);
for(i=1;i=num_st;i++) {
printf("c%d=%lg\t",base,c[base]);
printf("b%d=%lg\t",i,b);
switch(step) {
case 1:
for(j=1;j=num_x;j++)
{
printf("a[%d][%d]=%lg\t",i,j,a[j]);
}
printf("\n");
break;
case 2:
for(j=1;j=num_x;j++) {
k_a=0;
for(l=1;l=num_ar;l++) if(j==arti[l])k_a=1;
if(k_a!=1) printf("a[%d][%d]=%lg\t",i,j,a[j]);
}
printf("\n");
break;
}
}
//求檢驗數sigma
for(i=1;i=num_x;i++) {
sigma=c;
for(j=1;j=num_st;j++) sigma-=c[base[j]]*a[j];
for(j=1;j=num_st;j++) if(i==base[j]) sigma=0;
switch(step) {
case 1:
printf("sigma[%d]=%lg\t",i,sigma);
break;
case 2:
k_a=0;
for(l=1;l=num_ar;l++) if(i==arti[l]) k_a=1;
if(k_a!=1) printf("sigma[%d]=%lg\t",i,sigma);
break;
}
}
putchar('\n');
//檢驗檢驗數sigma是否全小于等于0
k=0;
for(i=1;i=num_x;i++) {
if(sigma0)
k=1;
}
if(k==0) {
//sigma是全小于等于0時,檢查是否為無窮多最優解
for(i=1;i=num_x;i++) {
k_f=k_a=0;
for(j=1;j=num_ar;j++)
if(i==arti[j]) k_a=1;
if(sigma==0k_a!=1) {
for(j=1;j=num_st;j++) if(i==base[j]) k_f=1;
if(k_f==0) {status=-1; return;}
}
}
status=1;
return;
}
//檢查是否為無界解
for(i=1;i=num_x;i++) {
k_f=0;
if(sigma0) {
for(j=1;j=num_st;j++) if(a[j]0) k_f=1;
if(k_f!=1) {status=0; return;}
}
}
//確定換入變量
for(i=1;i=num_x;i++) {
k=0;
for(j=1;j=num_st;j++) if(i==base[j]) k=1;
if(k==0sigma0) temp=sigma-1;
}//temp賦初值
for(i=1;i=num_x;i++) {
k=0;
for(j=1;j=num_st;j++) if(i==base[j]) k=1;
if(k==0)
if(sigmatempsigma0) {
base_in=i;
temp=sigma;
}
}
//確定換出變量
for(i=1;i=num_st;i++)
if(a[base_in]0) {
temp=b/a[base_in]+1;
break;
}//temp賦初值
for(i=1;i=num_st;i++) {
if(b/a[base_in]=tempa[base_in]0) {
for(j=1;j=num_ar;j++)
if(base==arti[j]) {
base_out=base;
base_elem=i;
temp=b/a[base_in];
break;
}
}//人工變量優先換出
if(b/a[base_in]tempa[base_in]0) {
base_out=base;
base_elem=i;
temp=b/a[base_in];
}
}
printf(" 基變量:");
for(i=1;i=num_st;i++) printf("x[%d] ",base);
printf("換入變量:x[%d] 換出變量:x[%d]",base_in,base_out);
//基變量變換,進行新方程初始化后迭代
for(i=1;i=num_st;i++) {
if(base==base_out) base=base_in;
}
//初始化主元素行系數
value_be=a[base_elem][base_in];
b[base_elem]/=value_be;
for(i=1;i=num_x;i++) a[base_elem]/=value_be;
for(i=1;i=num_st;i++) {
if(i!=base_elem) {
b-=b[base_elem]*a[base_in];
value_be=a[base_in];
for(j=1;j=num_x;j++) a[j]-=a[base_elem][j]*value_be;
}
}
stop++;
if(stopSTP) {status=-2; return;}
iterative();
}
void output() {
int i,j;
double X[MAX];
printf("\n結果如下:\n");
printf("\nX=(");
for(i=1;i=num_x;i++) {
for(j=1;j=num_st;j++)
if(i==base[j]) {X=b[j];break;}
else X=0;
printf("%lg ",X);
}
printf(")");
for(i=1;i=num_x;i++) max+=c*X;
if(ma_mi==1) printf("\nMax z= %lf\n",max);
else printf("\nMin z= %lf\n",-max);
}
網頁題目:線性規劃java代碼 線性規劃 java
網頁路徑:http://vcdvsql.cn/article32/ddsegsc.html
成都網站建設公司_創新互聯,為您提供網站導航、關鍵詞優化、搜索引擎優化、微信小程序、Google、品牌網站制作
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯