@islandids
@archipelagoes
$qa
+$max_mass
+$max_volume
+$lossperleaguepct
</%args>
<&| script &>
da_pageload= Date.now();
<%perl>
+my $loss_per_league= defined $lossperleaguepct ? $lossperleaguepct*0.01 : 1e-7;
+
my $now= time;
-my $loss_per_league= 1e-7;
my @flow_conds;
my @query_params;
<p>
% if (@islandids<=1) {
-Route is trivial.
+Route contains only one location.
% }
% if (!$specific) {
Route contains archipelago(es), not just specific islands.
Maximize
totalprofit:
- ".(join " +
+ ".(join "
", map {
- sprintf "%.20f %s", $_->{ExpectedUnitProfit}, $_->{Var}
+ sprintf "%+.20f %s", $_->{ExpectedUnitProfit}, $_->{Var}
} @flows)."
Subject To
foreach my $cstname (sort keys %avail_csts) {
my $c= $avail_csts{$cstname};
$cplex .= "
- ". sprintf("%-30s","$cstname:")." ".
+ ". sprintf("%-30s","$cstname:")." ".
join("+", @{ $c->{Flows} }).
" <= ".$c->{Qty}."\n";
}
+foreach my $ci (0..($#islandids-1)) {
+ my @rel_flows;
+ foreach my $f (@flows) {
+ next if $f->{Suppress};
+ next if $f->{'org_id'} == $f->{'dst_id'};
+ next unless grep { $f->{'org_id'} == $_ }
+ @islandids[0..$ci];
+ next unless grep { $f->{'dst_id'} == $_ }
+ @islandids[$ci+1..@islandids-1];
+ push @rel_flows, $f;
+print " RELEVANT $ci $f->{Ix} ";
+ }
+print " RELEVANT $ci COUNT ".scalar(@rel_flows)." ";
+ next unless @rel_flows;
+ foreach my $mv (qw(mass volume)) {
+ my $max_vn= "max_$mv";
+ my $max= $mv eq 'mass' ? $max_mass : $max_volume;
+ next unless defined $max;
+print " DEFINED MAX $mv $max ";
+ $cplex .= "
+ ". sprintf("%-10s","${mv}_$ci:")." ".
+ join(" + ", map { ($_->{"unit$mv"}*1e-3).' f'.$_->{Ix} } @rel_flows).
+ " <= $max";
+ }
+ $cplex.= "\n";
+}
+
$cplex.= "
Bounds
".(join "
", map { "$_->{Var} >= 0" } @flows)."
+";
+
+$cplex.= "
+Integer
+ ".(join "
+ ", map { "f$_" } (0..$#flows))."
+
End
";
while (<$output>) {
$glpsol_out.= $_;
print encode_entities($_) if $qa->{'debug'};
- if (m/^\s*No\.\s+Column name\s+St\s+Activity\s/) {
+ if (m/^\s*No\.\s+Column name\s+(?:St\s+)?Activity\s/) {
die if $found_section>0;
$found_section= 1;
next;
die $prerr unless $found_section;
};
-$addcols->({ DoReverse => 1 }, qw(
+$addcols->({ DoReverse => 1, Special => sub {
+ my ($flow,$col,$v,$spec) = @_;
+ if ($flow->{ExpectedUnitProfit} < 0) {
+ $spec->{Span}= 3;
+ $spec->{String}= '(Small margin)';
+ $spec->{Align}= 'align=center';
+ }
+} }, qw(
OptQty
));
$addcols->({ Total => 0, DoReverse => 1 }, qw(
<td><input type=hidden name=R<% $flow->{UidShort} %> value="">
<input type=checkbox name=T<% $flow->{UidShort} %> value=""
<% $flow->{Suppress} ? '' : 'checked' %> >
-% foreach my $ci (1..$#cols) {
+% my $ci= 1;
+% while ($ci < @cols) {
% my $col= $cols[$ci];
+% my $spec= {
+% Span => 1,
+% Align => ($col->{Text} ? '' : 'align=right')
+% };
% my $v= $flow->{$col->{Name}};
+% if ($col->{Special}) { $col->{Special}($flow,$col,$v,$spec); }
% $col->{Total} += $v
% if defined $col->{Total} and not $flow->{Suppress};
% $v='' if !$col->{Text} && !$v;
% my $sortkey= $col->{SortColKey} ?
% $flow->{$col->{SortColKey}} : $v;
% $ts_sortkeys{$ci}{$rowid}= $sortkey;
-<td <% $col->{Text} ? '' : 'align=right' %>><% $v |h %>
+<td <% $spec->{Span} ? "colspan=$spec->{Span}" : ''
+ %> <% $spec->{Align}
+ %>><% exists $spec->{String} ? $spec->{String} : $v |h %>
+% $ci += $spec->{Span};
% }
% }
<tr id="trades_total">
<tr><td colspan=3>
% $iquery->execute($islandids[$i]);
% my ($islandname) = $iquery->fetchrow_array();
-% my $this_dist= $distance->($islandids[$i-1],$islandids[$i]);
-% $total_dist += $this_dist;
% if (!$i) {
<strong>Start at <% $islandname |h %></strong>
% } else {
+% my $this_dist= $distance->($islandids[$i-1],$islandids[$i]);
+% $total_dist += $this_dist;
<strong>Sail to <% $islandname |h %></strong>
- <% $this_dist |h %> leagues </td>
% }