Modify dijkstra's algorithm with some conditions - graph

Given an undirected graph with costs on edges, find the shortest path, from given node A to B. Let's put it this way: besides the costs and edges we start at time t = 0 and for every node you are given a list with some times that you can't pass through those nodes at that times, and you can't do anything in that time you have to wait until "it passes". As the statement says, you are a prisoner and you can teleport through the cells and the teleportation time requires the cost of the edge time, and those time when you can't do anything is when a guardian is with you in the cell and they are in the cell at every timestamp given from the list, find the minimum time to escape the prison.
What I tried:
I tried to modify it like that: in the normal dijkstra you check if it's a guardian at the minimum time you find for every node, but it didn't work.. any other ideas?
int checkGuardian(int min, int ind, List *guardians)
{
for (List iter = guardians[ind]; iter; iter = iter->next)
if(min == iter->value.node)
return min + iter->value.node;
return 0;
}
void dijkstra(Graph G, int start, int end, List *guardians)
{
Multiset H = initMultiset();
int *parent = (int *)malloc(G->V * sizeof(int));
for (int i = 0; i < G->V; ++i)
{
G->distance[i] = INF;
parent[i] = -1;
}
G->distance[start] = 0;
H = insert(H, make_pair(start, 0));
while(!isEmptyMultiset(H))
{
Pair first = extractMin(H);
for (List iter = G->adjList[first.node]; iter; iter = iter->next)
if(G->distance[iter->value.node] > G->distance[first.node] + iter->value.cost
+ checkGuardian(G->distance[first.node] + iter->value.cost, iter->value.node, guardians))
{
G->distance[iter->value.node] = G->distance[first.node] + iter->value.cost
+ checkGuardian(G->distance[first.node] + iter->value.cost, iter->value.node, guardians);
H = insert(H, make_pair(iter->value.node, G->distance[iter->value.node]));
parent[iter->value.node] = first.node;
}
}
printf("%d\n", G->distance[end]);
printPath(parent, end);
printf("%d\n", end);
}
with these structures:
typedef struct graph
{
int V;
int *distance;
List *adjList;
} *Graph;
typedef struct list
{
int size;
Pair value;
struct list *tail;
struct list *next;
struct list *prev;
} *List;
typedef struct multiset
{
Pair vector[MAX];
int size;
int capacity;
} *Multiset;
typedef struct pair
{
int node, cost;
} Pair;
As an input you are given number of nodes, number of edges and start node. For the next number of edges lines you are reading and edge between 2 nodes and the cost associated with that edge, then for the next number of nodes lines you are reading a character "N" if you can't escape from that cell and "Y" if you can escape from that cell then the number of timestamps guardians are in then number of timestamps, timestamps.
For this input:
6 7 1
1 2 5
1 4 3
2 4 1
2 3 8
2 6 4
3 6 2
1 5 10
N 0
N 4 2 3 4 7
Y 0
N 3 3 6 7
N 3 10 11 12
N 3 7 8 9
I would expect this output:
12
1 4 2 6 3
But I get this output:
10
1 4 2 6 3

Related

Best way to find least standard deviation

