Closed matthewcrews closed 3 years ago
few thoughts:
ILinearExpression.Decisions
may be redundant or confusing if it is the same set as ILinearExpression.Coefficients.Keys
.
Also, the current form is convenient for other use case, like pretty printing of terms.
Maybe you should preserve the current type and have seq<LinearElement> -> ILinearExpression
transformation function, which is done once when constructing the expression objects?
So you're okay with leaving the burden of interpretation up to the Solver implementer? Like I said, my concern is with someone blowing the stack easily.
Like I said, my concern is with someone blowing the stack easily.
Sorry, I may overlook what is the workflow around that, if when I input expression using the operators: someDecision1 * 2.4 + someDecision2 * 4.2
it gives me an seq<LinearElement>
, it may be represented as "lazy" ILinearSequence
or one in the making, which materializes in the solver into a "reduced" ILinearExpression
whenever the model is given for solving.
I'm not clear when the transformation happens, I assume it can happen close to running the solver before registering the constraints / objectives.
I've had to use the current LinearExpression.Reduce
to avoid the issue you mention.
It overal looks good to me, I see it will replace lots of the internal records in the dev branch.
I decided to go with an ILinearExpression
of
type ILinearExpression =
abstract member Terms : seq<LinearTerm>
I am considering whether it would be worthwhile to include an ISimplifiedLinearExpression
of the form:
type IReducedLinearExpression =
abstract member SimplifiedTerms : IReadOnlyDictionary<IDecision, float>
abstract member Offset : float
And a helper function for mapping from ILinearExpression
to ISimplifiedLinearExpression
. The reason for this is because I find it easier to work with an ISimplifiedLinearExpression
when writing the code to interop with a Solver. Without this, I would have to implement the simplification logic in each Solver backend. I'm going to see how much trouble it is before I commit to that. A small amount of duplicate code is fine. Putting the ISimplifiedLinearExpression
interface in the Flips.Solver
library may make more sense.
The names of types are not final. I was exploring how to implement the interfaces but I plan on going back and making the names of types more clear.
@smoothdeveloper So I think I got this to the point where I feel I can merge this into dev
. Normally I would NOT like a PR to be this large. The reason it ended up that way was because I wanted to migrate all the code to the interfaces and get the tests and examples running again.
I'd appreciate you giving this a once over to make sure I haven't missed something obvious. I think this will allow us to start migrating solvers to the interfaces. I'd be happy to help migrate your CPLEX code since that's what we use. I'm going to start filling out the features for CBC and GLOPS.
Normally I would NOT like a PR to be this large. The reason it ended up that way was because I wanted to migrate all the code to the interfaces and get the tests and examples running again.
I'm perfectly OK with the PR and motives, this is a first take of splitting some of the model type representation from the API with the idea we should use interfaces to facilitate a broad axis of extensibility.
I think as we mature the rest of the API and see more extensive samples, use case specific circumstances would benefit such extensibility, as an easy to reason escape path when some of the choices made for the default representation hits a wall.
Also, since this PR was open, no other suggestions really came to me or others to help you explore more options.
Merging this PR will probably enable me to do a small round of adjustments in the CPLEX backend.
Regarding the technicals of the merge, since there is a little bit of noise in the diff (some whitespace adjustments, commented code) and there has been significant edits that are potentially conflicting in main
branch, I'd suggest to proceed like this:
dev
on top of main
(I think there is only one PR of mine that I'll need to rebase, but it may impact some private branches for other people)main
, merge that separate PRdev
from scratch about missing adjustments that would have slipped)I tried rebasing dev
onto main
last night and the project files got really messed up for some reason. Cannot tell you why. The dev
branch here is now messy. I tried fixing it but there's a lot of project settings toggling in the .fsproj
files that I'm not used to. I am not as familiar with rebasing so I'm sure I did something wrong due to an incorrect understanding.
Any insight you can offer would be appreciated. I've mostly done merges in the past.
I tried rebasing dev onto main last night and the project files got really messed up for some reason. ... I've mostly done merges in the past.
Generally speaking, I prefer rebasing when there are no conflicts and merging when there are. Do you feel like you have the correct code after merging?
So far the code looks good. The .fsproj
files are what need fixing.
Ok, I will take a look soon.
I tried merging main
into dev
. There were conflicts in eight files but none of them were in project files. Can you merge main
into dev
, resolve the conflicts in those eight files, and then share that work in a branch? At that time, I can see what issues remain in the project files.
I honestly can't figure out what happened. The .fsproj
files are so messed up I can't even fix them. They are using a lot of toggles that I've never used before so I have a really hard time debugging the error messages I get from the build. I have half a mind to just nuke the dev
branch since it appears to be so mangled at this point. I've spent several hours trying to fix it and I'm not getting anywhere.
I have merged main
into dev
. The .fsproj
files are really messed up for some reason. Lots of duplicates. That don't make sense.
Yeah, dev
looks so bad at this point, I don't know if it's salvageable. Code formatting got mangled and I can't figure out how to revert the rebase.
I'm going to try to undo the rebase
and try over
So, I think I was able to revert the rebase and I'm trying to merge main
into dev
. I'm not a git wizard so I'm learning as I go. All the formatting changes didn't help but that's part of why this needs to be done 🤷♂️.
I reverted to e54f8c5
and am attempting the merge. There's going to be some patching though due to formatting changes.
I was able to revert the rebase, merge main
into dev
, and then patch up the conflicts between dev
and add-interfaces
. It's building on my machine now using the build.cmd
script. @TysonMN could you see if the dev
branch is working for you now?
Executing sh build.sh
seems to work. Building in Visual Studio fails only for Flips.Solver.Cplex
because the dependent assemblies ILOG.Concert
and ILOG.CPLEX
are missing.
@TysonMN good point, we are going to need to make non redistributable solvers opt-in options in the build script.
Before I merge this I'd like to get some quick feedback. There are two approaches to the modeling of ILinearExpression. One is to model it as a sequence of elements like this:
I don't like this because it puts a lot of burden on the people interpreting the ILinearExpression to write code which will not blow a stack will iterating through a potentially long sequence.
I prefer this approach:
Which is much easier to use for someone writing a Solver backend. This is the form I prefer to work with when mapping from the the Flips.Model to the Solver model.