1. 程式人生 > >Linux/windows下java呼叫lingo

Linux/windows下java呼叫lingo

     最近有一些朋友問我關於java程式呼叫lingo的問題,為了方便大家瞭解一些過程,下面就將java呼叫的詳細過程重新寫一下。在介紹java呼叫前首先介紹下,他們之間呼叫的原理。

原理:一個完整的java-lingo程式,必須包含三個要素,java程式-model檔案-lingo軟體,這三這個缺一不可,並且model檔案與java程式是相互對應的也就是說如果你修改了其中任何一個檔案其他的檔案也許要做相應的修改,明確了這點後再來說明呼叫過程,首先java呼叫任何其他非java程式肯定是通過JNI將模型所需的資料傳遞給lingo模型檔案,而後Lingo程式再去求解模型,最後再將求解後的結果返回。至於

JNI的原理以及相關知識這裡不做介紹,有時間的朋友可以搜一下相關知識。這裡主要介紹的是Lingo部分,為了方便介紹這裡舉個例子:

MODEL:

SETS:

DAYS/ MON TUE WED THU FRI SAT SUN/:

NEEDS,START,ONDUTY;

ENDSETS

[OBJECTIVE]MIN = @SUM(DAYS(I):START(I));

@FOR(DAYS(TODAY):

!Calculate number on duty;

ONDUTY(TODAY)=

@SUM(DAYS(D)|D #LE# 5:

START(@WRAP(TODAY- D + 1,

@SIZE(DAYS))));

!Enforce staffing requirement;

ONDUTY(TODAY)>= NEEDS(TODAY);

@GIN(START);

);

DATA:

NEEDS= @POINTER(1);

@POINTER(2)= START;

@POINTER(3)= ONDUTY;

@POINTER(4)= OBJECTIVE;

@POINTER(5)= @STATUS();

ENDDATA

END

這是lng模型檔案,檔案的model部分不多做介紹,這裡主要介紹的是DATA部分,學過Lingo的朋友應該知道,Lingo模型的DATA部分,是模型的資料部分,用於初始模型中某些變數的值,

DATANEEDS的左邊寫著@POINTER(1)@POINTER(2)卻寫著START,這表示什麼意思呢,原來[email protected](1)表示,NEEDS這個變數的值是從外界獲取,@PIONT(2)=START這句話的意思是告訴外界@POINTER(2)這個地方的值獲取的是START的值,其他同理。說完這句後相信知道一點指標的朋友就應該知道,@POINT()這個函式表示的是一個記憶體的指標,並且這個指標被lingo和外界共同保留(這裡指的是java程式),外界與lingo的互動正是通過這些指標進行的,實際上就是變數記憶體共享。說道這裡還有一個疑問,那就是外界是怎樣知道,當前指標所對應的變數呢,這就要看你的程式執行順序了,在java呼叫lingo,@poiter(i)這個指標的開闢是在執行lng.LSsetPointerLng這個函式後,當第一次執行lng.LSsetPointerLng時,則對應著@POINTER(1),第二次對應著@PINTER(2),依次類推,I次執行,則對應這@POINTER(I).因此如果在lingo模型檔案中某個變數對應著@ponter(k),則對於他的值賦予在java程式碼中就必須在前面已經執行了k-1lng.LSsetPointerLng.至此原理已經介紹完畢,下面就來就一個值日安排的問題來給出具體的例子.

Lingo的安裝:這裡並不是要說明如何下載與安裝lingo,而是說明安裝完畢後所需要另外做的幾件事情。

1.Linux系統下,在命令終端中進入lingo安裝目錄下的bin/linux32目錄,而後執行

sudo./lingovars.sh以及sudo./symlinks.sh在執行完此命令後,還必須將bin/linux32這個目錄加入LD_LIBRARY_PATH環境變數中。

2.windows中則必須將lingo.exe所在目錄加入PATH環境變數中,這個設定可以通過,我的電腦--》屬性-》高階-》環境變數-Path中新增得到。