I have a spreadsheet where I put numbers that represent number of verses on each paragraph of a book.
I manually distribute sequential paragraphs by number of verses, so in the spreadsheet I'll have something like this:
Verses Day
5 1
6 1
3 1
10 2
8 3
4 3
2 3
6 4
3 4
10 5
3 5
2 6
5 6
10 7
= 2,7080128015
By summing the total of verses for each day - in this case, 7 days - I get the standard deviation and try to reduce it for a better distribution of paragraphs.
The question is: what is the best way to find the least standard deviation?
I thought on using brute force to generate all possible combinations, but that is not a good idea if the number increases.
EDIT: The standard deviation is based on total number of verses of each day, which are identified sequentialy. Day 1 has total of 14 verses, day 2, 10 and so on.
1 14
2 10
3 14
4 9
5 13
6 7
7 10
= 2,7080128015
Since the total number of verses and the number of days is constant, you want to minimize
sum (avg verse count - verse count of day i)^2
i
avg verse count is a constant and simply the total number of verses divided by the number of days.
This problem can be solved with a dynamic program over the days. Let us build the partial solution function f(days, paragraph) that gives us the minimal sum of squares for distributing paragraphs 0 through paragraph over days days. We are interested in the last value of this function.
We can build the function incrementally. Calculating f(1, p) for any p is straight-forward since we just need to calculate the differences to the average and square. Then, for all other days, we can calculate
f(d, p) = min f(d - 1, i) + (avg verse count - sum verse count of paragraph j)^2
i<p j:i+1..p
That means, we check the solutions for one day less and fill up the current day with the paragraphs between the previous day's end paragraph and p. While we calculate this function, we keep a pointer to the chosen minimum element (as usual for a dynamic program). When we are done calculating the entire function, we just follow the pointers back to the start, which will give us the partitioning.
The algorithm has a running time of O(d * p^2), where d is the number of days and p is the number of paragraphs.
Example Code
Here is some example C# code that implements the above algorithm:
struct Entry
{
public double minCost;
public int predecessor;
}
public static void Main()
{
//input data
int[] versesPerParagraph = { 5, 6, 3, 10, 8, 4, 2, 6, 3, 10, 3, 2, 5, 10 };
int days = 7;
//calculate constants
double avgVerses = (double)versesPerParagraph.Sum() / days;
//set up DP table (f(d,p))
int paragraphs = versesPerParagraph.Length;
Entry[,] dp = new Entry[days, paragraphs];
//initialize table
int verseCount = 0;
for(int p = 0; p < paragraphs; ++p)
{
verseCount += versesPerParagraph[p];
double diff = avgVerses - verseCount;
dp[0, p].minCost = diff * diff;
dp[0, p].predecessor = -1;
}
//run dynamic program
for(int d = 1; d < days; ++d)
{
for(int p = d; p < paragraphs; ++p)
{
verseCount = 0;
dp[d, p].minCost = double.MaxValue;
for(int i = p; i >= d; --i)
{
verseCount += versesPerParagraph[i];
double diff = avgVerses - verseCount;
double cost = dp[d - 1, i - 1].minCost + diff * diff;
if(cost < dp[d, p].minCost)
{
dp[d, p].minCost = cost;
dp[d, p].predecessor = i - 1;
}
}
}
}
//reconstruct the partitioning
{
int p = paragraphs - 1;
for (int d = days - 1; d >= 0; --d)
{
int predecessor = dp[d, p].predecessor;
//calculate number of verses, just to show them
verseCount = 0;
for (int i = predecessor + 1; i <= p; ++i)
verseCount += versesPerParagraph[i];
Console.WriteLine($"Day {d} ranges from paragraph {predecessor + 1} to {p} and has {verseCount} verses.");
p = predecessor;
}
}
}
The output is:
Day 6 ranges from paragraph 13 to 13 and has 10 verses.
Day 5 ranges from paragraph 10 to 12 and has 10 verses.
Day 4 ranges from paragraph 9 to 9 and has 10 verses.
Day 3 ranges from paragraph 6 to 8 and has 11 verses.
Day 2 ranges from paragraph 4 to 5 and has 12 verses.
Day 1 ranges from paragraph 2 to 3 and has 13 verses.
Day 0 ranges from paragraph 0 to 1 and has 11 verses.
This partitioning gives a standard deviation of 1.15.

Expressing Natural Number by sum of Triangular numbers

