Skip to content

Commit f02c634

Browse files
authored
Release v0.17.0
Release v0.17.0
2 parents 017b2f5 + b45e5d8 commit f02c634

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2711
-156
lines changed

.github/workflows/go-lint.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ jobs:
1616
- name: golangci-lint
1717
uses: golangci/golangci-lint-action@v3
1818
with:
19-
version: latest
19+
version: v1.48.0

README.md

+9-11
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ problems. Please find the following packages:
1313
Please visit the official [Go Package Docs][pkgsite] for documentation and
1414
testable examples.
1515

16+
## Usage
17+
18+
To run a decision automation problem with SDK you need the [Nextmv CLI][cli].
19+
1620
## Get started
1721

1822
Please visit the [tour of SDK][tour] to get started with data store modeling.
@@ -25,16 +29,10 @@ Nextmv's SDK is meant to be used in Go projects. To download please run:
2529
go get github.com/nextmv-io/sdk
2630
```
2731

28-
## Usage
29-
30-
To run a decision automation problem Nextmv's SDK requires specific plugins.
31-
Please contact [support][support] for details on installing plugins. They are
32-
not required to `build`.
33-
3432
[pkgsite]: https://pkg.go.dev/github.com/nextmv-io/sdk
35-
[store]: ./store/
36-
[route]: ./route/
37-
[run]: ./run/
38-
[model]: ./model/
33+
[store]: ./store/README.md
34+
[route]: ./route/README.md
35+
[run]: ./run/README.md
36+
[model]: ./model/README.md
3937
[tour]: https://github.com/nextmv-io/tour
40-
[support]: https://www.nextmv.io/contact
38+
[cli]: https://docs.nextmv.io/development/cli

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v0.16.0-dev.0-6
1+
v0.17.0

mip/connect.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package mip
2+
3+
import (
4+
"sync"
5+
6+
"github.com/nextmv-io/sdk/plugin"
7+
)
8+
9+
const slug = "sdk"
10+
11+
var connected bool
12+
13+
var mtx sync.Mutex
14+
15+
func connect() {
16+
if connected {
17+
return
18+
}
19+
20+
mtx.Lock()
21+
defer mtx.Unlock()
22+
23+
if connected {
24+
return
25+
}
26+
connected = true
27+
28+
plugin.Connect(slug, "MIPNewSolveOptions", &newSolveOptions)
29+
plugin.Connect(slug, "MIPNewModel", &newModel)
30+
plugin.Connect(slug, "MIPNewSolver", &newSolver)
31+
}

mip/constraint.go

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package mip
2+
3+
// Sense defines the constraint operator between the left-hand-side
4+
// and the right-hand-side.
5+
type Sense int64
6+
7+
// Sense of a Constraint.
8+
const (
9+
// LessThanOrEqual is used to define a less than or equal constraint
10+
// c, _ := d.NewConstraint(mip.LessThanOrEqual, 123.4)
11+
//
12+
// c.NewTerm(1.0, x) // results in 1.0 * x <= 123.4 in solver
13+
LessThanOrEqual Sense = iota
14+
// Equal is used to define an equality constraint
15+
// c, _ := d.NewConstraint(mip.Equal, 123.4)
16+
//
17+
// c.NewTerm(1.0, x) // results in 1.0 * x = 123.4 in solver
18+
Equal
19+
// GreaterThanOrEqual is used to define a greater or equal constraint
20+
// c, _ := d.NewConstraint(mip. GreaterThanOrEqual, 123.4)
21+
//
22+
// c.NewTerm(1.0, x) // results in 1.0 * x >= 123.4 in solver
23+
GreaterThanOrEqual
24+
)
25+
26+
// Constraint specifies a relation between variables a solution has to comply
27+
// with. A constraint consists out of terms, a sense and a right hand side.
28+
//
29+
// For example:
30+
//
31+
// 2.5 * x + 3.5 * y <= 10.0
32+
//
33+
// The less than operator is the sense
34+
// The value 10.0 is the right hand side
35+
//
36+
// 2.5 * x and 3.5 * y are 2 terms in this example
37+
type Constraint interface {
38+
// NewTerm adds a term to the invoking constraint, invoking this API
39+
// multiple times for the same variable will take the sum of coefficients
40+
// of earlier added terms for that variable
41+
//
42+
// d := mip.NewModel()
43+
//
44+
// x, _ := d.NewContinuousVar(10.0, 100.0)
45+
//
46+
// c, _ := d.NewConstraint(mip.LessThanOrEqual, 123.4)
47+
//
48+
// c.NewTerm(1.0, x) // results in 1.0 * x <= 123.4 in solver
49+
// c.NewTerm(2.0, x) // results in 3.0 * x <= 123.4 in solver
50+
NewTerm(coefficient float64, variable Var) Term
51+
// RightHandSide returns the right-hand side of the invoking constraint.
52+
RightHandSide() float64
53+
// Sense returns the sense of the invoking constraint.
54+
Sense() Sense
55+
// Terms returns a copy slice of terms of the invoking constraint,
56+
// each variable is reported once. If the same variable has been
57+
// added multiple times the sum of coefficients is reported for that
58+
// variable.
59+
Terms() Terms
60+
}
61+
62+
// Constraints slice of Constraint instances.
63+
type Constraints []Constraint

mip/doc.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
Package mip provides a general interface for solving mixed integer linear
3+
optimization problems using a variety of back-end solvers. The base interface is
4+
the Model which is a collection of variables, constraints and an objective. The
5+
interface Solver is constructed by mip.NewSolver. The solver can be invoked
6+
using Solver.Solve and returns a Solution.
7+
8+
A new Model is created:
9+
10+
d := mip.NewModel()
11+
12+
Var instances are created and added to the model:
13+
14+
x, _ := d.NewContinuousVar(0.0, 100.0)
15+
y, _ := d.NewIntegerVar(0, 100)
16+
17+
Constraint instances are created and added to the model:
18+
19+
c1, _ := d.NewConstraint(mip.GreaterThanOrEqual, 1.0)
20+
c1.NewTerm(-2.0, x)
21+
c1.NewTerm(2.0, y)
22+
23+
c2, _ := d.NewConstraint(mip.LessThanOrEqual, 13.0)
24+
c2.NewTerm(-8.0, x)
25+
c2.NewTerm(10.0, y)
26+
27+
The Objective is specified:
28+
29+
d.Objective().SetMaximize()
30+
d.Objective().NewTerm(1.0, x)
31+
d.Objective().NewTerm(1.0, y)
32+
33+
A Solver is created and invoked to produce a Solution:
34+
35+
solver, _ := mip.NewSolver("backend_solver_identifier", mipModel)
36+
solution, _ := solver.Solve(mip.DefaultSolverOptions())
37+
*/
38+
package mip

mip/example_constraint_test.go

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package mip_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/nextmv-io/sdk/mip"
8+
)
9+
10+
func ExampleConstraint_greaterThanEqual() {
11+
model := mip.NewModel()
12+
13+
c, _ := model.NewConstraint(mip.GreaterThanOrEqual, 1.0)
14+
15+
fmt.Println(c.Sense())
16+
fmt.Println(c.RightHandSide())
17+
// Output:
18+
// 2
19+
// 1
20+
}
21+
22+
func ExampleConstraint_equal() {
23+
model := mip.NewModel()
24+
25+
c, _ := model.NewConstraint(mip.Equal, 1.0)
26+
27+
fmt.Println(c.Sense())
28+
fmt.Println(c.RightHandSide())
29+
// Output:
30+
// 1
31+
// 1
32+
}
33+
34+
func ExampleConstraint_lessThanOrEqual() {
35+
model := mip.NewModel()
36+
37+
c, _ := model.NewConstraint(mip.LessThanOrEqual, 1.0)
38+
39+
fmt.Println(c.Sense())
40+
fmt.Println(c.RightHandSide())
41+
// Output:
42+
// 0
43+
// 1
44+
}
45+
46+
func ExampleConstraint_terms() {
47+
model := mip.NewModel()
48+
49+
v, _ := model.NewBinaryVar()
50+
c, _ := model.NewConstraint(mip.Equal, 1.0)
51+
52+
t1 := c.NewTerm(1.0, v)
53+
t2 := c.NewTerm(2.0, v)
54+
55+
fmt.Println(t1.Var().Index())
56+
fmt.Println(t1.Coefficient())
57+
fmt.Println(t2.Coefficient())
58+
fmt.Println(len(c.Terms()))
59+
fmt.Println(c.Terms()[0].Coefficient())
60+
// Output:
61+
// 0
62+
// 1
63+
// 2
64+
// 1
65+
// 3
66+
}
67+
68+
func benchmarkNewConstraintNewTerms(nrTerms int, b *testing.B) {
69+
model := mip.NewModel()
70+
v, _ := model.NewContinuousVar(1.0, 2.0)
71+
72+
for i := 0; i < b.N; i++ {
73+
c, _ := model.NewConstraint(mip.Equal, 1.0)
74+
for i := 0; i < nrTerms; i++ {
75+
c.NewTerm(1.0, v)
76+
}
77+
}
78+
}
79+
80+
func BenchmarkNewConstraintNewTerms0(b *testing.B) {
81+
benchmarkNewConstraintNewTerms(0, b)
82+
}
83+
84+
func BenchmarkNewConstraintNewTerms1(b *testing.B) {
85+
benchmarkNewConstraintNewTerms(1, b)
86+
}
87+
88+
func BenchmarkNewConstraintNewTerms2(b *testing.B) {
89+
benchmarkNewConstraintNewTerms(2, b)
90+
}
91+
92+
func BenchmarkNewConstraintNewTerms4(b *testing.B) {
93+
benchmarkNewConstraintNewTerms(4, b)
94+
}
95+
96+
func BenchmarkNewConstraintNewTerms8(b *testing.B) {
97+
benchmarkNewConstraintNewTerms(8, b)
98+
}
99+
100+
func BenchmarkNewConstraintNewTerms16(b *testing.B) {
101+
benchmarkNewConstraintNewTerms(16, b)
102+
}
103+
104+
func BenchmarkNewConstraintNewTerms32(b *testing.B) {
105+
benchmarkNewConstraintNewTerms(32, b)
106+
}

mip/example_model_test.go

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package mip_test
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/nextmv-io/sdk/mip"
7+
)
8+
9+
func ExampleModel_empty() {
10+
model := mip.NewModel()
11+
12+
fmt.Println(len(model.Constraints()))
13+
fmt.Println(len(model.Vars()))
14+
fmt.Println(len(model.Objective().Terms()))
15+
fmt.Println(model.Objective().IsMaximize())
16+
// Output:
17+
// 0
18+
// 0
19+
// 0
20+
// false
21+
}
22+
23+
func ExampleModel_queries() {
24+
model := mip.NewModel()
25+
26+
_, err := model.NewBinaryVar()
27+
if err != nil {
28+
panic(err)
29+
}
30+
_, err = model.NewContinuousVar(1.0, 2.0)
31+
if err != nil {
32+
panic(err)
33+
}
34+
_, err = model.NewBinaryVar()
35+
if err != nil {
36+
panic(err)
37+
}
38+
39+
_, err = model.NewConstraint(mip.Equal, 0.0)
40+
if err != nil {
41+
panic(err)
42+
}
43+
44+
fmt.Println(len(model.Vars()))
45+
fmt.Println(len(model.Constraints()))
46+
// Output:
47+
// 3
48+
// 1
49+
}

0 commit comments

Comments
 (0)