Skip to content

Commit

Permalink
#12: Adds -cycles and -matrix flags. (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanjoneil authored Aug 11, 2019
1 parent 0333e67 commit ef3a391
Show file tree
Hide file tree
Showing 9 changed files with 34 additions and 62 deletions.
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]]
}

0 comments on commit ef3a391

Please sign in to comment.