Output all possible paths of a graph using GLPK - math

I am trying to use glpk to enumerate all possible paths from a source node to a target node, but i am having some problems with the syntax. Here's my current code (adapted from the shortest path example):
param n, integer, > 0;
/* number of nodes */
set E, within {i in 0..n, j in 0..n};
/* set of edges */
param s, in {0..n};
/* source node */
param t, in {0..n};
/* target node */
var x{(i,j) in E}, >= 0;
/* x[i,j] = 1 means that edge (i,j) belong to shortest path;
x[i,j] = 0 means that edge (i,j) does not belong to shortest path;
note that variables x[i,j] are binary, however, there is no need to
declare them so due to the totally unimodular constraint matrix */
s.t. r{i in 1..n}: sum{(j,i) in E} x[j,i] + (if i = s then 1) =
sum{(i,j) in E} x[i,j] + (if i = t then 1);
/* conservation conditions for unity flow from s to t; every feasible
solution is a path from s to t */
var test, integer, =0;
minimize Z: sum{(i,j) in E} x[i,j];
/* objective function is the path length to be minimized */
solve;
for {(i,j) in E: x[i,j]>0}{
printf "%d --> %d ", i, j;
}
#printf " tamanho do caminho %d ", count;

Related

Understanding Bezier derivation code that leads nowhere

I'm trying to convert Bezier.js implementation of calculating normals to a Shadertoy program, and the code appears to not use any of the calculated values. It needs to be for quadratic rationals as well.
I found the Javascript code a slight bit hard to follow, so I simplified it for my Shadertoy program:
vec2[3] derive(vec2[3] p)
{
vec2[3] dpoints;
int l_length = 0, j;
for (int i = 2; i > 0; --i) {
vec2[3] l;
for (j = 0; j < i; j++) {
vec2 dpt = vec2(
float(i) * (p[j + 1].x - p[j].x),
float(i) * (p[j + 1].y - p[j].y));
dpoints[l_length] = dpt;
l[l_length] = dpt; ++l_length;
}
p = l;
}
return dpoints;
}
The Bezier.js program continues to add functionality for 3d beziers, in case that has anything to do with rational beziers.
I need to make sense of the rest of the program, since I don't know the theory for calculating the normals.
To spell Pomax's answer out loud:
Only the last calculated value is used, to make a "curve" (line) from origin.
The weights are calculated as w'0 = 2(w1-w0), w'1 = 2(w2-w1).
The resulting bezier at t gives the tangent of the original bezier at t.
I hope I got this right I haven't tried this yet.

Finding the minimum set of coins that make a given value

I've been trying to figure out if there would be a way to get the optimal minimum set of coins that would be used to make the change.
The greedy algorithm approach for this has an issue such as if we have the set of coins {1, 5, 6, 9} and we wanted to get the value 11. The greedy algorithm would give us {9,1,1} however the most optimal solution would be {5, 6}
From reading through this site I've found that this method can give us the total minimum number of coins needed. Would there be a way to get the set of coins from that as well?
I'm assuming you already know the Dynamic Programming method to find only the minimum number of coins needed. Let's say that you want to find the minimum number of coins to create a total value K. Then, your code could be
vector <int> min_coins(K + 1);
min_coins[0] = 0; // base case
for(int k = 1; k <= K; ++k) {
min_coins[k] = INF;
for(int c : coins) { // coins[] contains all values of coins
if(k - c >= 0) {
min_coins[k] = min(min_coins[k], min_coins[k - c] + 1);
}
}
}
Answer to your question: In order to find the actual set of coins that is minimal in size, we can simply keep another array last_coin[] where last_coin[k] is equal to the coin that was last added to the optimal set of coins for a sum of k. To illustrate this:
vector <int> min_coins(K + 1), last_coin(K + 1);
min_coins[0] = 0; // base case
for(int k = 1; k <= K; ++k) {
min_coins[k] = INF;
for(int c : coins) {
if(k - c >= 0) {
if(min_coins[k - c] + 1 < min_coins[k]) {
min_coins[k] = min_coins[k - c] + 1;
last_coin[k] = c; // !!!
}
}
}
}
How does this let you find the set of coins? Let's say we wanted to find the best set of coins that sum to K. Then, we know that last_coin[K] holds one of the coins in the set, so we can add last_coin[K] to the set. After that, we subtract last_coin[K] from K and repeat until K = 0. Clearly, this will construct a (not necessarily the) min-size set of coins that sums to K.
Possible implementation:
int value_left = K;
while(value_left > 0) {
last_coin[value_left] is added to the set
value_left -= last_coin[value_left]
}

Finding the center of the diameter of a graphtree using BFS?