Triangular numbers are numbers which is number of things when things can be arranged in triangular shape.
For Example, 1, 3, 6, 10, 15... are triangular numbers.
o o o o o o o o o o is shape of n=4 triangular number
what I have to do is A natural number N is given and I have to print
N expressed by sum of triangular numbers.
if N = 4
output should be
1 1 1 1
1 3
3 1
else if N = 6
output should be
1 1 1 1 1 1
1 1 1 3
1 1 3 1
1 3 1 1
3 1 1 1
3 3
6
I have searched few hours and couldn't find answers...
please help.
(I am not sure this might help, but I found that
If i say T(k) is Triangular number when n is k, then
T(k) = T(k-1) + T(k-3) + T(k-6) + .... + T(k-p) while (k-p) > 0
and p is triangular number )
Here's Code for k=-1(Read comments below)
#include <iostream>
#include <vector>
using namespace std;
long TriangleNumber(int index);
void PrintTriangles(int index);
vector<long> triangleNumList(450); //(450 power raised by 2 is about 200,000)
vector<long> storage(100001);
int main() {
int n, p;
for (int i = 0; i < 450; i++) {
triangleNumList[i] = i * (i + 1) / 2;
}
cin >> n >> p;
cout << TriangleNumber(n);
if (p == 1) {
//PrintTriangles();
}
return 0;
}
long TriangleNumber(int index) {
int iter = 1, out = 0;
if (index == 1 || index == 0) {
return 1;
}
else {
if (storage[index] != 0) {
return storage[index];
}
else {
while (triangleNumList[iter] <= index) {
storage[index] = ( storage[index] + TriangleNumber(index - triangleNumList[iter]) ) % 1000000;
iter++;
}
}
}
return storage[index];
}
void PrintTriangles(int index) {
// What Algorithm?
}
Here is some recursive Python 3.6 code that prints the sums of triangular numbers that total the inputted target. I prioritized simplicity of code in this version. You may want to add error-checking on the input value, counting the sums, storing the lists rather than just printing them, and wrapping the entire routine into a function. Setting up the list of triangular numbers could also be done in fewer lines of code.
Your code saved time but worsened memory usage by "memoizing" the triangular numbers (storing and reusing them rather than always calculating them when needed). You could do the same to the sum lists, if you like. It is also possible to make this more in the dynamic programming style: find the sum lists for n=1 then for n=2 etc. I'll leave all that to you.
""" Given a positive integer n, print all the ways n can be expressed as
the sum of triangular numbers.
"""
def print_sums_of_triangular_numbers(prefix, target):
"""Print sums totalling to target, each after printing the prefix."""
if target == 0:
print(*prefix)
return
for tri in triangle_num_list:
if tri > target:
return
print_sums_of_triangular_numbers(prefix + [tri], target - tri)
n = int(input('Value of n ? '))
# Set up list of triangular numbers not greater than n
triangle_num_list = []
index = 1
tri_sum = 1
while tri_sum <= n:
triangle_num_list.append(tri_sum)
index += 1
tri_sum += index
# Print the sums totalling to n
print_sums_of_triangular_numbers([], n)
Here are the printouts of two runs of this code:
Value of n ? 4
1 1 1 1
1 3
3 1
Value of n ? 6
1 1 1 1 1 1
1 1 1 3
1 1 3 1
1 3 1 1
3 1 1 1
3 3
6

Finding X & Y based off of Index

Good day all
I am having a math issue, it may be due to the lack of sleep but I am totally drawing a blank.
I need to find the x and y coordinates based off of the index.
So I know the width of the grid, the height and the index. But I dont know the X and Y coordinates. i need build a formula to get that data.
For example. I know the index of 9. Through a formula i need to be able to get the number 4 for X and 2 for Y
int numOfRows = 4
int numOfCols = 5
int index = 13
int X = ?
int Y = ?
//perform math magic
x = 4
y = 3
It is very simple:
public static void foo(int i) {
int x = i % 5 + 1;
int y = i / 5 + 1;
}
It gets much easier if you start counting with 0:
| 0 1 2 3 4
-----------------
0| 0 1 2 3 4
1| 5 6 7 8 9
2|10 11 12 13 14
3|...
4|
Let a be the number in the grid and numberOfCols the number of columns (5 in this example).
In that case, it's plain to see that
the row number is a / numberOfCols (without remainder) and
the column number is a modulo numberOfCols.
You can reduce your case to this case by adding 1 to the resulting row/col numbers.

