6

Tôi đã thực hiện các vấn đề lập trình tuyến tính trong lớp bằng cách vẽ đồ thị nhưng tôi muốn biết cách viết chương trình cho một vấn đề cụ thể để giải quyết nó cho tôi. Nếu có quá nhiều biến hoặc ràng buộc, tôi không bao giờ có thể làm điều này bằng cách vẽ đồ thị.Mã một bài tập lập trình tuyến tính bằng tay

Ví dụ vấn đề, phát huy tối đa 5x + 3Y với các ràng buộc:

  • 5x - 2y> = 0
  • x + y < = 7
  • x < = 5
  • x> = 0
  • y> = 0

Tôi đã vẽ đồ thị này và có r hiển thị egion với 3 góc. x = 5 y = 2 là điểm tối ưu.

Làm cách nào để chuyển mã này thành mã? Tôi biết về phương pháp simplex. Và rất quan trọng, tất cả các vấn đề LP sẽ được mã hóa trong cùng một cấu trúc? Liệu lực lượng vũ phu có hiệu quả không?

+2

Phương pháp simplex là những gì bạn muốn. –

+0

Câu trả lời là khác nhau nếu bạn đang tìm kiếm * Integer * Lập trình tuyến tính hoặc * Fractional * Lập trình tuyến tính (vì sự phức tạp của các vấn đề là khác nhau) – amit

+3

Trong [Bí quyết số cho C] (http://apps.nrbook.com/ c/index.html) trực tuyến, mục 10.8, bạn có thể tìm thấy việc thực hiện đơn giản thuật toán Simplex được viết bằng C. –

Trả lời

5

Có khá nhiều triển khai Simplex mà bạn sẽ tìm thấy nếu bạn tìm kiếm.

Ngoài những ai đề cập đến trong các bình luận (Bí quyết Numerical trong C), bạn cũng có thể tìm thấy:

  1. Google's own Simplex-Solver
  2. Sau đó có COIN-OR
  3. GNU có riêng của mình GLPK
  4. Nếu bạn muốn thực hiện C++, cái này trong Google Code thực sự có thể truy cập được.
  5. Có nhiều triển khai trong R bao gồm boot package. (Trong R, bạn có thể thấy việc thực hiện một chức năng bằng cách gõ nó mà không có dấu ngoặc đơn.)

Để giải quyết hai bạn câu hỏi khác:

  1. tất cả LP sẽ được mã hóa theo cùng một cách? Có, một bộ giải LP chung có thể được ghi để tải và giải quyết bất kỳ LP nào. (Có các định dạng tiêu chuẩn công nghiệp cho việc đọc LP của như mps.lp

  2. Sẽ brute lực lượng lao động? Hãy ghi nhớ rằng nhiều công ty và tổ chức lớn dành một thời gian dài trên tinh chỉnh các giải quyết. Có của LP có thú vị tài sản mà nhiều người giải quyết sẽ cố gắng khai thác. Ngoài ra, tính toán nhất định có thể được giải quyết song song. thuật toán là mũ, vì vậy tại một số lượng lớn các biến/chế, brute force sẽ không hoạt động.

Hy vọng rằng giúp.

0

tôi đã viết đây là matlab ngày hôm qua, mà có thể dễ dàng sao chép lại để C++ nếu bạn sử dụng thư viện Eigen hoặc viết lớp ma trận của riêng bạn bằng cách sử dụng std :: vector của một std :: vector

function [x, fval] = mySimplex(fun, A, B, lb, up) 

%Examples paramters to show that the function actually works 

% sample set 1 (works for this data set) 

% fun = [8 10 7]; 
% A = [1 3 2; 1 5 1]; 
% B = [10; 8]; 
% lb = [0; 0; 0]; 
% ub = [inf; inf; inf]; 

% sample set 2 (works for this data set) 

fun = [7 8 10]; 
A = [2 3 2; 1 1 2]; 
B = [1000; 800]; 
lb = [0; 0; 0]; 
ub = [inf; inf; inf]; 


% generate a new slack variable for every row of A 

numSlackVars = size(A,1); % need a new slack variables for every row of A 

% Set up tableau to store algorithm data 
tableau = [A; -fun]; 

tableau = [tableau, eye(numSlackVars + 1)]; 

lastCol = [B;0]; 

tableau = [tableau, lastCol]; 

% for convienience sake, assign the following: 

numRows = size(tableau,1); 
numCols = size(tableau,2); 

% do simplex algorithm 

% step 0: find num of negative entries in bottom row of tableau 

numNeg = 0; % the number of negative entries in bottom row 

for i=1:numCols 
    if(tableau(numRows,i) < 0) 
     numNeg = numNeg + 1; 
    end 
end 

% Remark: the number of negatives is exactly the number of iterations needed in the 
% simplex algorithm 

for iterations = 1:numNeg 
    % step 1: find minimum value in last row 
    minVal = 10000; % some big number 
    minCol = 1; % start by assuming min value is the first element 
    for i=1:numCols 
     if(tableau(numRows, i) < minVal) 
      minVal = tableau(size(tableau,1), i); 
      minCol = i; % update the index corresponding to the min element 
     end 
    end 

    % step 2: Find corresponding ratio vector in pivot column 
    vectorRatio = zeros(numRows -1, 1); 
    for i=1:(numRows-1) % the size of ratio vector is numCols - 1 
     vectorRatio(i, 1) = tableau(i, numCols) ./ tableau(i, minCol); 
    end 

    % step 3: Determine pivot element by finding minimum element in vector 
    % ratio 

    minVal = 10000; % some big number 
    minRatio = 1; % holds the element with the minimum ratio 

    for i=1:numRows-1 
     if(vectorRatio(i,1) < minVal) 
      minVal = vectorRatio(i,1); 
      minRatio = i; 
     end 
    end 

    % step 4: assign pivot element 

    pivotElement = tableau(minRatio, minCol); 

    % step 5: perform pivot operation on tableau around the pivot element 

    tableau(minRatio, :) = tableau(minRatio, :) * (1/pivotElement); 

    % step 6: perform pivot operation on rows (not including last row) 

    for i=1:size(vectorRatio,1)+1 % do last row last 
     if(i ~= minRatio) % we skip over the minRatio'th element of the tableau here 
      tableau(i, :) = -tableau(i,minCol)*tableau(minRatio, :) + tableau(i,:); 
     end 
    end 
end 

% Now we can interpret the algo tableau 

numVars = size(A,2); % the number of cols of A is the number of variables 

x = zeros(size(size(tableau,1), 1)); % for efficiency 

% Check for basicity 
for col=1:numVars 
    count_zero = 0; 
    count_one = 0; 
    for row = 1:size(tableau,1) 
     if(tableau(row,col) < 1e-2) 
      count_zero = count_zero + 1; 
     elseif(tableau(row,col) - 1 < 1e-2) 
      count_one = count_one + 1; 
      stored_row = row; % we store this (like in memory) column for later use 
     end 
    end 
    if(count_zero == (size(tableau,1) -1) && count_one == 1) % this is the case where it is basic 
     x(col,1) = tableau(stored_row, numCols); 
    else 
     x(col,1) = 0; % this is the base where it is not basic 
    end 
end 

% find function optimal value at optimal solution 
fval = x(1,1) * fun(1,1); % just needed for logic to work here 
for i=2:numVars 
    fval = fval + x(i,1) * fun(1,i); 
end 


end