Sorting two-way cell connections with priority - algorithm

I have a two dimensional grid of cells. In this simulation, cells may request to switch position with another cell. The request also has a priority.
The problem is that Im having a hard time coming up with a good way to structure this. If A wants to switch with B, and B also wants to switch with A, they currently can be switched and switched back in a single logic tick (which should be impossible).
The solution probably involves making sure (A to B)==(B to A) and insertion sorting them into a list by their priority.
Does such data structure have a name? Anyone recognise the problem and can provide some good links for reading?

I can't say that I've come across an example like this before, so I don't know what it would be called, but perhaps something like this would work...
Cell - a class or struct
CellId
XCoordinate
YCoordinate
SwitchRequest - a class or struct
RequestingCell
TargetCell
Priority
CanSwitch
SwitchRequests - an array of SwitchRequests
AlreadySwitchedCells - an array of Cells
Algorithm
For each tick:
clear AlreadySwitchedCells
build list of SwitchRequests
sort SwitchRequests by Priority (highest to lowest)
loop through each SwitchRequest
{
if (RequestingCell is not in AlreadySwitchedCells and TargetCell is not in AlreadySwitchedCells)
{
add RequestingCell and TargetCell to AlreadySwitchedCells
SwapCellIds(RequestingCell, TargetCell)
}
}
Note: There are some options here, like whether you should make the coordinates properties of a Cell or just store the CellIds in an two-dimensional array, but hopefully this gives you a starting point.

Related

How to choose best algorithm for sorting

I'm newbie here.
I am currently trying to solve the problem regarding the sorting algorithm.
I will outline the situation:
we have 60 items. Variables of type A and B are written to these items. Variables A and B are stored randomly. Variables A and B have another parameter X, which indicates their material. (material may change during storage). Items are then taken one by one to another item with 10 elements, where we try to achieve the storage of 2 or 3 of the same types of variables A or B from the same material on one element. After saving the required number of variables with the same properties, they are subsequently removed from this item.
I tried to describe it as simply as possible, but maybe I should have described it with a real example.
It can be imagined as a warehouse that has 10 elements and takes from a conveyor that has a capacity of 60 elements. As soon as the warehouse has the same type of goods of the same material on one element, it dispatches the goods and releases its position.
So I want to remove the elements from the conveyor as efficiently as possible and sort them in stock according to requirements.
It occurred to me to sort by case for all options.
Thank you for all your ideas and comments. If it's not very clear, then I apologize and try to explain it differently. :)

Sorting application difficulty

Currently I am reading a book on algorithms and found this usage of sorting.
Reconstructing the original order - How can we restore the original arrangment of a set of items after we permute them for some application? Add an extra field to the data record for the item, such that i-th record sets this field to i. Carry this field along whenever you move the record, and later sort on it when you want the initial order back.
I ve been trying hard to understand what does it mean. And I failed miserably. Pls somebody help?
Suppose you have list of items in random order:
itemC, itemB, itemA, itemD
you sorted them up:
itemA, itemB, itemC, itemD
and you didn't have enough memory to store them in a separate location, so original sequence is lost. Moreover, original order is random and it will be problematic/impossible to restore it.
This article gives a solution to this problem.
Add an extra field to the data record for the item, such that i-th record sets this field to i
So, we add an extra field for each of the items:
(itemC,1), (itemB,2), (itemA,3), (itemD, 4)
And after sort we have:
(itemA,3), (itemB,2), (itemC,1), (itemD, 4)
So we can easily restore initial order sorting by additional field
Let's say you have the data in an array, because it's the simplest structure that I can use to exemplify.
So, your node (i.e., element of the array) may look like this:
(some data type) data
The algorithm is suggesting you to add an integer field, so it looks like this:
(some data type) data,
int position
And then, you fill the positions with the actual index. Something like this pseudocode:
for current: 0 to lastElement
array[current].position = current
(that's not written in any language I know of, but it should be readable)
After doing that, you shuffle it (resort it) for whatever you need to.
When you want to restore the original ordering, all you need to do is sort by the position field.
Well, basically it's saying that you need some sort of thingy to keep track of the original order (which is destroyed by the permutation). One option would be to simply reverse the permutation (check out Steve Jessop's infrmative answer here).
Another option to invert the permutation would require fewer processing steps, but more memory. More specifically, each node in your input set would have an extra ID field, and all the elements in this input set are sorted based on this field. Once you apply the permutation, it's obvious that the IDs are no longer in a sorted order. If you wish to invert the permutation, all you have to do is sort the list again based on this field.