如果不這麼做在執行java程式時就會報載入庫檔案異常。

Java程式碼的編寫:Eclipse中新建一個java工程,並且引入lingo安裝檔案下的Lingo11.jar(具體名稱因版本而稍有不同)。再新建一個java檔案程式碼如下:

package com.xuen.test;
import java.awt.*;
import java.awt.event.*;
import java.io.File;

import javax.swing.*;

import com.lindo.Lingd11;


public class Staff1 implements ActionListener
{
   // Load the Lingo JNI interface
   static {
      System.loadLibrary( "Lingj11");
   }

   // Create a new Lingo object, which we will use to interface with Lingo
   Lingd11 lng = new Lingd11();

   // Stores the Lingo JNI environment pointer
   Object pnLngEnv;

   JFrame f;
   JPanel p;
   JTextField jtfNeeds[] = new JTextField[ 7];
   JTextField jtfStart[] = new JTextField[ 7];
   JTextField jtfOnDuty[] = new JTextField[ 7];
   JTextField jtfTotal;
   JButton jbtnSolve = new JButton("Solve");
   JButton jbtnExit = new JButton("Exit");

   int nLastIterationCount;

   public Staff1()
   {

      // Create the frame and panel
      f = new JFrame("Lingo staffing example using Java");
      p = new JPanel();                          //  t   l   b   r
      p.setBorder( BorderFactory.createEmptyBorder( 30, 10, 30, 50));
      p.setLayout( new GridLayout(10, 4, 40, 20));

      // Add the widgets.
      addWidgets();

      // Add the panel to the frame.
      f.getContentPane().add( p, BorderLayout.CENTER);

      // Exit when the window is closed.
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      // Show the frame
      f.pack();
      f.setVisible(true);

      // no solver iterations performed yet;
      nLastIterationCount = -1;
 
   }

