예제 #1
0
func updateUntilOptimalSolutionsFound(lambda float64, m markov.MarkovChain, node *coupling.Node, exact [][]bool, visited [][]bool, d [][]float64, c coupling.Coupling, TPSolver func(markov.MarkovChain, *coupling.Node, [][]float64, float64, int, int), solvedNodes []*coupling.Node) {
	log.Printf("find optimal for: (%v,%v)", node.S, node.T)
	min, i, j := uvmethod.Run(node, d)
	// if min is negative, we can further improve it, so we update it using the TPSolver and iterated until we cannot improve it further
	for min < 0 && !utils.ApproxEqual(min, 0) {
		previ, prevj := i, j
		TPSolver(m, node, d, min, i, j)
		setpair.Setpair(m, node, exact, visited, d, &c)
		disc.Disc(lambda, node, exact, d, &c)

		min, i, j = uvmethod.Run(node, d)

		if previ == i && prevj == j && min < 0 {
			break
		}
	}

	// append solved nodes such that we do not end up recurively calling nodes that have already been found to be optimal
	solvedNodes = append(solvedNodes, node)

	for _, row := range node.Adj {
		for _, edge := range row {
			if edge.To.Adj == nil {
				// if the node do not have an adjacency matrix or is exact, we do not have to proccess it
				continue
			}
			if coupling.IsNodeInSlice(edge.To, solvedNodes) {
				// if the node has already been proccesses, we do not have to do it again
				continue
			}

			updateUntilOptimalSolutionsFound(lambda, m, edge.To, exact, visited, d, c, TPSolver, solvedNodes)
		}
	}

	exact[node.S][node.T] = true
	exact[node.S][node.T] = true

	return
}
예제 #2
0
func TestOptimalSolutionFound(t *testing.T) {
	c, m, visited, exact, d := coupling.SetUpTest()
	d = sets.InitD(len(m.Transitions))

	w := matching.FindFeasibleMatching(m, 0, 3, &c)
	setpair.Setpair(m, w, exact, visited, d, &c)

	// the expected solution is not precice since the markov chain used do not use precise fractions
	expected := [][]float64{
		[]float64{0, 0.33, 0},
		[]float64{0, 0, 0.33},
		[]float64{0.17, 0, 0},
		[]float64{0.16, 0, 0.01}}

	min, i, j := uvmethod.Run(w, d)

	Solve(m, w, d, min, i, j)

	for i := range w.Adj {
		for j := range w.Adj[0] {
			assert.True(t, utils.ApproxEqual(expected[i][j], w.Adj[i][j].Prob), "the optimal probability found was not what we expected")
		}
	}
}