Search based on Second value in a map

I have a mapping of String id -> Object. Apart from merely having to insert and delete into this map, I would also need to find the id with the lowest x-value (x-value is a member in the Class from which the Object is instantiated).
Initially I thought I could just create another mapping x-value -> String id for this. But that does not help this much, because in case of Remove operation, I have to now anyway search this second map for a particular id (so we are back to the main problem itself now).
Any suggestions to do this efficiently? (time wise - memory is not a big constraint)
EDIT: I think I could just get the x-value from the id (for removal function) and remove from second map using the x-value. Another thing here - the x-value is a float. Good idea to use float as a key in a map ?? Maybe using fabs and a precision value could do the trick here for floating point comparisons ?
EDIT #2: Unfortunately I remembered why the above method might not work (I was busy with other stuff and forgot about this project for a while). The x-value for different map entries NEED NOT BE UNIQUE. String ID is the primary key. So I need to use a multimap and use equal_range.
Your solution of using an auxiliary map isn't as bad as your post suggests.
It is true that a removal operation would require a lookup in the second map. However, this lookup can be done in O(log n) time. This is unlikely to be a deal breaker. If it is, please post more details.
How often do you remove objects? Usually in cases like that you have to think about the frequency of operations too. If the Removing is done infrequently than your solution with the second map could be quite good.
If you use tree map for the second mapping, you will immediatelly have minimum element and it will take O(log n) to remove element from it.
One other alternative is to use priority queue backed by double linked list to find minimal element and in first map remember direct reference to the node of the element. This node can be used for removal.

Do I need to implement a b-tree search for this?

I have an array of integers, which could run into the hundreds of thousands (or more), sorted numerically ascending since that's how they were originally stacked.
I need to be able to query the array to get the index of its first occurrence of a number >= some input, as efficiently as possible. The only way I would know how to do this without even thinking about it would be to iterate through the array testing the condition until it returns true, at which point I'd stop iterating. However, this is the most expensive solution to this problem and I'm looking for the best algorithm to solve it.
I'm coding in Objective-C, but I'll give an example in JavaScript to broaden the audience of people who are able to respond.
// Sample set
var numbers = [1, 7, 23, 23, 23, 89, 1002, 1003];
var indexAfter100 = getIndexOfValueGreaterThan(100);
var indexAfter7 = getIndexOfValueGreaterThan(7);
// (indexAfter100 == 6) == true
// (indexAfter7 == 2) == true
Putting this data into a DB in order to perform this search will only be a last-resort solution since I'm keen to see some sort of algorithm to tackle this quickly in memory.
I do have the ability to change the data structure, or to store an additional data structure as I'm building the array, since my program has already pushed each number one by one onto this stack, so I'd just modify the code that's adding them to the stack. Searching for the index as they're being added to the stack isn't possible since the search operation will be repeated frequently with different values after the fact.
Right now I'm thinking "B-Tree" but to be honest, I would have no idea how to implement one and before I go off and start figuring that out, I wonder if there's a nice algorithm that fits this single use-case better?
You should use binary search. Objective C could even have a built-in method for that (many languages I know do). B-tree won't probably help much, unless you want to store the data on disk.
I don't know about Objective-C, but C (plain 'ol C) comes with a function called bsearch (besides, AFAIK, Obj-C can call C functions just fine):
http://www.cplusplus.com/reference/clibrary/cstdlib/bsearch/
That basically does a binary search which sounds like it's what you need.
A fast search algorithm should be able to handle an array of ints of that size without taking too long, I should think (and the array is sorted, so a binary search would probably be the way to go).
I think a btree is probably overkill...
Since they are sorted in a particular ASCending order and you only need the bigger ones, I would serialize that array, explode it by the INT and keep the part of the serialized string that holds the bigger INTs, then unserialize it and voilá.
Linear search also referred to as sequential search looks at each element in sequence from the start to see if the desired element is present in the data structure. When the amount of data is small, this search is fast.Its easy but work needed is in proportion to the amount of data to be searched.Doubling the number of elements will double the time to search if the desired element is not present.
Binary search is efficient for larger array. In this we check the middle element.If the value is bigger that what we are looking for, then look in the first half;otherwise,look in the second half. Repeat this until the desired item is found. The table must be sorted for binary search. It eliminates half the data at each iteration.Its logarithmic