   private void addWidgets()
   {
      String sDays[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
      JLabel jl[] = new JLabel[ 7];

      // Row 1...the headers
      JLabel jlHdrDay = new JLabel( "Day:", JLabel.RIGHT);
      p.add( jlHdrDay);
      JLabel jlHdrNeeds = new JLabel( "Needs:", JLabel.RIGHT);
      p.add( jlHdrNeeds);
      JLabel jlHdrStart = new JLabel( "Start:", JLabel.RIGHT);
      p.add( jlHdrStart);
      JLabel jlHdrOnDuty = new JLabel( "On Duty:", JLabel.RIGHT);
      p.add( jlHdrOnDuty);

      // Rows 2-8...days of the week
      for ( int i = 0; i < 7; i++)
      {

         jl[ i] = new JLabel( sDays[ i], JLabel.RIGHT);
         p.add( jl[ i]);
         jtfNeeds[ i] = new JTextField( "0", 5);
         jtfNeeds[ i].setHorizontalAlignment( JTextField.RIGHT);
         p.add( jtfNeeds[ i]);
         jtfStart[ i] = new JTextField( "0", JLabel.RIGHT);
         jtfStart[ i].setEditable( false);
         jtfStart[ i].setHorizontalAlignment( JTextField.RIGHT);
         p.add( jtfStart[ i]);
         jtfOnDuty[ i] = new JTextField( "0", JLabel.RIGHT);
         jtfOnDuty[ i].setEditable( false);
         jtfOnDuty[ i].setHorizontalAlignment( JTextField.RIGHT);
         p.add( jtfOnDuty[ i]);

      }

      // Row 9...displays total of Start column
      JLabel jlNull1 = new JLabel( " ", JLabel.RIGHT);
      p.add( jlNull1);
      JLabel jlTotal = new JLabel( "Total...", JLabel.RIGHT);
      p.add( jlTotal);
      jtfTotal = new JTextField( "0", JLabel.RIGHT);
      jtfTotal.setEditable( false);
      jtfTotal.setHorizontalAlignment( JTextField.RIGHT);
      p.add( jtfTotal);
      JLabel jlNull3 = new JLabel( " ", JLabel.RIGHT);
      p.add( jlNull3);

      // Row 10...Solve and Exit buttons
      JLabel jlNull4 = new JLabel( " ", JLabel.RIGHT);
      p.add( jlNull4);
      JLabel jlNull5 = new JLabel( " ", JLabel.RIGHT);
      p.add( jlNull5);
      jbtnSolve.addActionListener( this);
      p.add( jbtnSolve);
      jbtnExit.addActionListener( this);
      p.add( jbtnExit);

   }

   // Implementation of ActionListener interface.
   public void actionPerformed( ActionEvent event)
   {
      Object source = event.getSource();

      if ( source == jbtnSolve)
      {
         Solve();
      } else {
         System.exit( 0);
      }
   }

   private static int MySolverCallback( Object pnLng, int iLoc, Object jobj)
   {
      Staff1 s = (Staff1) jobj;
      int nIterations[] = new int [1];
      s.lng.LSgetCallbackInfoIntLng( pnLng, Lingd11.LS_IINFO_ITERATIONS_LNG, nIterations);
      if ( nIterations[0] != s.nLastIterationCount)
      {
         s.nLastIterationCount = nIterations[0];
         System.out.println("In Java callback function...iterations = " + s.nLastIterationCount);
      }
      return( 0);
   }

   private static int MyErrorCallback( Object pnLng, int nErrorCode, String jsErrMessage, Object jobj)
   {
      System.out.println("Lingo error code: " + nErrorCode);
      System.out.println("Lingo error message:\n\n " + jsErrMessage);
      return( 0);
   }

   private void Solve()
   {

      int nErr;
      Double d1=0.;
      double dNeeds[] = new double[7];
      double dStart[] = new double [7];
      double dOnDuty[] = new double [7];
      double dObj[] = new double [1];
      double dStatus[] = new double [1];

      System.out.println("\nSolving...");
      
      // get the staffing requirements
      for ( int i=0; i<7; i++)
      {
         String s = jtfNeeds[i].getText();
         try {
            dNeeds[ i] = d1.valueOf( s);
         }
         catch ( Exception e)
         {
            dNeeds[ i] = 0.;
         }
      }
      
      // clear output fields
      for ( int i=0; i<7; i++)
      {
         jtfStart[i].setText( " ");
         jtfOnDuty[i].setText( " ");
      }
      jtfTotal.setText( " ");
      
      // create the Lingo environment
      pnLngEnv = lng.LScreateEnvLng();
      if ( pnLngEnv == null)
      {
         System.out.println( "***Unable to create Lingo environment***");
         return;
      }
      
      // open a log file
      nErr = lng.LSopenLogFileLng( pnLngEnv, "lingo.log");
      if ( nErr != lng.LSERR_NO_ERROR_LNG )
      {
         System.out.println( "***LSopenLogFileLng() error***: " + nErr);
         return;
      }
      
      // pass lingo a pointer to the staffing needs
      int[] nPointersNow = new int[1];
	  nErr = lng.LSsetPointerLng( pnLngEnv, dNeeds, nPointersNow);
      if ( nErr != lng.LSERR_NO_ERROR_LNG )
      {
         System.out.println( "***LSsetPointerLng() error***: " + nErr);
         return;
      }
      
      // pass pointers to output areas
	  nErr = lng.LSsetPointerLng( pnLngEnv, dStart, nPointersNow);
      if ( nErr != lng.LSERR_NO_ERROR_LNG )
      {
         System.out.println( "***LSsetPointerLng() error***: " + nErr);
         return;
      }
	  nErr = lng.LSsetPointerLng( pnLngEnv, dOnDuty, nPointersNow);
      if ( nErr != lng.LSERR_NO_ERROR_LNG )
      {
         System.out.println( "***LSsetPointerLng() error***: " + nErr);
         return;
      }
	  nErr = lng.LSsetPointerLng( pnLngEnv, dObj, nPointersNow);
      if ( nErr != lng.LSERR_NO_ERROR_LNG )
      {
         System.out.println( "***LSsetPointerLng() error***: " + nErr);
         return;
      }
	  nErr = lng.LSsetPointerLng( pnLngEnv, dStatus, nPointersNow);
      if ( nErr != lng.LSERR_NO_ERROR_LNG )
      {
         System.out.println( "***LSsetPointerLng() error***: " + nErr);
         return;
      }
      
      // pass Lingo the name of the solver callback function...
      nErr = lng.LSsetCallbackSolverLng( pnLngEnv, "MySolverCallback", this);
      
      // ...and the error callback function
      nErr = lng.LSsetCallbackErrorLng( pnLngEnv, "MyErrorCallback", this);
      
      // construct the script
      
      // echo input to log file
      String sScript = "SET ECHOIN 1" + "\n";
      
      // load the model from disk
      File f=new File("Staffptr.lng");
      sScript = sScript + "TAKE "+f.getAbsolutePath() + "\n";
      
      // view the formulation
      sScript = sScript + "LOOK ALL" + "\n";
      
      // solve
      sScript = sScript + "GO" + "\n";
      
      // exit script processor
      sScript = sScript + "QUIT" + "\n";
      
      // run the script
      dStatus[0] = -1;
      nLastIterationCount = -1;
	  nErr = lng.LSexecuteScriptLng( pnLngEnv, sScript);
      if ( nErr != lng.LSERR_NO_ERROR_LNG )
      {
         System.out.println( "***LSexecuteScriptLng error***: " + nErr);
         return;
      }
      
      // clear the pointers to force update of local arrays
      // ***NOTE*** solution won't get passed to local arrays until
      // LSclearPointersLng is called!!!
	  nErr = lng.LSclearPointersLng( pnLngEnv);
      if ( nErr != lng.LSERR_NO_ERROR_LNG )
      {
         System.out.println( "***LSclearPointerLng() error***: " + nErr);
         return;
      }
      
      // check the solution status
      if ( dStatus[0] != lng.LS_STATUS_GLOBAL_LNG) 
       System.out.println( "***Unable to Solve*** dStatus:" + dStatus[0]);
      
      // close Lingo's log file
	  nErr = lng.LScloseLogFileLng( pnLngEnv);
      if ( nErr != lng.LSERR_NO_ERROR_LNG )
      {
         System.out.println( "***LScloseLogFileLng() error***: " + nErr);
         return;
      }
	  
      // delete the Lingo environment
      lng.LSdeleteEnvLng( pnLngEnv);
      
      // post the solution
      Integer nTotal = 0;
      for ( int i=0; i<7; i++)
      {
         Double d = dStart[i];
         Integer n = d.intValue(); 
         jtfStart[i].setText( n.toString());
         nTotal = nTotal + n;
      
         d = dOnDuty[i];
         n = d.intValue();
         jtfOnDuty[i].setText( n.toString());
      }
      jtfTotal.setText( nTotal.toString());
    
      //System.out.println( "free Java memory: " +  Runtime.getRuntime().freeMemory());
   }

   // main method
   public static void main(String[] args) {
      Staff1 s = new Staff1();
   }

}


編寫完上述程式碼後還需編寫Lingo模型檔案,在工程資料夾下新建一個STAFFPTR.LNG的文字檔案,並在其中寫入如下內容:

MODEL:

SETS:

DAYS/ MON TUE WED THU FRI SAT SUN/:

NEEDS,START, ONDUTY;

ENDSETS

[OBJECTIVE]MIN = @SUM( DAYS( I): START( I));

@FOR(DAYS( TODAY):

!Calculate number on duty;

ONDUTY(TODAY) =

@SUM(DAYS( D)| D #LE# 5:

START(@WRAP( TODAY - D + 1, @SIZE( DAYS))));

!Enforce staffing requirement;

ONDUTY(TODAY) >= NEEDS( TODAY);

@GIN(START);

);

DATA:

NEEDS= @POINTER( 1);

@POINTER(2) = START;

@POINTER(3) = ONDUTY;

@POINTER(4) = OBJECTIVE;

@POINTER(5) = @STATUS();

ENDDATA

END

完成後右鍵執行即可,如果執行時報如下錯誤,

Exceptionin thread "main" java.lang.UnsatisfiedLinkError:

則說明你的安裝過程有錯(或者你是用的lingo精簡版),重新執行上面所說的Lingo的安裝過程,以及配置eclipserunconfigurations的環境變數。

最後說明一點,其實這些知識lingo的幫助檔案說明的很清楚,對於一項陌生的應用幫助檔案是最好的老師。

相關推薦

Linux/windowsjava呼叫lingo

