I have to implement the Schulze method in SciLab. Unfortunately, I'm completely new to this tool and neither am I good at such kind of job. Could anyone advise something as to where to look for some examples and tools to do it as fast and easy as possible? The program shouldn't be extremely flexible or qualitative, it would be fine if it just worked with some hard-coded input. As I understand, the Schulze method can be implemented using graph and I've found a toolbox for SciLab. Should I use it?
Update:
Here's what I managed to come up with. The code is a total mess and I admit it since I'm really bad at working with such kind of languages. I've tested it with the example from Wikipedia, seems to work.
The code is too long so here's a pastebin
You can find a pseudo implementation on Wikipedia:
# Input: d[i,j], the number of voters who prefer candidate i to candidate j.
# Output: p[i,j], the strength of the strongest path from candidate i to candidate j.
for i from 1 to C
for j from 1 to C
if (i ≠ j) then
if (d[i,j] > d[j,i]) then
p[i,j] := d[i,j]
else
p[i,j] := 0
for i from 1 to C
for j from 1 to C
if (i ≠ j) then
for k from 1 to C
if (i ≠ k and j ≠ k) then
p[j,k] := max ( p[j,k], min ( p[j,i], p[i,k] ) )
Translating this to SciLab would require using functions, for-loops, if-else constructs, max, min.
Below I plainly translated the pseudo code into Scilab code. I haven't tested it and you'll have to find out the arguments to call it with.
function p = schulzeMethod(d, C)
// Initialize a zero matrix p of the same size as d
p = zeros(size(d))
for i = 1:C
for j = 1:C
if i ~= j then
if d(i,j) > d(j,i) then
p(i,j) = d(i,j)
else
p(i,j) = 0
end
end
end
end
for i = 1:C
for j = 1:C
if i ~= j then
for k = 1:C
if (i ~= k) & ( j ~= k) then
p(j,k) = max(p(j,k), min(p(j,i), p(i,k)))
end
end
end
end
end
endfunction
// Create some random values
C = 10
d = rand(C, C)
// Call the function above
p = schulzeMethod(d, C)
disp(p)
Good luck, hope it helps! Please give some feedback if it worked to help others.
Related
I am new to Linear Algebra and learning about triangular systems implemented in Julia lang. I have a col_bs() function I will show here that I need to do a mathematical flop count of. It doesn't have to be super technical this is for learning purposes. I tried to break the function down into it's inner i loop and outer j loop. In between is a count of each FLOP , which I assume is useless since the constants are usually dropped anyway.
I also know the answer should be N^2 since its a reversed version of the forward substitution algorithm which is N^2 flops. I tried my best to derive this N^2 count but when I tried I ended up with a weird Nj count. I will try to provide all work I have done! Thank you to anyone who helps.
function col_bs(U, b)
n = length(b)
x = copy(b)
for j = n:-1:2
if U[j,j] == 0
error("Error: Matrix U is singular.")
end
x[j] = x[j]/U[j,j]
for i=1:j-1
x[i] = x[i] - x[j] * U[i , j ]
end
end
x[1] = x[1]/U[1,1]
return x
end
1: To start 2 flops for the addition and multiplication x[i] - x[j] * U[i , j ]
The $i$ loop does: $$ \sum_{i=1}^{j-1} 2$$
2: 1 flop for the division $$ x[j] / = U[j,j] $$
3: Inside the for $j$ loop in total does: $$ 1 + \sum_{i=1}^{j-1} 2$$
4:The $j$ loop itself does:$$\sum_{j=2}^n ( 1 + \sum_{i=1}^{j-1} 2)) $$
5: Then one final flop for $$ x[1] = x[1]/U[1,1].$$
6: Finally we have
$$\\ 1 + (\sum_{j=2}^n ( 1 + \sum_{i=1}^{j-1} 2))) .$$
Which we can now break down.
If we distribute and simplify
$$\\ 1 + (\sum_{j=2}^n + \sum_{j=2}^n \sum_{i=1}^{j-1} 2) .$$
We can look at only the significant variables and ignore constants,
$$\\
\\ 1 + (n + n(j-1))
\\ n + nj - n
\\ nj
$$
Which then means that if we ignore constants the highest possibility of flops for this formula would be $n$ ( which may be a hint to whats wrong with my function since it should be $n^2$ just like the rest of our triangular systems I believe)
Reduce your code to this form:
for j = n:-1:2
...
for i = 1:j-1
... do k FLOPs
end
end
The inner loop takes k*(j-1) flops. The cost of the outer loop is thus
Since you know that j <= n, you know that this sum is less than (n-1)^2 which is enough for big O.
In fact, however, you should also be able to figure out that
I'm very new to functional programming. I'm struggling using recursion instead of for loop. Here's what I have so far.
let max_factor n =
let rec loop k =
if k >= n then []
else
begin
if k < n && n % k = 0 then
k :: loop(k+1)
end
my plan is to insert the ones into a list and then find the largest from the list. But I have a feeling I'm doing it wrong. With functional programming, is it always like "going around" or am I just a bad at this? is my approach way off? Can someone please guide me how I should approach this simple problem...
The equivalent to your java code would be
let max_factor (n : int) : int =
let rec loop i =
if i < 2 then 1
else if n mod i = 0 then i
else loop (i-1)
in loop (n / 2);; (* you don't want to start at n, which would trivially divide n *)
I'm attempting to implement Hofstadter's Q Sequence using the recursive definition:
Q(1) = 1
Q(2) = 1
Q(n) = Q(n - Q(n-2)) + Q(n - Q(n-1)) for n > 2
I get the wrong result for n > 3. Here's what I have so far:
: Q recursive
dup 3 <
if
drop 1
else
dup dup 2dup 2 - Q - Q -rot 1- Q - Q +
then ;
Try it online: http://ideone.com/PmnJRO (Edit: Now has the fixed, correct implementation)
I think it doesn't work because there are values added to the stack after each call of Q where n is greater than 2, making -rot not work as I expected.
Is there a simple adjustment to make this work? Or do I need to use a different approach, maybe using a variable for n?
OEIS: A005185
I realized my mistake. I didn't need to preserve n after calling Q, but I had used dup enough times to preserve it each call. This left n on the stack after each call, making the output incorrect. I removed one of the dup's and it works.
I have spent a lot of time to learn about implementing/visualizing dynamic programming problems using iteration but I find it very hard to understand, I can implement the same using recursion with memoization but it is slow when compared to iteration.
Can someone explain the same by a example of a hard problem or by using some basic concepts. Like the matrix chain multiplication, longest palindromic sub sequence and others. I can understand the recursion process and then memoize the overlapping sub problems for efficiency but I can't understand how to do the same using iteration.
Thanks!
Dynamic programming is all about solving the sub-problems in order to solve the bigger one. The difference between the recursive approach and the iterative approach is that the former is top-down, and the latter is bottom-up. In other words, using recursion, you start from the big problem you are trying to solve and chop it down to a bit smaller sub-problems, on which you repeat the process until you reach the sub-problem so small you can solve. This has an advantage that you only have to solve the sub-problems that are absolutely needed and using memoization to remember the results as you go. The bottom-up approach first solves all the sub-problems, using tabulation to remember the results. If we are not doing extra work of solving the sub-problems that are not needed, this is a better approach.
For a simpler example, let's look at the Fibonacci sequence. Say we'd like to compute F(101). When doing it recursively, we will start with our big problem - F(101). For that, we notice that we need to compute F(99) and F(100). Then, for F(99) we need F(97) and F(98). We continue until we reach the smallest solvable sub-problem, which is F(1), and memoize the results. When doing it iteratively, we start from the smallest sub-problem, F(1) and continue all the way up, keeping the results in a table (so essentially it's just a simple for loop from 1 to 101 in this case).
Let's take a look at the matrix chain multiplication problem, which you requested. We'll start with a naive recursive implementation, then recursive DP, and finally iterative DP. It's going to be implemented in a C/C++ soup, but you should be able to follow along even if you are not very familiar with them.
/* Solve the problem recursively (naive)
p - matrix dimensions
n - size of p
i..j - state (sub-problem): range of parenthesis */
int solve_rn(int p[], int n, int i, int j) {
// A matrix multiplied by itself needs no operations
if (i == j) return 0;
// A minimal solution for this sub-problem, we
// initialize it with the maximal possible value
int min = std::numeric_limits<int>::max();
// Recursively solve all the sub-problems
for (int k = i; k < j; ++k) {
int tmp = solve_rn(p, n, i, k) + solve_rn(p, n, k + 1, j) + p[i - 1] * p[k] * p[j];
if (tmp < min) min = tmp;
}
// Return solution for this sub-problem
return min;
}
To compute the result, we starts with the big problem:
solve_rn(p, n, 1, n - 1)
The key of DP is to remember all the solutions to the sub-problems instead of forgetting them, so we don't need to recompute them. It's trivial to make a few adjustments to the above code in order to achieve that:
/* Solve the problem recursively (DP)
p - matrix dimensions
n - size of p
i..j - state (sub-problem): range of parenthesis */
int solve_r(int p[], int n, int i, int j) {
/* We need to remember the results for state i..j.
This can be done in a matrix, which we call dp,
such that dp[i][j] is the best solution for the
state i..j. We initialize everything to 0 first.
static keyword here is just a C/C++ thing for keeping
the matrix between function calls, you can also either
make it global or pass it as a parameter each time.
MAXN is here too because the array size when doing it like
this has to be a constant in C/C++. I set it to 100 here.
But you can do it some other way if you don't like it. */
static int dp[MAXN][MAXN] = {{0}};
/* A matrix multiplied by itself has 0 operations, so we
can just return 0. Also, if we already computed the result
for this state, just return that. */
if (i == j) return 0;
else if (dp[i][j] != 0) return dp[i][j];
// A minimal solution for this sub-problem, we
// initialize it with the maximal possible value
dp[i][j] = std::numeric_limits<int>::max();
// Recursively solve all the sub-problems
for (int k = i; k < j; ++k) {
int tmp = solve_r(p, n, i, k) + solve_r(p, n, k + 1, j) + p[i - 1] * p[k] * p[j];
if (tmp < dp[i][j]) dp[i][j] = tmp;
}
// Return solution for this sub-problem
return dp[i][j];;
}
We start with the big problem as well:
solve_r(p, n, 1, n - 1)
Iterative solution is only to, well, iterate all the states, instead of starting from the top:
/* Solve the problem iteratively
p - matrix dimensions
n - size of p
We don't need to pass state, because we iterate the states. */
int solve_i(int p[], int n) {
// But we do need our table, just like before
static int dp[MAXN][MAXN];
// Multiplying a matrix by itself needs no operations
for (int i = 1; i < n; ++i)
dp[i][i] = 0;
// L represents the length of the chain. We go from smallest, to
// biggest. Made L capital to distinguish letter l from number 1
for (int L = 2; L < n; ++L) {
// This double loop goes through all the states in the current
// chain length.
for (int i = 1; i <= n - L + 1; ++i) {
int j = i + L - 1;
dp[i][j] = std::numeric_limits<int>::max();
for (int k = i; k <= j - 1; ++k) {
int tmp = dp[i][k] + dp[k+1][j] + p[i-1] * p[k] * p[j];
if (tmp < dp[i][j])
dp[i][j] = tmp;
}
}
}
// Return the result of the biggest problem
return dp[1][n-1];
}
To compute the result, just call it:
solve_i(p, n)
Explanation of the loop counters in the last example:
Let's say we need to optimize the multiplication of 4 matrices: A B C D. We are doing an iterative approach, so we will first compute the chains with the length of two: (A B) C D, A (B C) D, and A B (C D). And then chains of three: (A B C) D, and A (B C D). That is what L, i and j are for.
L represents the chain length, it goes from 2 to n - 1 (n is 4 in this case, so that is 3).
i and j represent the starting and ending position of the chain. In case L = 2, i goes from 1 to 3, and j goes from 2 to 4:
(A B) C D A (B C) D A B (C D)
^ ^ ^ ^ ^ ^
i j i j i j
In case L = 3, i goes from 1 to 2, and j goes from 3 to 4:
(A B C) D A (B C D)
^ ^ ^ ^
i j i j
So generally, i goes from 1 to n - L + 1, and j is i + L - 1.
Now, let's continue with the algorithm assuming that we are at the step where we have (A B C) D. We now need to take into account the sub-problems (which are already calculated): ((A B) C) D and (A (B C)) D. That is what k is for. It goes through all the positions between i and j and computes the sub problems.
I hope I helped.
The problem with recursion is the high number of stack frames that need to be pushed/popped. This can quickly become the bottle-neck.
The Fibonacci Series can be calculated with iterative DP or recursion with memoization. If we calculate F(100) in DP all we need is an array of length 100 e.g. int[100] and that's the guts of our used memory. We calculate all entries of the array pre-filling f[0] and f[1] as they are defined to be 1. and each value just depends on the previous two.
If we use a recursive solution we start at fib(100) and work down. Every method call from 100 down to 0 is pushed onto the stack, AND checked if it's memoized. These operations add up and iteration doesn't suffer from either of these. In iteration (bottom-up) we already know all of the previous answers are valid. The bigger impact is probably the stack frames; and given a larger input you may get a StackOverflowException for what was otherwise trivial with an iterative DP approach.
Cross + roads = danger ==> the answer is ==> 96233 + 62513=158746
I'm looking for a instruction to find the answer easier for another example. one of my teacher said that we can using tree to find it. but sometimes using tree to find the answer is impossible.
How do you usually find you're cryptarithmetic solution?
One simple way :
Define the variables (just for convenience) :
vars = Symbol[#] & /# ("abc" <> ToString[#] & /# Range[26]) ;
Associate a variable to each letter of the alphabet :
alphabet = Transpose[{CharacterRange["a", "z"], vars}];
Write a helper function to translate a string into an expression :
formDigits[astring_] := FromDigits[alphabet[[alphabet[[#, 2]] & /#
Position[alphabet[[All, 1]], #][[1, 1]] & /# Characters[astring], 2]]]
Example :
formDigits["cross"]
(* abc19 + 10 (abc19 + 10 (abc15 + 10 (abc18 + 10 abc3))) *)
Write the system of equations corresponding to "Cross + roads = danger" :
equation = formDigits["cross"] + formDigits["roads"] == formDigits["danger"]
Finally solve the system with the obvious additional constraints :
sol = First#FindInstance[{equation, Sequence ## Thread[Thread[0 <= vars <= 9]],
Not[Apply[And, Thread[vars == 0]]]}, alphabet[[All, 2]], Integers] ;
Check :
formDigits["cross"] /. sol
formDigits["roads"] /. sol
formDigits["danger"] /. sol
(* 78644
86614
165258 *)
This is naturally solved, in Prolog. See also Faster implementation of verbal arithmetic in Prolog :
%% unique selection from narrowing domain
selectM([A|As],S,Z):- select(A,S,S1),selectM(As,S1,Z).
selectM([],Z,Z).
%% a puzzle
cryp([[C,R,O,S,S]+[R,O,A,D,S]=[D,A,N,G,E,R]]):-
Dom=[0,1,2,3,4,5,6,7,8,9],
selectM([S],Dom,D0),
N1 is S+S, R is N1 mod 10, R=\=0,
selectM([R,D],D0,D1), D=\=0,
N2 is (N1//10)+S+D, E is N2 mod 10,
selectM([E,O,A,G],D1,D2),
N3 is (N2//10)+O+A, G is N3 mod 10,
N4 is (N3//10)+R+O, N is N4 mod 10,
selectM([N,C],D2,_), C=\=0,
N5 is (N4//10)+C+R, A is N5 mod 10,
D is N5//10.
The key to efficiency is to choose the instantiations of digits progressively, one by one, testing right away to scrap the invalid choices as soon as possible. I'm sure this can be translated to Mathematica.
The other problem like this sum is
CROSS + ROADS = DENGER
The solution for this problem is
68244 + 82714 = 150958