my
$one
= 1;
my
$neg_one
= -1;
my
$EMPTY_STRING
=
q()
;
sub
pivot {
my
$self
=
shift
;
my
$pivot_row_number
=
shift
;
my
$pivot_column_number
=
shift
;
my
$scale
=
$one
/ (
$self
->tableau->[
$pivot_row_number
]->[
$pivot_column_number
]);
for
my
$j
(0 ..
$self
->number_of_columns) {
$self
->tableau->[
$pivot_row_number
]->[
$j
] =
$self
->tableau->[
$pivot_row_number
]->[
$j
] * (
$scale
);
}
$self
->tableau->[
$pivot_row_number
]->[
$pivot_column_number
] =
$scale
;
for
my
$i
(0 ..
$self
->number_of_rows) {
if
(
$i
!=
$pivot_row_number
) {
my
$neg_a_ic
=
$self
->tableau->[
$i
]->[
$pivot_column_number
] * (
$neg_one
);
for
my
$j
(0 ..
$self
->number_of_columns) {
$self
->tableau->[
$i
]->[
$j
] =
$self
->tableau->[
$i
]->[
$j
] +
(
$neg_a_ic
* (
$self
->tableau->[
$pivot_row_number
]->[
$j
]));
}
$self
->tableau->[
$i
]->[
$pivot_column_number
] =
$neg_a_ic
* (
$scale
);
}
}
return
;
}
after
'pivot'
=>
sub
{
my
$self
=
shift
;
$self
->number_of_pivots_made(
$self
->number_of_pivots_made + 1);
return
;
};
sub
is_optimal {
my
$self
=
shift
;
for
my
$j
(0 ..
$self
->number_of_columns - 1) {
if
(
$self
->tableau->[
$self
->number_of_rows ]->[
$j
] >
$self
->EPSILON) {
return
0;
}
}
return
1;
}
sub
determine_simplex_pivot_columns {
my
$self
=
shift
;
my
@simplex_pivot_column_numbers
;
for
my
$col_num
(0 ..
$self
->number_of_columns - 1) {
if
(
$self
->tableau->[
$self
->number_of_rows ]->[
$col_num
] >
$self
->EPSILON)
{
push
(
@simplex_pivot_column_numbers
,
$col_num
);
}
}
return
(
@simplex_pivot_column_numbers
);
}
sub
determine_positive_ratios {
my
$self
=
shift
;
my
$pivot_column_number
=
shift
;
my
@positive_ratios
;
my
@positive_ratio_row_numbers
;
for
my
$row_num
(0 ..
$self
->number_of_rows - 1) {
if
(
$self
->tableau->[
$row_num
]->[
$pivot_column_number
] >
$self
->EPSILON)
{
push
(
@positive_ratios
,
$self
->tableau->[
$row_num
]->[
$self
->number_of_columns ] /
$self
->tableau->[
$row_num
]->[
$pivot_column_number
]);
push
@positive_ratio_row_numbers
,
$row_num
;
}
}
return
(\
@positive_ratios
, \
@positive_ratio_row_numbers
);
}
sub
current_solution {
my
$self
=
shift
;
my
@y
= @{
$self
->y_variables };
my
@u
= @{
$self
->u_variables };
my
%primal_solution
;
for
my
$i
(0 ..
$#y
) {
$primal_solution
{
$y
[
$i
]->{generic} } =
$self
->tableau->[
$i
]->[
$self
->number_of_columns ];
}
my
%dual_solution
;
for
my
$j
(0 ..
$#u
) {
$dual_solution
{
$u
[
$j
]->{generic} } =
$self
->tableau->[
$self
->number_of_rows ]->[
$j
] * -1;
}
return
(\
%primal_solution
, \
%dual_solution
);
}
sub
is_basic_feasible_solution {
my
$self
=
shift
;
for
my
$i
(0 ..
$self
->number_of_rows - 1) {
if
(
$self
->tableau->[
$i
]->[
$self
->number_of_columns ] <
-(
$self
->EPSILON))
{
return
0;
}
}
return
1;
}
1;