-
Notifications
You must be signed in to change notification settings - Fork 74
/
Copy pathengine_multi.go
90 lines (70 loc) · 1.88 KB
/
engine_multi.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package optimus
import (
"context"
"fmt"
"go.uber.org/zap"
"golang.org/x/sync/errgroup"
)
type bruteConfig struct {
Match int `yaml:"match" default:"128"`
Model optimizationMethodFactory `yaml:"model"`
}
type BatchModelConfig struct {
Brute bruteConfig `yaml:"brute"`
Methods []optimizationMethodFactory `yaml:"models"`
}
type BatchModelFactory struct {
BatchModelConfig
}
func (m *BatchModelFactory) Config() interface{} {
return &m.BatchModelConfig
}
func (m *BatchModelFactory) Create(orders, matchedOrders []*MarketOrder, log *zap.SugaredLogger) OptimizationMethod {
if len(matchedOrders) <= m.Brute.Match {
return m.Brute.Model.Create(orders, matchedOrders, log)
}
methods := make([]OptimizationMethod, len(m.Methods))
for id := range m.Methods {
methods[id] = m.Methods[id].Create(orders, matchedOrders, log)
}
return &BatchModel{
Methods: methods,
Log: log,
}
}
type BatchModel struct {
Methods []OptimizationMethod
Log *zap.SugaredLogger
}
func (m *BatchModel) Optimize(ctx context.Context, knapsack *Knapsack, orders []*MarketOrder) error {
if len(m.Methods) == 0 {
return fmt.Errorf("no optimization methods found")
}
wg, ctx := errgroup.WithContext(ctx)
knapsacks := make([]*Knapsack, 0, len(m.Methods))
for range m.Methods {
knapsacks = append(knapsacks, knapsack.Clone())
}
for id := range m.Methods {
method := m.Methods[id]
knapsack := knapsacks[id]
wg.Go(func() error {
return method.Optimize(ctx, knapsack, orders)
})
}
if err := wg.Wait(); err != nil {
return err
}
winnerId := 0
winnerPrice := 0.0
for id := range knapsacks {
price := knapsacks[id].PPSf64()
m.Log.Debugf("[%d] %T optimization resulted in %.12f price", id, m.Methods[id], price)
if price > winnerPrice {
winnerId = id
winnerPrice = price
}
}
*knapsack = *knapsacks[winnerId].Clone()
return nil
}