Data filtering or better LINQ query?

I am using the new WPF toolkit's Chart to plot large data sets. I also have a crosshair tracker that follows the mouse when it's over the chart area to tell exactly what is the value of the nearest data point (see Yahoo! Finance charts).
I use the following code to find the closest data point that is lower (or equal) to where the mouse is currently hovering (the nasty detail about the chart is that it actually interpolates the data to tell you what's the EXACT value where you hove your mouse over, even though the mouse is located between the data points):
TimeDataPoint point = mainSeries.Find(
new Predicate<TimeDataPoint>(
delegate(TimeDataPoint p) {
return xValue > p.Date && !mainSeries.Exists(new Predicate<TimeDataPoint>(
delegate(TimeDataPoint middlePoint) {
return middlePoint.Date > p.Date && xValue > middlePoint.Date;
}));
}));
[Here, mainSeries is simply a List<TimeDataPoint>]
This works very well for relatively small data sets, but once I go up to 12000+ points (this will increase rapidly), the code above slows down to a standstill (it does a run through data 12000+^2 times).
I am not very good at constructing queries so I am wondering if it is possible to use a better LINQ query to do this.
EDIT: Another idea that was inspired by #Randolpho comment is this: I will search for all points that are lower than given (this will be at most n (here: 12,000+)) and then select a Max<> (which should be also at most O(n)). This should produce the same result but only with order of n operations and thus should be at least a little bit faster...
My other alternative is to actually filter the data set and maintain an upper bound on the number of points depending on the level of details the user wants to see. I would rather not go down that road if there's a possibility of having a more efficient query.
Pre-compute the closest data points based on the known resolution of display/chart. Then, when you hover over a point, it's a simple lookup of the x/y coordinates against the known pre-computed value.
For performance reasons, do your pre-computation in a separate thread and do not allow the display of those values until the computation is completed. Re-compute every time the size of the chart is changed.
Bottom line: There is no LINQ query that will help you execute every time you do a mouse-over for large data sets. It just can't be done. You're looking at order N^2 no matter what. So pre-compute it and cache it, so you only do your computations once.
This is an intriguing idea but wouldn't I still need to do a look-up of x/y among 12000+ pairs? Could you elaborate on how I should store the pre-computed x/y pairs for a fast look-up? For example, I have data points at (200,300) and (250, 300) and user's mouse is at (225, 300). – Alexandra
Well, I guess that would depend on the graph. Based on your code and your mention of Yahoo Finance Charts, I'm assuming your data only varies by horizontal postion, i.e. for a given X value, you are computing the display data.
In that case, you can a simple Dictionary<int, TimeDataPoint> as your cache. The Key is the transformed X coordinate (i.e. in the coordinate space of your display graph), the Value is the pre-computed TimeDataPoint. The dictionary would have a record for every X coordinate in your display graph, so a 400-pixel-wide graph has 400 pre-computed data points.
If your data varies against both axes, you could instead use Dictionary<System.Windows.Point, TimeDataPoint>, in pretty much the same way, but this would increase the number of items in your Dictionary by an order of magnitude. A 400 by 300 graph would have 120000 entries in the dictionary, so the tradeoff is a higher memory footprint.
Pre-calculating your data is the tricky part; it'd have to be done differently from the way you're currently doing it. I'm going to assume here that xValue in your example is an interpolation of a Date based on the X value, since it's compared to p.Date.
This might work:
private Dictionary<int, TimeDataPoint> BuildCache(List<TimeDataPoint> mainSeries)
{
int xPrevious = 0;
int xCurrent = 0;
Dictionary<int, TimeDataPoint> cache = new Dictionary<int, TimeDataPoint>();
foreach(var p in mainSeries)
{
xCurrent = XFromDate(p.Date);
for(int val = xPrevious; val < xCurrent; val++)
{
cache.Add(val, p);
}
xPrevious = xCurrent;
}
return cache;
}
XFromDate would extract the X coordinate for a particular date. I'll leave doing that up to you. :)

Resources