Skip to content

Commit 5bdbb70

Browse files
committed
feature: add core demo7.
1 parent b6bcfdc commit 5bdbb70

File tree

4 files changed

+190
-2
lines changed

4 files changed

+190
-2
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ $$
6969
$$
7070

7171
$$
72-
y \leq \sum_{i} x_{i}, \\; \forall i
72+
y \leq \sum_{i} x_{i}
7373
$$
7474

7575
$$

README_ch.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ $$
6868
$$
6969

7070
$$
71-
y \leq \sum_{i} x_{i}, \\; \forall i
71+
y \leq \sum_{i} x_{i}
7272
$$
7373

7474
$$
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
package fuookami.ospf.kotlin.example.core_demo
2+
3+
import fuookami.ospf.kotlin.utils.math.*
4+
import fuookami.ospf.kotlin.utils.error.*
5+
import fuookami.ospf.kotlin.utils.concept.*
6+
import fuookami.ospf.kotlin.utils.functional.*
7+
import fuookami.ospf.kotlin.utils.multi_array.*
8+
import fuookami.ospf.kotlin.core.frontend.variable.*
9+
import fuookami.ospf.kotlin.core.frontend.expression.monomial.*
10+
import fuookami.ospf.kotlin.core.frontend.expression.polynomial.*
11+
import fuookami.ospf.kotlin.core.frontend.expression.symbol.*
12+
import fuookami.ospf.kotlin.core.frontend.inequality.*
13+
import fuookami.ospf.kotlin.core.frontend.model.mechanism.*
14+
import fuookami.ospf.kotlin.core.backend.plugins.scip.*
15+
16+
data object Demo7 {
17+
data class Store(
18+
val demand: Flt64
19+
) : AutoIndexed(Store::class)
20+
21+
data class Warehouse(
22+
val stowage: Flt64,
23+
val cost: Map<Store, Flt64>
24+
) : AutoIndexed(Warehouse::class)
25+
26+
private val stores = listOf(
27+
Store(Flt64(200.0)),
28+
Store(Flt64(400.0)),
29+
Store(Flt64(600.0)),
30+
Store(Flt64(300.0))
31+
)
32+
private val warehouses = listOf(
33+
Warehouse(
34+
Flt64(510.0), mapOf(
35+
stores[0] to Flt64(12.0),
36+
stores[1] to Flt64(13.0),
37+
stores[2] to Flt64(21.0),
38+
stores[3] to Flt64(7.0)
39+
)
40+
),
41+
Warehouse(
42+
Flt64(470.0), mapOf(
43+
stores[0] to Flt64(14.0),
44+
stores[1] to Flt64(17.0),
45+
stores[2] to Flt64(8.0),
46+
stores[3] to Flt64(18.0)
47+
)
48+
),
49+
Warehouse(
50+
Flt64(520.0), mapOf(
51+
stores[0] to Flt64(10.0),
52+
stores[1] to Flt64(11.0),
53+
stores[2] to Flt64(9.0),
54+
stores[3] to Flt64(15.0)
55+
)
56+
)
57+
)
58+
59+
private lateinit var x: UIntVariable2
60+
61+
private lateinit var cost: LinearSymbol
62+
private lateinit var shipment: LinearSymbols1
63+
private lateinit var purchase: LinearSymbols1
64+
65+
private val metaModel: LinearMetaModel = LinearMetaModel("demo7")
66+
67+
private val subProcesses = listOf(
68+
Demo7::initVariable,
69+
Demo7::initSymbol,
70+
Demo7::initObject,
71+
Demo7::initConstraint,
72+
Demo7::solve,
73+
Demo7::analyzeSolution
74+
)
75+
76+
suspend operator fun invoke(): Try {
77+
for (process in subProcesses) {
78+
when (val result = process()) {
79+
is Ok -> {}
80+
81+
is Failed -> {
82+
return Failed(result.error)
83+
}
84+
}
85+
}
86+
return ok
87+
}
88+
89+
private suspend fun initVariable(): Try {
90+
x = UIntVariable2("x", Shape2(warehouses.size, stores.size))
91+
for (w in warehouses) {
92+
for (s in stores) {
93+
x[w, s].name = "${x.name}_(${w.index},${s.index})"
94+
}
95+
}
96+
metaModel.addVars(x)
97+
return ok
98+
}
99+
100+
private suspend fun initSymbol(): Try {
101+
cost = LinearExpressionSymbol(sum(warehouses.map { w ->
102+
sum(stores.filter { w.cost.contains(it) }.map { s ->
103+
w.cost[s]!! * x[w, s]
104+
})
105+
}), "cost")
106+
metaModel.addSymbol(cost)
107+
108+
shipment = LinearSymbols1(
109+
"shipment",
110+
Shape1(warehouses.size)
111+
) { (i, _) ->
112+
val w = warehouses[i]
113+
LinearExpressionSymbol(
114+
sum(stores.filter { w.cost.contains(it) }.map { s -> x[w, s] }),
115+
"shipment_${w.index}"
116+
)
117+
}
118+
metaModel.addSymbols(shipment)
119+
120+
purchase = LinearSymbols1(
121+
"purchase",
122+
Shape1(stores.size)
123+
) { (i, _) ->
124+
val s = stores[i]
125+
LinearExpressionSymbol(
126+
sum(warehouses.filter { w -> w.cost.contains(s) }.map { w -> x[w, s] }),
127+
"purchase_${s.index}"
128+
)
129+
}
130+
metaModel.addSymbols(purchase)
131+
return ok
132+
}
133+
134+
private suspend fun initObject(): Try {
135+
metaModel.minimize(LinearPolynomial(cost),"cost")
136+
return ok
137+
}
138+
139+
private suspend fun initConstraint(): Try {
140+
for(w in warehouses){
141+
metaModel.addConstraint(
142+
shipment[w] leq w.stowage,"stowage_${w.index}"
143+
)
144+
}
145+
146+
for(s in stores){
147+
metaModel.addConstraint(
148+
purchase[s] geq s.demand ,"demand_${s.index}"
149+
)
150+
}
151+
return ok
152+
}
153+
154+
private suspend fun solve(): Try {
155+
metaModel.export("1.opm")
156+
157+
val solver = SCIPLinearSolver()
158+
when (val ret = solver(metaModel)) {
159+
is Ok -> {
160+
metaModel.tokens.setSolution(ret.value.solution)
161+
}
162+
163+
is Failed -> {
164+
return Failed(ret.error)
165+
}
166+
}
167+
return ok
168+
}
169+
170+
private suspend fun analyzeSolution(): Try {
171+
val solution = stores.associateWith { warehouses.associateWith { Flt64.zero }.toMutableMap() }
172+
for (token in metaModel.tokens.tokens) {
173+
if (token.result!! geq Flt64.one
174+
&& token.variable.belongsTo(x)
175+
) {
176+
val warehouse = warehouses[token.variable.vectorView[0]]
177+
val store = stores[token.variable.vectorView[1]]
178+
solution[store]!![warehouse] = solution[store]!![warehouse]!! + token.result!!
179+
}
180+
}
181+
return ok
182+
}
183+
}

examples/ospf-kotlin-example/src/test/fuookami/ospf/kotlin/example/CoreDemoTest.kt

+5
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,9 @@ class CoreDemoTest {
3434
fun runDemo6() {
3535
assert(runBlocking { Demo6().ok })
3636
}
37+
38+
@Test
39+
fun runDemo7() {
40+
assert(runBlocking { Demo7().ok })
41+
}
3742
}

0 commit comments

Comments
 (0)