Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#12: Adds -cycles and -matrix flags. #13

Merged
merged 1 commit into from
Aug 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## v0.2.0

* #12: Add cycle and matrix output to lsap command
* `lsap` provides `-cycles` and `-matrix` flags for assignment forms.
* `ap.Matrix` is now a `[][]int8` instead of `[][]bool`.
* #10: Add reduced cost and dual price output to lsap command
* `lsap` uses `-dual` and `-rc` flags for dual prices and reduced costs.
* #6: Provide Cycle struct and method
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,12 @@ Usage:
]
EOF
Flags:
-cycles
output cyclic assignment form
-dual
output dual prices
-matrix
output matrix assignment form
-rc
output reduced cost matrix
```
10 changes: 10 additions & 0 deletions cmd/lsap/lsap.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ func usage() {
}

func main() {
cycles := flag.Bool("cycles", false, "output cyclic assignment form")
dual := flag.Bool("dual", false, "output dual prices")
matrix := flag.Bool("matrix", false, "output matrix assignment form")
rc := flag.Bool("rc", false, "output reduced cost matrix")
flag.Usage = usage
flag.Parse()
Expand All @@ -44,10 +46,18 @@ func main() {
"cost": a.Cost(),
}

if *cycles {
out["cycles"] = p.Cycles()
}

if *dual {
out["dual"] = a.DualPrices()
}

if *matrix {
out["matrix"] = p.Matrix()
}

if *rc {
rcMatrix := make([][]int64, len(p))
for u := range p {
Expand Down
4 changes: 2 additions & 2 deletions cycles.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (c Cycles) Inverse() Cycles {
func (c Cycles) Matrix() Matrix {
m := make(Matrix, c.len())
for u := range m {
m[u] = make([]bool, len(m))
m[u] = make([]int8, len(m))
}

for _, cycle := range c {
Expand All @@ -54,7 +54,7 @@ func (c Cycles) Matrix() Matrix {
if i < len(cycle)-1 {
v = cycle[i+1]
}
m[u][v] = true
m[u][v] = 1
}
}

Expand Down
8 changes: 1 addition & 7 deletions cycles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,6 @@ func ExampleCycles() {
// Output:
// [[0 1] [2] [3 6 4 5]]
// [[0 1] [2] [3 5 4 6]]
// - X - - - - -
// X - - - - - -
// - - X - - - -
// - - - - - - X
// - - - - - X -
// - - - X - - -
// - - - - X - -
// [[0 1 0 0 0 0 0] [1 0 0 0 0 0 0] [0 0 1 0 0 0 0] [0 0 0 0 0 0 1] [0 0 0 0 0 1 0] [0 0 0 1 0 0 0] [0 0 0 0 1 0 0]]
// [1 0 2 6 5 3 4]
}
25 changes: 2 additions & 23 deletions matrix.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package ap

import "strings"

// Matrix representation of an assignment. If u is assigned to v, then M[u][v]
// is true. Each row and each column has exactly one true element.
type Matrix [][]bool
type Matrix [][]int8

// Cycles converts a permutation matrix to a cyclic representation.
func (m Matrix) Cycles() Cycles {
Expand All @@ -21,30 +19,11 @@ func (m Matrix) Permutation() Permutation {
p := make(Permutation, len(m))
for u, mu := range m {
for v, assigned := range mu {
if assigned {
if assigned == 1 {
p[u] = v
break
}
}
}
return p
}

func (m Matrix) String() string {
s := make([]string, len(m))
for u, mu := range m {
s[u] = rowString(mu)
}
return strings.Join(s, "\n")
}

func rowString(row []bool) string {
s := make([]string, len(row))
for i, v := range row {
s[i] = "-"
if v {
s[i] = "X"
}
}
return strings.Join(s, " ")
}
30 changes: 9 additions & 21 deletions matrix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,22 @@ import (

func ExampleMatrix() {
m := ap.Matrix{
{false, true, false, false, false, false, false},
{true, false, false, false, false, false, false},
{false, false, true, false, false, false, false},
{false, false, false, false, false, false, true},
{false, false, false, false, false, true, false},
{false, false, false, true, false, false, false},
{false, false, false, false, true, false, false},
{0, 1, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 1, 0, 0},
}
fmt.Println(m)
fmt.Println(m.Cycles())
fmt.Println(m.Inverse())
fmt.Println(m.Permutation())

// Output:
// - X - - - - -
// X - - - - - -
// - - X - - - -
// - - - - - - X
// - - - - - X -
// - - - X - - -
// - - - - X - -
// [[0 1 0 0 0 0 0] [1 0 0 0 0 0 0] [0 0 1 0 0 0 0] [0 0 0 0 0 0 1] [0 0 0 0 0 1 0] [0 0 0 1 0 0 0] [0 0 0 0 1 0 0]]
// [[0 1] [2] [3 6 4 5]]
// - X - - - - -
// X - - - - - -
// - - X - - - -
// - - - - - X -
// - - - - - - X
// - - - - X - -
// - - - X - - -
// [[0 1 0 0 0 0 0] [1 0 0 0 0 0 0] [0 0 1 0 0 0 0] [0 0 0 0 0 1 0] [0 0 0 0 0 0 1] [0 0 0 0 1 0 0] [0 0 0 1 0 0 0]]
// [1 0 2 6 5 3 4]
}
4 changes: 2 additions & 2 deletions permutation.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ func (p Permutation) Inverse() Permutation {
func (p Permutation) Matrix() Matrix {
m := make(Matrix, len(p))
for u, v := range p {
m[u] = make([]bool, len(p))
m[u][v] = true
m[u] = make([]int8, len(p))
m[u][v] = 1
}
return m
}
8 changes: 1 addition & 7 deletions permutation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,5 @@ func ExamplePermutation() {
// [1 0 2 6 5 3 4]
// [[0 1] [2] [3 6 4 5]]
// [1 0 2 5 6 4 3]
// - X - - - - -
// X - - - - - -
// - - X - - - -
// - - - - - - X
// - - - - - X -
// - - - X - - -
// - - - - X - -
// [[0 1 0 0 0 0 0] [1 0 0 0 0 0 0] [0 0 1 0 0 0 0] [0 0 0 0 0 0 1] [0 0 0 0 0 1 0] [0 0 0 1 0 0 0] [0 0 0 0 1 0 0]]
}