Calculating possible permutations in a grid with the given length?

I have a 4x4 grid full of letters. How can I calculate all possible routes from any point to any point that consist of 2 to 10 points?
All points within a route must be connected to another point within the same route vertically, horizontally or diagonally. For example you can go from A to B, A to E and A to F but not A to C.
Each point can be used only once in a route.
Here's an example of 25 possible permutations:
+---+---+---+---+
| A | B | C | D |
+---+---+---+---+
| E | F | G | H |
+---+---+---+---+
| I | J | K | L |
+---+---+---+---+
| M | N | O | P |
+---+---+---+---+
- AB
- ABC
- ABCD
- ABCDH
- ABCDHG
- ABCDHGF
- ABCDHGFE
- ABCDHGFEI
- ABCDHGFEIJ
- AE
- AEI
- AEIM
- AEIMN
- AEIMNJ
- AEIMNJF
- AIEMNJFB
- AIEMNJFBC
- AIEMNJFBCG
- AFKP
- PONM
- FGKL
- NJFB
- MNJGD
Now I should clear the question. I'm not asking HOW to get all the permutations. I'm asking what is the total amount of the possible permutations (i.e. an integer) and how to calculate it.
As mentioned in the comments the question can be answered with basic DFS in java starting at top left at (0,0)
EDIT: I added if(count(visited)>10) return; for the constraint
static int count=0;
static int count(boolean[][] b){
int r = 0;
for(int i=0;i<b.length;i++){
for(int j=0;j<b[0].length;j++){
if(b[i][j]) r++;
}
}
return r;
}
static boolean[][] copy(boolean[][] arr){
boolean [][] r = new boolean[arr.length][];
for(int i = 0; i < arr.length; i++)
r[i] = arr[i].clone();
return r;
}
static void dfs(int i, int j,boolean[][] visited) {
visited[i][j] = true;
if(count(visited)>10) return;
count++;
for (int k=-1;k<2;k++) {
for (int l=-1;l<2;l++) {
int r = i+k;
int c = j+l;
if (r>-1 && r<visited.length && c>-1 && c<visited.length && !visited[r][c]){
dfs(r,c,copy(visited));
}
}
}
}
public static void main(String args[]) {
boolean[][] visited = {
{false, false, false, false},
{false, false, false, false},
{false, false, false, false},
{false, false, false, false}
};
// dfs(row,column,initialize all to false)
dfs(0,0,visited);
System.out.println(count-1);
}
The above script just goes through each permutation and increments count every time since this includes the starting point (for example (0,0)) i have at the bottom count-1
Output: 105837 (edited from my incorrect original 1012519)
for 2x2 starting at same place i get 15. Which you can see from running
static int count=0;
static int count(boolean[][] b){
int r = 0;
for(int i=0;i<b.length;i++){
for(int j=0;j<b[0].length;j++){
if(b[i][j]) r++;
}
}
return r;
}
static boolean[][] copy(boolean[][] arr){
boolean [][] r = new boolean[arr.length][];
for(int i = 0; i < arr.length; i++)
r[i] = arr[i].clone();
return r;
}
static void dfs(int i, int j,boolean[][] visited,String str) {
visited[i][j] = true;
if (count(visited)>10) return;
count++;
str+="("+i+","+j+")";
System.out.println(str+": "+count);
for (int k=-1;k<2;k++) {
for (int l=-1;l<2;l++) {
int r = i+k;
int c = j+l;
if (r>-1 && r<visited.length && c>-1 && c<visited.length && !visited[r][c]){
dfs(r,c,copy(visited),str);
}
}
}
}
public static void main(String args[]) {
boolean[][] visited = {
{false, false},
{false, false}
};
dfs(0,0,visited,"");
// "count-1" to account for the starting position
System.out.println(count-1);
}
Output:
(0,0): 1
(0,0)(0,1): 2
(0,0)(0,1)(1,0): 3
(0,0)(0,1)(1,0)(1,1): 4
(0,0)(0,1)(1,1): 5
(0,0)(0,1)(1,1)(1,0): 6
(0,0)(1,0): 7
(0,0)(1,0)(0,1): 8
(0,0)(1,0)(0,1)(1,1): 9
(0,0)(1,0)(1,1): 10
(0,0)(1,0)(1,1)(0,1): 11
(0,0)(1,1): 12
(0,0)(1,1)(0,1): 13
(0,0)(1,1)(0,1)(1,0): 14
(0,0)(1,1)(1,0): 15
(0,0)(1,1)(1,0)(0,1): 16
15
the same script with 4x4 instead last 6 lines of output are:
(0,0)(1,1)(2,2)(3,3)(3,2)(3,1)(3,0)(2,1)(1,2)(0,3): 105834
(0,0)(1,1)(2,2)(3,3)(3,2)(3,1)(3,0)(2,1)(1,2)(1,3): 105835
(0,0)(1,1)(2,2)(3,3)(3,2)(3,1)(3,0)(2,1)(1,2)(2,3): 105836
(0,0)(1,1)(2,2)(3,3)(3,2)(3,1)(3,0)(2,1)(2,0): 105837
(0,0)(1,1)(2,2)(3,3)(3,2)(3,1)(3,0)(2,1)(2,0)(1,0): 105838
105837
The requirements for your problem are complex enough that I doubt there is a simple mathematical calculation--at least I cannot think of one. Here is recursive Python code to find your path count.
SIDE = 4 # Length of side of grid
MAXLEN = 10 # Maximum path length allowed
SIDE2 = SIDE + 2
DIRS = ( # offsets for directions
-1 * SIDE2 - 1, # up & left
-1 * SIDE2 + 0, # up
-1 * SIDE2 + 1, # up & right
0 * SIDE2 - 1, # left
0 * SIDE2 + 1, # right
1 * SIDE2 - 1, # down & left
1 * SIDE2 + 0, # down
1 * SIDE2 + 1, # down & right
)
def countpaths(loc, pathlen):
"""Return the number of paths starting at the point indicated by
parameter loc of length at most parameter pathlen, not repeating
points or using points marked False in global variable isfree[]."""
global isfree
pathcnt = 1 # count sub-path of just this one point
if pathlen > 1:
isfree[loc] = False
for dir in DIRS:
if isfree[loc + dir]:
pathcnt += countpaths(loc + dir, pathlen - 1)
isfree[loc] = True
return pathcnt
# Init global boolean array variable to flag which points are still available
isfree = [1 <= r <= SIDE and 1 <= c <= SIDE
for r in range(SIDE2) for c in range(SIDE2)]
# Use the symmetries of the square grid to find count of paths in grid
allpathcnt = 0
for r in range(1, (SIDE + 1) // 2 + 1): # do a triangular slice of the grid
for c in range(1, r + 1):
# Find the number of similar (by symmetry) points in the grid
if 2 * r - 1 == SIDE:
if r == c:
sym = 1 # center of entire grid
else:
sym = 4 # center of column
else:
if r == c:
sym = 4 # diagonal
else:
sym = 8 # other
# Add paths starting at this kind of point removing those of length 1
allpathcnt += sym * (countpaths(r * SIDE2 + c, MAXLEN) - 1)
print('Total path count is ' + str(allpathcnt))
This code takes into account the requirement that paths have lengths between 2 and 10 by limiting the path length to 10 and removing the paths of length 1. The requirement that points are not repeated is fulfilled by using array isfree[] to note which points are still free (True) and which are already used or should not be used (False).
Python is a somewhat slow language, so I increased speed by moving some calculations out of the inner recursions. I used a surrounding border of always-False points around your 4x4 grid, removing the need for explicit bounds checking. I used a one-dimensional list rather than two-dimensional and pre-coded the offsets from each cell to neighboring cells in constant DIRS (for "directions"). I used a final optimization by not using all 16 starting points. There are 4 corner points like A, 8 side points like B, and 4 center points like F, so I just found the numbers of paths from A, B, and F and calculated what the total would be for starting at all points.
This version of my code can handle any size square grid and maximum path length. I checked my code by varying SIDE and MAXLEN separately to 1, 2, and 3, and checking the results for each point by hand.
The final answer I get is
1626144
I was interested to note that the section of code taking the most space is the part that determines the symmetries of a point in the grid. I have found other, more concise ways to do this, but they are all much less readable.

Wrong output in recursive fibonacci number program

I have written the program to print fibonacci numbers upto the limit as the user wants. I wrote that program in recursive fashion which should give the output as expected. It is giving the right output but with appended wrong values too. This happens if the user wants to print 4 or more than 4 fibonacci numbers. Also in the recursive function I have decreased the count value before passing it in the same function call. If i decrease the count value in the called function parameters then the while loop runs endlessly. When the loop finishes after some steps and the user limit input is 5 then the output is
Enter the limit number....
5
Fibonacci numbers are: 0 1 1 2 3 3 2 3 3
Finished.........
Can anyone tell me the fault in my program or the exact reason behind this output. Thanks in advance for it.
Program is as follows:
public class FibonacciNumbers
{
public static void main(String[] args)
{
int i=0, j=1;
Scanner sc = new Scanner(System.in);
System.out.println("Enter the limit number....");
int num = sc.nextInt();
System.out.print("Fibonacci numbers are: " + i + " " + j + " " );
fibonacci(num-2, i, j);
System.out.println("\nFinished.........");
}
public static void fibonacci(int count, int i, int j)
{
int sum = 0;
while(count > 0)
{
sum = i+j;
i=j;
j=sum;
System.out.print(sum + " ");
--count;
fibonacci(count, i, j);
}
}
}
You don't need both the while loop AND the recursive function calls. You have to choose between using a loop OR recursive calls.
The recursive solution:
public static void fibonacci(int count, int i, int j) {
if (count>0){
int sum = i+j;
i=j;
j=sum;
System.out.print(sum + " ");
--count;
fibonacci(count, i, j);
}
}
The solution involving a loop:
public static void fibonacci(int count, int i, int j) {
int sum = 0;
while(count > 0) {
sum = i+j;
i=j;
j=sum;
System.out.print(sum + " ");
--count;
}
}
The problem with your code
If you look closely at the following output of your code, you can see that in the beginning of the output there are the actual 7 first fibonacci numbers, and after that comes an unneeded series of the same fibonacci numbers. You printed two numbers from main, and then you expected 5 more numbers but got 31:
Enter the limit number.... 7
Fibonacci numbers are: 0 1 1 2 3 5 8 8 5 8 8 3 5 8 8 5 8 8 2 3 5 8 8 5
8 8 3 5 8 8 5 8 8
This happens because when you first call the fibonacci function with count=5, the while loop has 5 iterations, so it prints 5 fibonacci numbers and the fibonacci function is called 5 times from there with these count parameters: 4,3,2,1,0. When the fibonacci function is called with the parameter count=4, it prints 4 numbers and calls fibonacci 4 times with these parameters: 3,2,1,0 because the while loop then has 4 iterations. I drew an image of the recursive calls (I omitted the f(0) calls because they don't print anything):
If you add it all up, you can see that the program prints 31 fibonacci numbers altogether which is way too much because you wanted to print only 5! This trouble is caused by using while and recursive calls at the same time. You want the recursive behaviour to be like this instead, with no while loop:
OR you want one while loop and no recursion:

Resources