     最近有一些朋友問我關於java程式呼叫lingo的問題,為了方便大家瞭解一些過程,下面就將java呼叫的詳細過程重新寫一下。在介紹java呼叫前首先介紹下,他們之間呼叫的原理。 原理:一個完整的java-lingo程式,必須包含三個要素,java程式-model

Linux環境java呼叫ffmpeg命令進行視訊轉碼

1.這是在Linux系統下的程式碼,我執行後可以轉換成功: import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import

Windows Java呼叫CRF++詳解

轉自:http://www.cnblogs.com/i-bugs/p/3580383.html 1.步驟一覽 2.步驟詳情 2.1.環境準備 Swig(Simplified Wrapper and Interface Generator)下載,Windows作業系統直接解

LinuxJava呼叫C

概述 Java要想呼叫C的程式,就要把C生成的DLL檔案給Java呼叫,也就是要使用Java的本地化方法JNI呼叫C的DLL檔案。Java本地介面JNI(Java Native Interface),設計目的是與C/C++實現本地互動。 實現 1、在Java類中宣告nati

WindowsJava程式如何操作LinuxHbase資料庫表過程、難點的心得歷程

Java客戶端訪問Hbase 1.      過程 A. 首先搭建Hadoop叢集、在叢集中搭建zookeeper最後搭建Hbase(在搭建過程中由於最新版本不穩定建議採用較低版本的Hadoop:2.5-2.7均可,Zookeeper:zookeeper-3.3.6,HBa

LinuxJava呼叫MySql的第一個例子(全過程) 及 MySql改密碼的種種誤區

第三步:解壓mysql-connector-java-5.1.24.tar.gz這個檔案到/usr/local/java/。事實上這個目錄是任意的,只不過為了方便。我把jdk和eclipse都安裝到了上面這個目錄下。如下所示:第四步:新建一個TestMySql工程,右鍵工程-

linuxjava呼叫c/c++庫

本文僅作為自己測試過程的一些記錄。由於在專案中想複用之前的c程式碼介面以減少java開發的工作量,因此做了最簡單的HelloWorld測試。java呼叫C/C++庫是使用JNI介面。具體過程記錄如下:1、在eclipse下建立一個名為nativeTest的java工程,在其中

LinuxJava呼叫so檔案

嘗試了一下在linux下Java呼叫so檔案。需要注意以下幾點: 1,在linux下呼叫的so檔案的格式必須是linux的,而不是x86或其他。 2,linux打包的so檔案的位數必須和本機JVM的位數一樣,都是32位或都是64位,JVM位數可以通過java -ve

WindowsJava環境配置,tomcat安裝

配置 錯誤 javac images 環境 http blank 操作 targe 軟件151 盧煒傑 問題描述:在Windows下面做Java web相關的項目的時候,Java和tomcat是基礎,這裏記載一下Java環境的配置以及tomcat的安裝和配置。 使用工

WindowsJava開發環境搭建

環境 輸入 電腦 blog html dev 進行 點擊 develop 1、在cmd中輸入Java,若如下圖所示的提示,則說明當前電腦沒有安裝Java運行環境或者是JDK,則需要手動下載和安裝Java 2、打開網站http://www.oracle.com/index.

WindowsJava環境變量配置

javaWindows下JAVA用到的環境變量主要有3個,JAVA_HOME、CLASSPATH、PATH。1.JAVA_HOME:1C:\Program Files\Java\jdk1.7.0_602.CLASSPATH:1.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.ja

c++ 網絡編程(四)TCP/IP LINUX/windows socket 基於I/O復用的服務器端代碼 解決多進程服務端創建進程資源浪費問題

linux系統中 cin 通過 sel print 大小 查看 服務 集合 原文作者:aircraft 原文鏈接:https://www.cnblogs.com/DOMLX/p/9613861.html 好了,繼上一篇說到多進程服務端也是有缺點的,每創建一個

Linux環境java環境搭建一 JDK搭建

shell dt.jar 移動 之前 下載 環境變量path his exp 格式 第一步:下載jdk壓縮文件 第二步:上傳到家目錄下的soft目錄下,可以采用winscp,此處下載的是.tar.gz文件 第三步:解壓壓縮文件,並在/usr/local目錄下創建一個jdk7

WindowsJAVA開發環境搭建及環境變數配置

1、安裝JDK開發環境 下載網站:http://www.oracle.com/ 開始安裝JDK: 修改安裝目錄如下: 確定之後,單擊“下一步”。 注:當提示安裝JRE時,可以選擇不要安裝。 2、配置環境變數: 對於Java程式開發而言,主要會

Linux/WindowsC++設定執行緒名字方便多執行緒除錯

C++多執行緒程式設計,除錯是一個大問題,原因之一就是,執行緒名字繼承了父程序的名字,因此導致同一段程式碼的不同執行緒名字一樣;而且還會導致執行緒的名字怪怪的,不好看。 因此,如果在程式碼中可以設定執行緒的名字就好了,這樣在除錯中就可以看到期望的執行緒名字,這樣便於除錯。 由於編

WindowsC++呼叫系統軟鍵盤及其需要注意的點

Windows下系統軟鍵盤的程式名是osk.exe,系統軟鍵盤在有鍵盤的時候一點用都沒有,但是沒有鍵盤的時候想要輸入點東西,系統軟鍵盤就至關重要了。 osk.exe為微軟系統自帶的虛擬鍵盤程式,功能與真的鍵盤差不多.只需要在執行中輸入"osk"即可啟動虛擬鍵盤。 W

Linux/WindowsPython環境搭建步驟

一、Linux下Python環境搭建 一般情況下,Linux系統都已經預安裝好Python,但是版本都比較低,需要安裝新的版本方便使用。  下載地址:https://www.python.org/downloads/source/  1、上傳安裝檔案到Linux系統的/opt目錄下。

c++ 網路程式設計(九)TCP/IP LINUX/windows 多執行緒超詳細教程 以及 多執行緒實現服務端

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <process.h> #include <winsock2.h> #include <win

c++ 網路程式設計(九)TCP/IP LINUX/windows 多執行緒超詳細教程 以及 多執行緒實現服務端

原文作者:aircraft 原文連結:https://www.cnblogs.com/DOMLX/p/9661012.html  先講Linux下(windows下在後面可以直接跳到後面看): 一.執行緒基本概念 前面我們講過多程序伺服器,但我們知道它開銷很大

windowsvc呼叫openssl實現RSA加密

     拿到了linux下c實現的RSA呼叫原始碼,想在windows下程式設計實現相同的結果,查了查資料,在vc6和vs2010除錯通過,在win7 x64和winXP 32 執行結果一致,記錄下來,以備日後查詢。 一、安裝openssl 1、進入Win32 Open