Beispiel #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
}
Beispiel #2
0
//Retrieves d values into the buffer given, based on indexes from rowused and columnused
func retrieveDValues(buffer *bytes.Buffer, d [][]float64, rowused, columnused []int) {
	for _, row := range rowused {
		for _, column := range columnused {
			u, v := utils.GetMinMax(row, column) //The same d value may be used two times
			log.Printf("Retrieving d[%v][%v] = %v", u, v, d[u][v])
			(*buffer).WriteString(strconv.FormatFloat(d[u][v], 'f', -1, 64))
			(*buffer).WriteString(" ")
		}
	}
}
func filloutAdj(row, col []int, lenrow, lencol int, w [][]*coupling.Edge, c *coupling.Coupling) {
	for i := 0; i < lenrow; i++ {
		for j := 0; j < lencol; j++ {
			var node *coupling.Node
			s, t := utils.GetMinMax(row[i], col[j])

			node = coupling.FindNode(s, t, c)

			if node == nil {
				node = &coupling.Node{S: s, T: t, Succ: []*coupling.Node{}}
				c.Nodes = append(c.Nodes, node)
			}

			w[i][j] = &coupling.Edge{To: node}
		}
	}
}
Beispiel #4
0
func Setpair(m markov.MarkovChain, w *coupling.Node, exact [][]bool, visited [][]bool, dist [][]float64, c *coupling.Coupling) {
	log.Printf("Setting pair for %v and %v", w.S, w.T)
	visited[w.S][w.T] = true

	for _, edge := range findDemandedPairs(w, visited) {
		u, v := utils.GetMinMax(edge.To.S, edge.To.T)

		visited[u][v] = true

		if u == v {
			log.Printf("%v and %v is the same state ", u, v)
			dist[u][v] = 0
			exact[u][v] = true
		} else if m.Labels[u] != m.Labels[v] {
			log.Printf("%v and %v have different labels ", u, v)
			dist[u][v] = 1
			exact[u][v] = true
		} else if !(exact[u][v] || exact[v][u]) {
			log.Printf("%v and %v have the same label ", u, v)
			w2 := matching.FindFeasibleMatching(m, u, v, c)
			Setpair(m, w2, exact, visited, dist, c)
		}
	}
}
func FindFeasibleMatching(m markov.MarkovChain, u int, v int, c *coupling.Coupling) *coupling.Node {
	n := len(m.Transitions[u])

	u, v = utils.GetMinMax(u, v)

	// tries to find the node (u,v) in c, if not make a new one and add to c
	node := coupling.FindNode(u, v, c)

	if node == nil {
		node = &coupling.Node{S: u, T: v, Succ: []*coupling.Node{}}
		c.Nodes = append(c.Nodes, node)
	}

	log.Printf("copy the transitions from the states %v and %v", u, v)
	uTransitions := make([]float64, n, n)
	vTransitions := make([]float64, n, n)

	// copies the transitions of u and v such that we do not makes changes in the markov chain
	copy(uTransitions, m.Transitions[u])
	copy(vTransitions, m.Transitions[v])

	// finds the length of the rows and columns in the matching for u and v
	lenrow, lencol := matchingDimensions(uTransitions, vTransitions, n)

	log.Printf("row and column length are: %v and %v", lenrow, lencol)

	rowindex := make([]int, lenrow, lenrow)
	colindex := make([]int, lencol, lencol)

	// finds the row and column indexs for the u and v matching
	setMatchingIndexes(uTransitions, vTransitions, n, rowindex, colindex)

	log.Printf("row index: %s", rowindex)
	log.Printf("column index: %s", colindex)

	matching := make([][]*coupling.Edge, lenrow, lenrow)

	for i := range matching {
		matching[i] = make([]*coupling.Edge, lencol, lencol)
	}

	// fills out the matching with node pointers, using nodes already in the coupling c if they exist
	filloutAdj(rowindex, colindex, lenrow, lencol, matching, c)

	// completes the matching by inserting probabilities and setting appropriate cells to basic
	i, j := 0, 0
	for i < lenrow && j < lencol {
		if utils.ApproxEqual(uTransitions[rowindex[i]], vTransitions[colindex[j]]) {
			matching[i][j].Prob = uTransitions[rowindex[i]]

			// check if we are in the lower right corner, such that we do not get an out of bounds error
			if !(i+1 == lenrow && j+1 == lencol) {
				matching[i][j+1].Basic = true
				node.BasicCount++
			}

			matching[i][j].Basic = true
			matching[i][j].To.Succ = append(matching[i][j].To.Succ, node)
			node.BasicCount++

			i++
			j++
		} else if uTransitions[rowindex[i]] < vTransitions[colindex[j]] {
			matching[i][j].Prob = uTransitions[rowindex[i]]
			vTransitions[colindex[j]] = vTransitions[colindex[j]] - uTransitions[rowindex[i]]

			matching[i][j].Basic = true
			matching[i][j].To.Succ = append(matching[i][j].To.Succ, node)
			node.BasicCount++

			i++
		} else {
			matching[i][j].Prob = vTransitions[colindex[j]]
			uTransitions[rowindex[i]] = uTransitions[rowindex[i]] - vTransitions[colindex[j]]

			matching[i][j].Basic = true
			matching[i][j].To.Succ = append(matching[i][j].To.Succ, node)
			node.BasicCount++

			j++
		}
	}

	log.Println("Logging matching:")

	for i := 0; i < lenrow; i++ {
		for j := 0; j < lencol; j++ {
			log.Printf(" - At: u %d, %d prob: %f, basic: %t",
				matching[i][j].To.S,
				matching[i][j].To.T,
				matching[i][j].Prob,
				matching[i][j].Basic)
		}
	}

	node.Adj = matching

	return node
}