classdef dantzig_3_3
    %{
    Reference:
        George B. Dantzig.
        Linear Programming and Extensions.
        Princeton University Press, 1963.
        Chapter 3.3 Transportation Problem, page 35.
    %}
    properties(Constant)
        name = 'dantzig_3_3';
        category = 'transportation';
        subcategory = '';
        datasets = {};
        x0 = [325.0000, 304.9057, 320.0943];
        y0 = [45.0943, 304.9057, 0.0, 279.9057, 0.0, 320.0943];
    end


    methods(Static)
        % Upper-level objective function
        function val = F(x, ~, ~)
            val = sum((x-400).^2);
        end
        
        % Upper-level inequality constraints
        function val = G(x, ~, ~)
            val = x.' - [325; 300; 275];
        end
        
        % Upper-level equality constraints
        function val = H(~, ~, ~)
            val = [];
        end
        
        % Lower-level objective function
        function val = f(~, y, ~)
            val = dot(y, [2.5, 1.7, 1.8, 2.5, 1.8, 1.4]);
        end
        
        % Lower-level inequality constraints
        function val = g(x, y, ~)
            val = [
                350 - y(1) - y(2) - y(3);
                650 - y(4) - y(5) - y(6);
                y(1) + y(4) - x(1);
                y(2) + y(5) - x(2);
                y(3) + y(6) - x(3);
        ];
        end
        
        % Lower-level equality constraints
        function val = h(~, ~, ~)
            val = [];
        end

        % If the bilevel program is parameterized by data, this function should
        %  provide code to read data file and return an appropriate structure.
        function val = read_data(~)
            val = [];
        end

        % Key are the function/variable names
        % Values are their dimention
        function n = dimentions(key, ~)
            n = dictionary( ...
                'x', 3, ...
                'y', 6, ...
                'F', 1, ...
                'G', 3, ...
                'H', 0, ...
                'f', 1, ...
                'g', 5, ...
                'h', 0 ...
            );
            if isKey(n,key)
                n = n(key);
            end
        end
    end
end