So this function, biggest_dist, finds the diameter of a graph(the given graph in the task is always a tree).
What I want it instead to find is to find the center of the diameter, the node with the least maximum distance to all the other nodes.
I "kinda" understand the idea that we can do this by finding the path from u to t (distance between uand tis the diameter) by keeping track of the parent for each node. From there I choose the node in the middle of uand t? My question is how do I implement that for this function here? Will this make it output node 2 for this graph?
int biggest_dist(int n, int v, const vector< vector<int> >& graph)
//n are amount of nodes, v is an arbitrary vertex
{ //This function finds the diameter of thegraph
int INF = 2 * graph.size(); // Bigger than any other length
vector<int> dist(n, INF);
dist[v] = 0;
queue<int> next;
next.push(v);
int bdist = 0; //biggest distance
while (!next.empty()) {
int pos = next.front();
next.pop();
bdist = dist[pos];
for (int i = 0; i < graph[pos].size(); ++i) {
int nghbr = graph[pos][i];
if (dist[nghbr] > dist[pos] + 1) {
dist[nghbr] = dist[pos] + 1;
next.push(nghbr);
}
}
}
return bdist;
}
As a matter of fact, this function does not compute the diameter. It computes the furthest vertex from a given vertex v.
To compute the diameter of a tree, you need first to choose an arbitrary vertex (let's say v), then find the vertex that is furthest away from v (let's say w), and then find a vertex that is furthest away from w, let's sat u. The distance between w and u is the diameter of the tree, but the distance between v and w (what your function is doing) is not guaranteed to be the diameter.
To make your function compute the diameter, you will need to make it return the vertex it found alongside with the distance. Conveniently, it will always be the last element you process, so just make your function remember the last element it processed alongside with the distance to that element, and return them both. Then call your function twice, first from any arbitrary vertex, then from the vertex that the first call returned.
To make it actually find the center, you can also remember the parent for each node during your BFS. To do so, allocate an extra array, say prev, and when you do
dist[nghbr] = dist[pos] + 1;
also do
prev[nghbr] = pos;
Then at the end of the second call to the function, you can just descend bdist/2 times into the prev, something like:
center = lastVertex;
for (int i = 0; i + i < bdist; ++ i) center = prev[center];
So with a little tweaks to your function (making it return the furthest vertex from v and a vertex that is on the middle of that path, and not return the diameter at all), this code is likely to return you the center of the tree (I only tested it on your example, so it might have some off by one errors)
pair<int, int> biggest_dist(int n, int v, const vector< vector<int> >& graph)
{
int INF = 2 * graph.size(); // Bigger than any other length
vector<int> dist(n, INF);
vector<int> prev(n, INF);
dist[v] = 0;
queue<int> next;
next.push(v);
int bdist = 0; //biggest distance
int lastV = v;
while (!next.empty()) {
int pos = next.front();
next.pop();
bdist = dist[pos];
lastV = pos;
for (int i = 0; i < graph[pos].size(); ++i) {
int nghbr = graph[pos][i];
if (dist[nghbr] > dist[pos] + 1) {
dist[nghbr] = dist[pos] + 1;
prev[nghbr] = pos;
next.push(nghbr);
}
}
}
int center = lastV;
for (int i = 0; i + i < bdist; ++ i) center = prev[center];
return make_pair(lastV, center);
}
int getCenter(int n, const vector< vector<int> >& graph)
{
// first call is to get the vertex that is furthest away from vertex 0, where 0 is just an arbitrary vertes
pair<int, int> firstResult = biggest_dist(n, 0, graph);
// second call is to find the vertex that is furthest away from the vertex just found
pair<int, int> secondResult = biggest_dist(n, firstResult.first, graph);
return secondResult.second;
}

Find closest value in a vector with binary search

