Пример #1
0
func TopoSpec(c gospec.Context) {
	c.Specify("Check toposort on linked list", func() {
		a := adag{
			[]int{1},
			[]int{2},
			[]int{3},
			[]int{4},
			[]int{5},
			[]int{6},
			[]int{},
		}
		order := algorithm.TopoSort(a)
		checkOrder(c, a, order)
	})

	c.Specify("multi-edges don't mess up toposort", func() {
		a := adag{
			[]int{1, 1, 1},
			[]int{},
		}
		order := algorithm.TopoSort(a)
		checkOrder(c, a, order)
	})

	c.Specify("Check toposort on a more complicated digraph", func() {
		a := adag{
			[]int{8, 7, 4}, // 0
			[]int{5},
			[]int{0},
			[]int{9},
			[]int{14},
			[]int{15}, // 5
			[]int{1},
			[]int{},
			[]int{},
			[]int{13},
			[]int{3}, // 10
			[]int{12},
			[]int{18},
			[]int{16},
			[]int{},
			[]int{14}, // 15
			[]int{},
			[]int{},
			[]int{},
			[]int{},
			[]int{},
		}
		order := algorithm.TopoSort(a)
		checkOrder(c, a, order)
	})

	c.Specify("A cyclic digraph returns nil", func() {
		a := adag{
			[]int{8, 7, 4}, // 0
			[]int{5},
			[]int{0},
			[]int{9},
			[]int{14},
			[]int{15}, // 5
			[]int{1},
			[]int{},
			[]int{20},
			[]int{13},
			[]int{3}, // 10
			[]int{12},
			[]int{18},
			[]int{16},
			[]int{2},
			[]int{14}, // 15
			[]int{6},
			[]int{},
			[]int{},
			[]int{},
			[]int{},
		}
		order := algorithm.TopoSort(a)
		c.Expect(len(order), Equals, 0)
	})
}
Пример #2
0
func order(input []RectObject) []int {
	defer func() {
		if err := recover(); err != nil {
			base.Error().Printf("Failure in sorting: %v", err)
		}
	}()
	var minx, miny int
	for _, r := range input {
		x, y := r.Pos()
		if x < minx {
			minx = x
		}
		if y < miny {
			miny = y
		}
	}

	ra := make([]RectObject, len(input))
	for i, r := range input {
		x, y := r.Pos()
		dx, dy := r.Dims()
		ra[i] = arog{x - minx + 1, y - miny + 1, dx, dy}
	}

	mapping := make(map[RectObject]int, len(ra))
	for i := range ra {
		mapping[ra[i]] = i
	}
	var e endpointArray
	for i := range ra {
		e = append(e, endpoint{RectObject: ra[i], first: false})
		e = append(e, endpoint{RectObject: ra[i], first: true})
	}
	sort.Sort(e)
	var sweep_pos int
	less_func := func(_a, _b interface{}) bool {
		a := _a.(RectObject)
		b := _b.(RectObject)
		ax, ay, ax2, ay2 := firstAndLastPoints(a)
		da := ax*ax + ay*ay
		da2 := ax2*ax2 + ay2*ay2
		w_a := width(a.Dims())
		bx, by, bx2, by2 := firstAndLastPoints(b)
		db := bx*bx + by*by
		db2 := bx2*bx2 + by2*by2
		w_b := width(b.Dims())
		va := w_b * (w_a*da + (da2-da)*(sweep_pos-pos(ax, ay)))
		vb := w_a * (w_b*db + (db2-db)*(sweep_pos-pos(bx, by)))
		return va < vb
	}
	l := llrb.New(less_func)

	dag := make(adag, len(ra))

	for _, p := range e {
		if p.first {
			sweep_pos = pos(firstPoint(p.RectObject))
			l.ReplaceOrInsert(p.RectObject)
			lower := l.LowerBound(p.RectObject)
			upper := l.UpperBound(p.RectObject)
			if lower != nil {
				index := mapping[lower.(RectObject)]
				dag[index] = append(dag[index], mapping[p.RectObject])
			}
			if upper != nil {
				index := mapping[p.RectObject]
				dag[index] = append(dag[index], mapping[upper.(RectObject)])
			}
		} else {
			l.Delete(p.RectObject)
		}
	}
	return algorithm.TopoSort(dag)
}