Exemple #1
0
func PseudoMetric(m markov.MarkovChain, lambda float64, TPSolver func(markov.MarkovChain, *coupling.Node, [][]float64, float64, int, int)) [][]float64 {
	// initialize all the sets and the coupling
	n := len(m.Transitions)
	tocompute := sets.InitToCompute(len(m.Transitions))
	visited := sets.MakeMatrix(n)
	exact := sets.MakeMatrix(n)
	c := coupling.New()
	d := InitD(n)

	for !sets.EmptySet(tocompute) {
		var node *coupling.Node
		s, t := extractrandomfromset(tocompute)
		s, t = utils.GetMinMax(s, t)
		tocompute[s][t], tocompute[t][s] = false, false
		log.Printf("Run with node: (%v,%v)", s, t)

		if m.Labels[s] != m.Labels[t] {
			// s and t have the same label, so we set its distance to 0, and its exact and visited to true
			log.Printf("State %v and %v had different labels", s, t)
			d[s][t] = 1
			exact[s][t] = true
			visited[s][t] = true
			continue
		} else if s == t {
			// s and t are the same state, so we set its distance to 1, and its exact and visited to true
			log.Printf("State %v %v) was the same state", s, t)
			d[s][t] = 0
			exact[s][t] = true
			visited[s][t] = true
			continue
		}

		// since the pair of states is not the same and share a label, we have to further process it
		// try to find the correpsonding node in the coupling
		node = coupling.FindNode(s, t, &c)

		if node == nil {
			// if FindNode returned a nil pointer, the node does not exist, and we have to make it
			node = matching.FindFeasibleMatching(m, s, t, &c)
			setpair.Setpair(m, node, exact, visited, d, &c)
		} else if node.Adj == nil {
			// if FindNode did return a node reference, but its adjacency matrix(matching) is nil, we have to create it
			node = matching.FindFeasibleMatching(m, s, t, &c)
			setpair.Setpair(m, node, exact, visited, d, &c)
		}

		disc.Disc(lambda, node, exact, d, &c)

		updateUntilOptimalSolutionsFound(lambda, m, node, exact, visited, d, c, TPSolver, []*coupling.Node{})

		removeExactEdges(node, exact)

		// remove everything that has been computed to exact, such that we will not try to solve it again
		tocompute = *sets.DifferensReal(&tocompute, &exact)
	}

	return d
}
func TestCorrectSuccessorFound(t *testing.T) {
	c := coupling.New()
	m := coupling.SetUpMarkov()

	w := FindFeasibleMatching(m, 0, 3, &c)
	log.Println(w.Adj[2][2].To)
	assert.True(t, coupling.IsNodeInSlice(w, w.Adj[0][0].To.Succ), "node (0,3) did not become a successor for (0,1)")
	assert.True(t, coupling.IsNodeInSlice(w, w.Adj[1][1].To.Succ), "node (0,3) did not become a successor for (1,2)")
	assert.True(t, coupling.IsNodeInSlice(w, w.Adj[2][2].To.Succ), "node (0,3) did not become a successor for (2,3)")
	assert.True(t, coupling.IsNodeInSlice(w, w.Adj[3][2].To.Succ), "node (0,3) did not become a successor for (2,5)")
	assert.False(t, coupling.IsNodeInSlice(w, w.Adj[0][1].To.Succ), "node (0,3) become a successor for (1,1)")
	assert.False(t, coupling.IsNodeInSlice(w, w.Adj[1][0].To.Succ), "node (0,3) become a successor for (0,2)")
}
func TestCorrectBasicCount(t *testing.T) {
	c := coupling.New()
	m := coupling.SetUpMarkov()

	w := matching.FindFeasibleMatching(m, 0, 3, &c)

	SteppingStone(w, 2, 0)

	assert.Equal(t, len(w.Adj)+(len(w.Adj[0])-1), w.BasicCount, "the number of basic cell is not correct")

	SteppingStone(w, 3, 0)

	assert.Equal(t, len(w.Adj)+(len(w.Adj[0])-2), w.BasicCount, "the number of basic cell is not correct")
}
func setUpCoupling() coupling.Coupling {
	c := coupling.New()
	n1 := coupling.Node{S: 0, T: 0}
	n2 := coupling.Node{S: 0, T: 1}
	n3 := coupling.Node{S: 1, T: 0}
	n4 := coupling.Node{S: 1, T: 1}
	e1 := coupling.Edge{&n1, 0.5, true}
	e2 := coupling.Edge{&n2, 0.2, true}
	e3 := coupling.Edge{&n3, 0, false}
	e4 := coupling.Edge{&n4, 0.3, true}
	n1.Succ = []*coupling.Node{&n1, &n2, &n4}
	n2.Succ = []*coupling.Node{&n2, &n4, &n1}
	n4.Succ = []*coupling.Node{&n2, &n1, &n4}
	n2.Adj = [][]*coupling.Edge{[]*coupling.Edge{&e1, &e2}, []*coupling.Edge{&e3, &e4}}
	c.Nodes = []*coupling.Node{&n1, &n2, &n3, &n4}

	return c
}
func TestCorrectMatchingFound(t *testing.T) {
	expected := [][]float64{
		[]float64{0.33, 0.0, 0.0},
		[]float64{0.0, 0.33, 0.0},
		[]float64{0.0, 0.0, 0.17},
		[]float64{0.0, 0.0, 0.17}}

	c := coupling.New()
	m := coupling.SetUpMarkov()

	w := FindFeasibleMatching(m, 0, 3, &c)

	for i := 0; i < len(expected); i++ {
		for j := 0; j < len(expected[0]); j++ {
			assert.True(t, utils.ApproxEqual(expected[i][j], w.Adj[i][j].Prob), "the correct probability were not inserted")
		}
	}
}
func TestCorrectBasicFound(t *testing.T) {
	expected := [][]bool{
		[]bool{true, true, false},
		[]bool{false, true, true},
		[]bool{false, false, true},
		[]bool{false, false, true}}

	c := coupling.New()
	m := coupling.SetUpMarkov()

	w := FindFeasibleMatching(m, 0, 3, &c)

	for i := 0; i < len(expected); i++ {
		for j := 0; j < len(expected[0]); j++ {
			assert.Equal(t, expected[i][j], w.Adj[i][j].Basic, "the cell were not correctly set to either basic or non-basic")
		}
	}

	assert.Equal(t, len(w.Adj)+(len(w.Adj[0])-1), w.BasicCount, "the number of basic cell is not correct")
}