As a silly toy example, suppose
x=4.5
w=c(1,2,4,6,7)
I wonder if there is a simple R function that finds the index of the closest match to x in w. So if foo is that function, foo(w,x) would return 3. The function match is the right idea, but seems to apply only for exact matches.
Solutions here (e.g. which.min(abs(w - x)), which(abs(w-x)==min(abs(w-x))), etc.) are all O(n) instead of log(n) (I'm assuming that w is already sorted).
R>findInterval(4.5, c(1,2,4,5,6))
[1] 3
will do that with price-is-right matching (closest without going over).
You can use data.table to do a binary search:
dt = data.table(w, val = w) # you'll see why val is needed in a sec
setattr(dt, "sorted", "w") # let data.table know that w is sorted
Note that if the column w isn't already sorted, then you'll have to use setkey(dt, w) instead of setattr(.).
# binary search and "roll" to the nearest neighbour
dt[J(x), roll = "nearest"]
# w val
#1: 4.5 4
In the final expression the val column will have the you're looking for.
# or to get the index as Josh points out
# (and then you don't need the val column):
dt[J(x), .I, roll = "nearest", by = .EACHI]
# w .I
#1: 4.5 3
# or to get the index alone
dt[J(x), roll = "nearest", which = TRUE]
#[1] 3
See match.closest() from the MALDIquant package:
> library(MALDIquant)
> match.closest(x, w)
[1] 3
x = 4.5
w = c(1,2,4,6,7)
closestLoc = which(min(abs(w-x)))
closestVal = w[which(min(abs(w-x)))]
# On my phone- please pardon typos
If your vector is lengthy, try a 2-step approach:
x = 4.5
w = c(1,2,4,6,7)
sdev = sapply(w,function(v,x) abs(v-x), x = x)
closestLoc = which(min(sdev))
for maddeningly long vectors (millions of rows!, warning- this will actually be slower for data which is not very, very, very large.)
require(doMC)
registerDoMC()
closestLoc = which(min(foreach(i = w) %dopar% {
abs(i-x)
}))
This example is just to give you a basic idea of leveraging parallel processing when you have huge data. Note, I do not recommend you use it for simple & fast functions like abs().
To do this on character vectors, Martin Morgan suggested this function on R-help:
bsearch7 <-
function(val, tab, L=1L, H=length(tab))
{
b <- cbind(L=rep(L, length(val)), H=rep(H, length(val)))
i0 <- seq_along(val)
repeat {
updt <- M <- b[i0,"L"] + (b[i0,"H"] - b[i0,"L"]) %/% 2L
tabM <- tab[M]
val0 <- val[i0]
i <- tabM < val0
updt[i] <- M[i] + 1L
i <- tabM > val0
updt[i] <- M[i] - 1L
b[i0 + i * length(val)] <- updt
i0 <- which(b[i0, "H"] >= b[i0, "L"])
if (!length(i0)) break;
}
b[,"L"] - 1L
}
NearestValueSearch = function(x, w){
## A simple binary search algo
## Assume the w vector is sorted so we can use binary search
left = 1
right = length(w)
while(right - left > 1){
middle = floor((left + right) / 2)
if(x < w[middle]){
right = middle
}
else{
left = middle
}
}
if(abs(x - w[right]) < abs(x - w[left])){
return(right)
}
else{
return(left)
}
}
x = 4.5
w = c(1,2,4,6,7)
NearestValueSearch(x, w) # return 3
Based on #neal-fultz answer, here is a simple function that uses findInterval():
get_closest_index <- function(x, vec){
# vec must be sorted
iv <- findInterval(x, vec)
dist_left <- x - vec[ifelse(iv == 0, NA, iv)]
dist_right <- vec[iv + 1] - x
ifelse(! is.na(dist_left) & (is.na(dist_right) | dist_left < dist_right), iv, iv + 1)
}
values <- c(-15, -0.01, 3.1, 6, 10, 100)
grid <- c(-2, -0.1, 0.1, 3, 7)
get_closest_index(values, grid)
#> [1] 1 2 4 5 5 5
Created on 2020-05-29 by the reprex package (v0.3.0)
You can always implement custom binary search algorithm to find the closest value. Alternately, you can leverage standard implementation of libc bsearch(). You can use other binary search implementations as well, but it does not change the fact that you have to implement the comparing function carefully to find the closest element in array. The issue with standard binary search implementation is that it is meant for exact comparison. That means your improvised comparing function needs to do some kind of exactification to figure out if an element in array is close-enough. To achieve it, the comparing function needs to have awareness of other elements in the array, especially following aspects:
position of the current element (one which is being compared with the
key).
the distance with key and how it compares with neighbors (previous
or next element).
To provide this extra knowledge in comparing function, the key needs to be packaged with additional information (not just the key value). Once the comparing function have awareness on these aspects, it can figure out if the element itself is closest. When it knows that it is the closest, it returns "match".
The the following C code finds the closest value.
#include <stdio.h>
#include <stdlib.h>
struct key {
int key_val;
int *array_head;
int array_size;
};
int compar(const void *k, const void *e) {
struct key *key = (struct key*)k;
int *elem = (int*)e;
int *arr_first = key->array_head;
int *arr_last = key->array_head + key->array_size -1;
int kv = key->key_val;
int dist_left;
int dist_right;
if (kv == *elem) {
/* easy case: if both same, got to be closest */
return 0;
} else if (key->array_size == 1) {
/* easy case: only element got to be closest */
return 0;
} else if (elem == arr_first) {
/* element is the first in array */
if (kv < *elem) {
/* if keyval is less the first element then
* first elem is closest.
*/
return 0;
} else {
/* check distance between first and 2nd elem.
* if distance with first elem is smaller, it is closest.
*/
dist_left = kv - *elem;
dist_right = *(elem+1) - kv;
return (dist_left <= dist_right) ? 0:1;
}
} else if (elem == arr_last) {
/* element is the last in array */
if (kv > *elem) {
/* if keyval is larger than the last element then
* last elem is closest.
*/
return 0;
} else {
/* check distance between last and last-but-one.
* if distance with last elem is smaller, it is closest.
*/
dist_left = kv - *(elem-1);
dist_right = *elem - kv;
return (dist_right <= dist_left) ? 0:-1;
}
}
/* condition for remaining cases (other cases are handled already):
* - elem is neither first or last in the array
* - array has atleast three elements.
*/
if (kv < *elem) {
/* keyval is smaller than elem */
if (kv <= *(elem -1)) {
/* keyval is smaller than previous (of "elem") too.
* hence, elem cannot be closest.
*/
return -1;
} else {
/* check distance between elem and elem-prev.
* if distance with elem is smaller, it is closest.
*/
dist_left = kv - *(elem -1);
dist_right = *elem - kv;
return (dist_right <= dist_left) ? 0:-1;
}
}
/* remaining case: (keyval > *elem) */
if (kv >= *(elem+1)) {
/* keyval is larger than next (of "elem") too.
* hence, elem cannot be closest.
*/
return 1;
}
/* check distance between elem and elem-next.
* if distance with elem is smaller, it is closest.
*/
dist_right = *(elem+1) - kv;
dist_left = kv - *elem;
return (dist_left <= dist_right) ? 0:1;
}
int main(int argc, char **argv) {
int arr[] = {10, 20, 30, 40, 50, 60, 70};
int *found;
struct key k;
if (argc < 2) {
return 1;
}
k.key_val = atoi(argv[1]);
k.array_head = arr;
k.array_size = sizeof(arr)/sizeof(int);
found = (int*)bsearch(&k, arr, sizeof(arr)/sizeof(int), sizeof(int),
compar);
if(found) {
printf("found closest: %d\n", *found);
} else {
printf("closest not found. absurd! \n");
}
return 0;
}
Needless to say that bsearch() in above example should never fail (unless the array size is zero).
If you implement your own custom binary search, essentially you have to embed same comparing logic in the main body of binary search code (instead of having this logic in comparing function in above example).

number of k-ary tree from pre-order and post-order traversals

Suppose pre-order and post-order traversals and k are given. How many k-ary trees are there with these traversals?
An k-ary tree is a rooted tree for which each vertex has at most k children.
It depends on the particular traversal pair. For instance
pre-order: a b c
post-order: b c a
describes only one possible tree (the fewest possible, unless you include inconsistent traversal pairs). On the other hand:
pre-order: a b c
post-order: c b a
describes 2^(3-1) = 4 trees (the most possible amongst all scenarios where the traversals have 3 nodes and k can be anything), namely the 4 3-node lines.
If you want to know the number of possible binary trees having Pre-order and Post-order traversals, you should first draw one possible tree. then count the number of nodes with only one child. The total number of possible trees would be : 2^(Number of single-child nodes)
as an example:
pre: adbefgchij
post: dgfebijhca
i draw one tree that has 3 single-child nodes. So , the number of possible trees is 8.
First determine the corresponding range of sub-tree by DFS, and get the amount of sub-tree, then solve it through combination of the sub-trees.
const int maxn = 30;
int C[maxn][maxn];
char pre[maxn],post[maxn];
int n,m;
void prepare()
{
memset(C,0,sizeof(C));
for(int i=0;i<maxn;i++)
{
C[i][0] = 1;
}
for(int i=1;i<maxn;i++)
{
for(int j=1;j<=i;j++)
{
C[i][j] = C[i-1][j-1] + C[i-1][j];
}
}
return;
}
int dfs(int rs,int rt,int os,int ot)
{
if(rs == rt) return 1;
int son = 0,res = 1;
int l = rs + 1,r = os;
while(l <= rt)
{
while(r < ot)
{
if(pre[l] == post[r])
{
son++;
break;
}
r++;
}
res *= dfs(l , l + r - os , os , r);
l += r - os + 1;
rs = l - 1;
os = ++r;
}
return res * C[m][son];
}
int main()
{
prepare();
while(scanf("%d",&m) && m)
{
scanf("%s %s",pre,post);
n = strlen(pre);
printf("%d\n",dfs(0,n-1,0,n-1));
}
return 0;
}

Resources