2013-05-24 7 views
1

매트릭스를 생성하기 위해 CPLEX 최적화 코드를 작성합니다. r 및 n을 명령 줄 인수로 사용하지만 2 및 4로 가정 할 수 있습니다 지금 당장.최적화에서 가능한 모든 최적 이하 (최적이 아님 !!!) 솔루션 찾기

행렬을 발생하기위한 조건은 임의의 행 또는 임의의 열에있는 원소의 합이 원소가 0과 10 I가 설정

(즉 이중 확률 매트릭스) 사이의 정수이다 (10)를, 동일해야한다는 것이다 이 조건을 제약 조건에 적용하고 행렬을 생성하지만 10 및 0 행렬 만 제공합니다.

나는 CPLEX가 항상 "최적의"솔루션을 찾았 기 때문에 생각합니다.하지만 해결하고 싶은 문제에 대해서는별로 도움이되지 않습니다.

나머지 6, 7, 8, 9, 10, 0 ~ 5의 행렬이 필요합니다.

이러한 조건을 만족하는 가능한 모든 행렬을 생성하고 (나중에 추가해야 할 조건을 추가하여) 모두 테스트하여 사례를 소진 할 수 있습니다.

어떻게하면됩니까? 또한

나는이 솔루션 풀 일을 조사하고, 그것이 쉬운 일이 아닙니다 ..

,

cplex.out() < < cplex.getSolnPoolNsolns < < "솔루션 = 수"() < < endl;

이것은 1을 제공합니다. 단 하나의 해결책이 있다는 것을 의미하지만, 수백만 개의 행렬이 있다는 것을 알고 있습니다.

모든 '차선책'행렬을 생성하는 방법에 대한 아이디어가 있으시면 언제든지 도와주세요.

감사합니다.

내 코드를 IPGenMat.cpp에 첨부했고, aa.sol은 내게 준 솔루션입니다.

여기 아래에 복사했습니다.

:

#include<ilcplex/ilocplex.h> 
#include<vector> 
#include<iostream> 
#include<sstream> 
#include<string> 

using namespace std; 

int main(int argc, char** argv) { 
    if (argc < 2) { 
     cerr << "Error: " << endl; 
     return 1; 
    } 
    else { 
     int r, n; 
     stringstream rValue(argv[1]); 
     stringstream nValue(argv[2]); 

     rValue >> r; 
     nValue >> n; 

     int N=n*r; 
     int ds = 10; //10 if doubly-stochastic, smaller if sub-doubly stochastic 
     IloEnv env; 

     try { 
      IloModel model(env); 

      IloArray<IloNumVarArray> m(env, N); 

      for (int i=0; i<N; i++) { 
       m[i] = IloNumVarArray(env, N, 0, 10, ILOINT); 

      } 


      IloArray<IloExpr> sumInRow(env, N); 

      for (int i=0; i<N; i++) { 
       sumInRow[i] = IloExpr(env); 
      } 

      for (int i=0; i<N; i++) { 
       for (int j=0; j<N; j++) { 
        sumInRow[i] += m[i][j]; 
       } 
      } 

      IloArray<IloRange> rowEq(env, N); 

      for (int i=0; i<N; i++) { 
       rowEq[i] = IloRange(env, ds, sumInRow[i], 10); //doubly stochastic 
      } 


      IloArray<IloExpr> sumInColumn(env, N); 

      for (int i=0; i<N; i++) { 
       sumInColumn[i] = IloExpr(env); 
      } 

      for (int i=0; i<N; i++) { 
       for (int j=0; j<N; j++) { 
        sumInColumn[i] += m[j][i]; 
       } 
      } 

      IloArray<IloRange> columnEq(env, N); 

      for (int i=0; i<N; i++) { 
       columnEq[i] = IloRange(env, ds, sumInColumn[i], 10); //doubly stochastic 
      } 

      for (int i=0; i<N; i++) { 
       model.add(rowEq[i]); 
       model.add(columnEq[i]); 
      } 

      IloCplex cplex(env); 
      cplex.extract(model); 
      cplex.setParam(IloCplex::SolnPoolAGap,0.0); 
      cplex.setParam(IloCplex::SolnPoolIntensity,4); 
      cplex.setParam(IloCplex::PopulateLim, 2100000000); 
      cplex.populate();//.solve(); 
      cplex.out() << "solution status = " << cplex.getStatus() << endl; 
      cplex.out() << "number of solutions = " << cplex.getSolnPoolNsolns() << endl; 
      cplex.out() << endl; 
      cplex.writeSolutions("aa.sol"); 

      for (int i = 0; i < N; i++) { 
       for (int j = 0; j < N; j++) { 
        cplex.out() << cplex.getValue(m[i][j]) << " | "; 
       } 
       cplex.out() << endl; 
      } 
      cplex.out() << endl; 

     } 

     catch(IloException& e) { 
      cerr << " ERROR: " << e << endl; 
     } 
     catch(...) { 
      cerr << " ERROR: " << endl; 
     } 
     env.end(); 
     return 0; 
    } 
} 

답변

2

당신은 PORTAvint를 사용하여 시도 할 수 있습니다 (즉, 두 가지 질문? 1. 어떻게 찾을 수있는 '덜 최적의 솔루션 2. 어떻게 이러한 모든 솔루션을 찾을 수 있습니다) 유틸리티 또는이 대신 PPL. CPLEX는 열거 문제가 아닌 최적화 문제를 해결합니다.

문제는 작은 최적화 문제이지만, 정말 큰 열거 문제입니다. 당신이 무엇을 해야할지 더 많은 해결책이있을 것입니다. 선형 불평등을 사용하여 원하는 것을 좁히고 표현하려고 시도 할 수 있습니다.

0

SolnPoolAGap 솔루션 풀의 솔루션에 대한 객관적인 값의 절대 허용 오차를 설정합니다. 이 측정에 따라 현 솔루션의 목적보다 더 나쁜 (최소화의 경우 더 크거나 최대화의 경우 더 적은) 솔루션은 솔루션 풀에 보관되지 않습니다.

그래서, 그냥 솔루션이 항목 m_i_j 일부 행렬이다 가정하자이 매개 변수

0

에서 0.0 보다 더 높은 값을 넣어야 하위 최적의 솔루션을 얻을 수있다. 이진 결정 변수 세트로 문제를 표현하십시오. m_i_j_v "행 i와 열 i의 행렬은 값 v를가집니다". 그런 다음 문제를 해결 한 후에는 설정된 모든 결정 변수에 대해 합계하는 다른 제약 조건을 추가하여 N-1이되도록 할 수 있습니다. 이것은 해결책으로 이것을 제외 할 것입니다. 문제가 실행 불가능해질 때까지 반복을 헹굽니다.