線形計画の単純アルゴリズム
問題の定義:
問題の定義は複雑で、「アルゴリズム導論」の線形計画の一章を見ることを提案した.単純アルゴリズムは、次のような問題を解くために使用されます.
例:
式の最小値を求めます:-2 X 1–3 X 2
引数は次の制約を満たします.
X1 + X2 = 7
X1 – 2X2 <= 4
X1 >= 0
コンストレイントを標準に変換するには、次の手順に従います.
標準型の条件:
1.目標関数の最大値を求める
2.各引数がゼロ以上(負の制約なし)
3.制約不等式、最小化制約のみ
変換結果は次のとおりです.
max 2X1 – 3X2 + 3X3
そして、以下を満たす.
X1 + X2- X3 <= 7
-X1 – X2+ X3 <= -7
X1 – 2X2+ 2X3 <= 4
X1, X2, X3 >= 0
標準型をリラックス型に変換するには、次の手順に従います.
z = 2X1– 3X2 + 3X3
X4 = 7- X1 - X2 + X3
X5 = -7+ X1 + X2 - X3
X6 = 4- X1 + 2X2 - 2X3
基本変数の下付き集合B={4,5,6}
非基本変数の下付き集合N={1,2,3}
C = [ 2 3 3 ]T
b = [ 7 -7 4 ]T
A
1
1
-1
-1
-1
1
1
-2
2
v = 0
具体的には,A,b,C,vを1つの配列に格納する.
data
0v
2c
-3c
3c
7b
1A
1A
-1A
-7b
-1A
-1A
1A
4b
1A
-2A
2A
コードは次のとおりです.
問題の定義は複雑で、「アルゴリズム導論」の線形計画の一章を見ることを提案した.単純アルゴリズムは、次のような問題を解くために使用されます.
例:
式の最小値を求めます:-2 X 1–3 X 2
引数は次の制約を満たします.
X1 + X2 = 7
X1 – 2X2 <= 4
X1 >= 0
コンストレイントを標準に変換するには、次の手順に従います.
標準型の条件:
1.目標関数の最大値を求める
2.各引数がゼロ以上(負の制約なし)
3.制約不等式、最小化制約のみ
変換結果は次のとおりです.
max 2X1 – 3X2 + 3X3
そして、以下を満たす.
X1 + X2- X3 <= 7
-X1 – X2+ X3 <= -7
X1 – 2X2+ 2X3 <= 4
X1, X2, X3 >= 0
標準型をリラックス型に変換するには、次の手順に従います.
z = 2X1– 3X2 + 3X3
X4 = 7- X1 - X2 + X3
X5 = -7+ X1 + X2 - X3
X6 = 4- X1 + 2X2 - 2X3
基本変数の下付き集合B={4,5,6}
非基本変数の下付き集合N={1,2,3}
C = [ 2 3 3 ]T
b = [ 7 -7 4 ]T
A
1
1
-1
-1
-1
1
1
-2
2
v = 0
具体的には,A,b,C,vを1つの配列に格納する.
data
0v
2c
-3c
3c
7b
1A
1A
-1A
-7b
-1A
-1A
1A
4b
1A
-2A
2A
コードは次のとおりです.
/*
*Copyright(c) Computer Science Department of XiaMen University
*
*Authored by laimingxing on: 2012 03 03 00:14:35 CST
*
* @desc:
*
* @history
*/
#include <iostream>
#include<algorithm>
#include <vector>
#include <string.h>
using namespace std;
const double unbounded = 10000000;
const int MAX = 10;
int n;
double data[MAX][MAX];//A,b,c,v data
void PIVOT( vector<int> &N, vector<int> &B, int l ,int e);
void simple( vector<int> &N, vector<int>&B);
int main(int argc, char* argv[])
{
//
//
const int nX = 3;
// ,
const int nEquation = 4;
int i = 0, j = 0, k = 0;
vector<int>B,N;
double arr[ nEquation + 1 ][nX + 1 ] = {
{ 2, -3, 3,0},{1, 1, -1, 7}, {-1, -1, 1, -7}, {1, -2, 2, 4}
};
//N
for( k = 1; k <= nX; k++)
N.push_back( k);
//B
for( ; k < nX + nEquation; k++)
B.push_back( k);
n = nX + nEquation ;
memset( data, 0, sizeof(int) * n * n);
//c
for( i = 1; i < n; i++)
if( i <= nX) data[0][i] = arr[0][i - 1];
else data[0][i] = 0;
//A
for( i = nX + 1; i < n; i++)
{
for( j = 1; j <= nX ; j++)
{
data[i][j] = arr[ i - nX][j -1];
//cout << data[i][j] << "\t";
}
}
//b
for( i = nX + 1; i < n; i++)
data[i][0] = arr[ i - nX][nX];
simple( N,B);
return 0;
}
void simple( vector<int> &N, vector<int>&B)
{
for( int j = 1; j <= n; j++)
{
if(data[0][j] <= 0) continue;
double minBound = unbounded;
int minIndex = 0;
for( vector<int>::iterator i = B.begin(); i != B.end(); i++)
{
if( data[*i][j] <= 0)continue;
double temp = data[*i][0] / data[*i][j];
if( temp < minBound)
{
minBound = temp;
minIndex = *i;
}
}
if( minBound > unbounded - 1)
cout <<"Unbounded" << endl;
else
PIVOT( N, B, minIndex, j);
}
for( int i = 1 ; i <= n ; i++)
if( find(B.begin(), B.end(),i) != B.end() )
cout << "x"<<i << " = " << data[i][0] << endl;
else
cout << "x"<<i << " = " << 0 <<endl;
}
//N ,B
void PIVOT( vector<int> &N, vector<int> &B, int l ,int e)
{
data[e][0] = data[l][0] / data[l][e];
vector<int>::iterator j;
for( j = N.begin(); j != N.end(); j++)
{
if( *j == e)continue;
data[e][*j] = data[l][*j] / data[l][e];
}
data[e][l] = 1/ data[l][e];
for( vector<int>::iterator iter = B.begin(); iter != B.end(); iter++)
{
if( *iter == l) continue;
data[*iter][0] -= data[*iter][e] * data[e][0];
for( vector<int>::iterator it = N.begin(); it != N.end(); it++)
{
if( *it == e)continue;
data[*iter][*it] -= data[*iter][e] * data[e][*it];
}
data[*iter][l] = -1 * data[*iter][l] * data[e][l];
}
//Computer the objective function
data[0][0] += data[0][e] * data[e][0];
for( j = N.begin(); j != N.end(); j++)
{
if( *j == e) continue;
data[0][*j] -= data[0][e] * data[e][*j];
}
data[0][l] = -1 * data[0][e] * data[e][l];
//Compute new sets of basic and nonbasic variables.
vector<int>::iterator temp_it = find( N.begin(), N.end(), e);
if( temp_it != N.end() ) N.erase( temp_it);
N.push_back(l);
temp_it = find( B.begin(), B.end(), l);
if( temp_it != B.end() ) B.erase( temp_it);
B.push_back(e);
}