#!/usr/bin/perl -w use strict; my ($model, $dual); $model = parse(); print_model($model); $dual = dualize($model); print_model($dual); sub parse { my ( $line, $model, $varname, $upbo, $lowbo, ); $line = <>; die unless $line =~ /^Model name:/; $line = <>; $varname = [undef, split " ", $line]; $line = <>; $model->[0] = [split " ", $line]; $model->[0][0] = substr("\l$model->[0][0]", 0, 3); die unless $model->[0][0] eq "min" or $model->[0][0] eq "max"; while (<>) { last if not /\d/; # "Type real real ..." my (@coef, $consname, $constype); @coef = split " "; $consname = $coef[0]; $coef[0] = pop @coef; $constype = pop @coef; if ($constype eq "<=" ) { $constype = $model->[0][0] eq "max" ? 1 : -1; } elsif ($constype eq ">=") { $constype = $model->[0][0] eq "min" ? 1 : -1; } else { # $constype eq "=" $constype = 0; } push @coef, $constype, $consname; push @$model, [@coef]; } die unless /^Type(\s+real)*\s*$/i; $line = <>; $upbo = [split " ", $line]; die unless $upbo->[0] eq 'upbo'; $line = <>; $lowbo = [split " ", $line]; die unless $lowbo->[0] eq 'lowbo'; my ($vartype, $i); for ($i=1; $i<=$#$lowbo; ++$i) { if ($upbo->[$i] eq "Inf" and $lowbo->[$i] eq "-Inf") { $vartype->[$i] = 0; } elsif ($upbo->[$i] eq "Inf" and $lowbo->[$i] eq "0") { $vartype->[$i] = 1; } elsif ($upbo->[$i] eq "0" and $lowbo->[$i] eq "-Inf") { $vartype->[$i] = -1; } else { die "difficult variable $varname->[$i]," . "whose bounds are: lower $lowbo->[$i], upper $upbo->[$i]"; } } push @$model, $vartype, $varname; return $model; } sub add_plus { my ($t) = @_; return $t>=0 ? "+" . $t : $t; } sub print_model { my ($model) = @_; my ($i, $j, $m, $n); $m = $#$model - 2; $n = $#{$model->[1]} - 2; print " "; for ($j=1; $j<=$n; ++$j) { printf " %-6s", $model->[$m+2][$j]; } print "\n[$model->[0][0]] :"; for ($j=1; $j<=$n; ++$j) { printf "%5s %-6s", add_plus($model->[0][$j]), $model->[$m+2][$j]; } print "\n"; for ($i=1; $i<=$m; ++$i) { printf "%6s:", $model->[$i][$n+2]; for ($j=1; $j<=$n; ++$j) { printf "%5s %-6s", add_plus($model->[$i][$j]), $model->[$m+2][$j]; } if ($model->[$i][$n+1] > 0) { if ($model->[0][0] eq "max") { print " <="; } else { print " >="; } } elsif ($model->[$i][$n+1] < 0) { if ($model->[0][0] eq "max") { print " >="; } else { print " <="; } } else { print " ="; } printf "%6s\n", $model->[$i][0]; } print "[sign]:"; for ($j=1; $j<=$n; ++$j) { if ($model->[$m+1][$j] > 0) { print " + "; } elsif ($model->[$m+1][$j] < 0) { print " - "; } else { printf " any "; } } print "\n\n"; } sub dualize { my ($model) = @_; my ($dual); my ($i, $j, $m, $n); $m = $#$model - 2; $n = $#{$model->[1]} - 2; for ($i=0; $i<=$m+2; ++$i) { for ($j=0; $j<=$n+2; ++$j) { $dual->[$j][$i] = $model->[$i][$j]; } } $dual->[0][0] = $model->[0][0] eq "max" ? "min" : "max"; return $dual; }