Dynamic Programming - String, Substrings and Minimum Cost - python-3.x

Dear Computer Science experts,
I have a question regarding Dynamic Programming (DP). The problem is I am given a sentence of characters and a cost_list that contains a list of substrings of sentence with their costs, the goal is to find lowest cost. It is assumed that cost_list contains all the substrings in sentence.
For example, suppose I have the below parameters,
sentence = "xxxyyzz"
cost_list = [["x", 1], ["xx", 3], ["y", 3], ["yy", 1], ["z", 2]]
So sentence could be [xx][x][yy][z][z], so the total cost is 3 + 1 + 1 + 2 + 2 = 9
But I could also select the substrings in sentence in a different way and we have [x][x][x][yy][z][z], which gives us 1 + 1 + 1 + 1 + 2 + 2 = 8 and it is the lowest cost.
The question is to construct a Dynamic Programming algorithm find_lowest_cost(sentence, cost_list).
Below is my recursive function for this problem I created, I have tested and it is correct,
def find_lowest_cost(sentence, cost_list):
if len(sentence) == 0:
return 0
else:
result = []
possible_substrings = []
possible_costs = []
for c in cost_list:
current_substring = c[0]
current_cost = c[1]
if current_substring == sentence[0:len(current_substring)]:
possible_substrings.append(current_substring)
possible_costs.append(current_cost)
for i in range(0, len(possible_substrings)):
result.append(possible_costs[i] + find_lowest_cost(sentence[len(possible_substrings[i]):], cost_list))
return min(result)
sentence = "xxxyyzz"
cost_list = [["x", 1], ["xx", 3], ["y", 3], ["yy", 1], ["z", 2]]
print(find_lowest_cost(sentence, cost_list))
I am stuck on how to converting the Recursion to Dynamic Programming (DP).
Question 1: For DP table, my columns are the characters of sentence. How what should my rows be? My thinking is it can't be a rows of "x", "xx", "y", "yy" and "z" because how would we compare "yy" with, say only "y" in sentence?
Question 2: Suppose rows and columns are figured out, at the current cell, what should the current cell be built upon? My notion is the cell is built-upon the lowest value of previous cells, such as cell[row][col-1], cell[row-1][col] and cell[row-1][col-1]?
Thanks!

Once you are able to get the recursive solution then try to look for how many variable are getting changed. Analysing the recursive approach:
We need to find a solution like, what is the minimum cost when string is having length 1, then 2 so on... There would be repetitive calculation for substring from 0 to k th index so we need to store all calculated result into single dp so that we can give the answer of any k th index which has already calculated.
Below is my Java solution.
import java.util.HashMap;
public class MyClass {
private static Integer[] dp;
public static void main(String args[]) {
// cost_list = [["x", 1], ["xx", 3], ["y", 3], ["yy", 1], ["z", 2]]
HashMap<String, Integer> costmp = new HashMap();
costmp.put("x", 1);
costmp.put("xx", 3);
costmp.put("y", 3);
costmp.put("yy", 1);
costmp.put("z", 2);
String sentence = "xxxyyzz";
// String sentence = "xxyyzzxxxxyyyyxxxyxxyyyxxyyyzzzyyyxxxyyyyzzzyyyyxxxyyyzzzyyxxxxxxxxxxxxxxyyxyxyzzzzxxyyxx";
// String sentence = "xxxyyzzxxxxyyyyxxxyxxyyyxxyyyzzzyyyxxxyyyyzzzy";
dp = new Integer[sentence.length()+1];
int res = find_lowest_cost(sentence, costmp, 0);
System.out.println("find_lowest_cost = " + res);
}
private static int find_lowest_cost(String sentence, HashMap<String, Integer> costmp, int st)
{
if(st == sentence.length())
return 0;
int mincost = Integer.MAX_VALUE;
if(dp[st] != null)
return dp[st];
String str = new String();
for(int i = st;i < sentence.length(); i++)
{
str+=sentence.charAt(i);
if(!costmp.containsKey(str))
break;
int cost = costmp.get(str);
mincost = Math.min(mincost, cost+find_lowest_cost(sentence, costmp, i+1));
}
dp[st] = mincost;
return mincost;
}
}

Related

DP Print (not count) all possible path classic climbing stair

I came across this classic question and found may many solution to it. for loop and DP/ reclusive + memorization.
Also found a twisted version of the questions asking to print all possible path instead of counting. Wondering for the twisted version, if we have DP solution ?
Q: If there are n stairs, you can either take 1 or 2 steps at a time, how may way can you finish the stairs. we can just using fib to calculate it. What if you are ask print out all possible ways(not revision please). For example, if n = 5. we have as solution. pseudo code is welcome or any language.
[1, 1, 1, 1, 1]
[1, 1, 1, 2]
[1, 1, 2, 1]
[1, 2, 1, 1]
[1, 2, 2]
[2, 1, 1, 1]
[2, 1, 2]
[2, 2, 1]
I have divided the solution into two subsections. First one using Memoization and the second one using Recursion.
Hope it helps!
Memoization Approach: It uses an array and calculates forward the solution based on base condition. I am using an array of type string array to store all the possible paths. To add a new path we are performing cartesian using Union.
Example:
To reach 1 we have path {1}
To reach 2 we have two paths {1, 2}
To reach 3 we have three paths {1 1 1, 1 2, 2 1} which is cartesian of above two paths.
Note: I have used two arrays just to make the solution understandable. We should be good with a single array.
Demo Memoization Approach
Full Program using Memoization Approach:
namespace Solutions
{
using System;
using System.Linq;
class Program
{
static void Main()
{
// Total Number of steps in stairs
var totalNumberOfSteps = 4;
// Total Number of allowed steps
var numberOfStepsAllowed = 2;
dynamic result = ClimbSteps(numberOfStepsAllowed, totalNumberOfSteps);
Console.WriteLine(result.Mem);
Console.WriteLine(string.Join(", ", result.Print));
Console.ReadLine();
}
private static dynamic ClimbSteps(int numberOfStepsAllowed, int totalNumberOfSteps)
{
var memList = Enumerable.Repeat(0, totalNumberOfSteps + 1).ToArray();
var printList = new string[totalNumberOfSteps + 1][];
if (numberOfStepsAllowed != 0)
{
memList[0] = 0;
printList[0] = new[] { "" };
memList[1] = 1;
printList[1] = new[] { "1" };
memList[2] = 2;
printList[2] = numberOfStepsAllowed > 1 ? new[] { "1 1", "2" } : new[] { "1 1" };
for (var indexTot = 3; indexTot <= totalNumberOfSteps; indexTot++)
{
for (var indexSteps = 1; indexSteps <= numberOfStepsAllowed && indexTot - indexSteps > 0; indexSteps++)
{
var indexTotalStep = indexTot;
var indexAllowedStep = indexSteps;
memList[indexTot] += memList[indexTot - indexSteps];
var cartesianValues = (from x in printList[indexSteps] from y in printList[indexTotalStep - indexAllowedStep] select x + " " + y)
.Union(from x in printList[indexSteps] from y in printList[indexTotalStep - indexAllowedStep] select y + " " + x).Distinct();
printList[indexTot] = printList[indexTot] == null
? cartesianValues.ToArray()
: printList[indexTot].Union(cartesianValues).Distinct().ToArray();
}
}
}
return new { Mem = memList[totalNumberOfSteps], Print = printList[totalNumberOfSteps] };
}
}
}
Output:
5
1 1 1 1, 1 1 2, 1 2 1, 2 1 1, 2 2
Recursive Approach
Demo Recursive Approach
Full Program using Recursive Approach:
namespace Solutions
{
using System;
class Program
{
static void Main()
{
// Total Number of steps in stairs
var totalNumberOfSteps = 4;
// Total Number of allowed steps
var numberOfStepsAllowed = 2;
ClimbSteps(numberOfStepsAllowed, totalNumberOfSteps);
Console.ReadLine();
}
private static void ClimbSteps(int numberOfStepsAllowed, int totalNumberOfSteps)
{
// Reach from [totalNumberOfSteps - [1..numberOfStepsAllowed]]
ClimbStep(stepsAllowed: numberOfStepsAllowed, totalNumberOfSteps: totalNumberOfSteps, currentStep: 0, stepsTaken: String.Empty);
}
private static void ClimbStep(int stepsAllowed, int totalNumberOfSteps, int currentStep, string stepsTaken)
{
if (currentStep == totalNumberOfSteps)
{
Console.WriteLine(stepsTaken);
}
for (int i = 1; i <= stepsAllowed && currentStep + i <= totalNumberOfSteps; i++)
{
ClimbStep(stepsAllowed, totalNumberOfSteps, currentStep + i, stepsTaken + i + " ");
}
}
}
}
Ouput:
1 1 1 1
1 1 2
1 2 1
2 1 1
2 2

Get all possible sums from a list of numbers

Let's say I have a list of numbers: 2, 2, 5, 7
Now the result of the algorithm should contain all possible sums.
In this case: 2+2, 2+5, 5+7, 2+2+5, 2+2+5+7, 2+5+7, 5+7
I'd like to achieve this by using Dynamic Programming. I tried using a matrix but so far I have not found a way to get all the possibilities.
Based on the question, I think that the answer posted by AT-2016 is correct, and there is no solution that can exploit the concept of dynamic programming to reduce the complexity.
Here is how you can exploit dynamic programming to solve a similar question that asks to return the sum of all possible subsequence sums.
Consider the array {2, 2, 5, 7}: The different possible subsequences are:
{2},{2},{5},{7},{2,5},{2,5},{5,7},{2,5,7},{2,5,7},{2,2,5,7},{2,2},{2,7},{2,7},{2,2,7},{2,2,5}
So, the question is to find the sum of all these elements from all these subsequences. Dynamic Programming comes to the rescue!!
Arrange the subsequences based on the ending element of each subsequence:
subsequences ending with the first element: {2}
subsequences ending with the second element: {2}, {2,2}
subsequences ending with the third element: {5},{2,5},{2,5},{2,2,5}
subsequences ending with the fourth element: {7},{5,7},{2,7},{2,7},{2,2,7},{2,5,7},{2,5,7},{2,2,5,7}.
Here is the code snippet:
The array 's[]' calculates the sums for 1,2,3,4 individually, that is, s[2] calculates the sum of all subsequences ending with third element. The array 'dp[]' calculates the overall sum till now.
s[0]=array[0];
dp[0]=s[0];
k = 2;
for(int i = 1; i < n; i ++)
{
s[i] = s[i-1] + k*array[i];
dp[i] = dp[i-1] + s[i];
k = k * 2;
}
return dp[n-1];
This is done in C# and in an array to find the possible sums that I used earlier:
static void Main(string[] args)
{
//Set up array of integers
int[] items = { 2, 2, 5, 7 };
//Figure out how many bitmasks is needed
//4 bits have a maximum value of 15, so we need 15 masks.
//Calculated as: (2 ^ ItemCount) - 1
int len = items.Length;
int calcs = (int)Math.Pow(2, len) - 1;
//Create array of bitmasks. Each item in the array represents a unique combination from our items array
string[] masks = Enumerable.Range(1, calcs).Select(i => Convert.ToString(i, 2).PadLeft(len, '0')).ToArray();
//Spit out the corresponding calculation for each bitmask
foreach (string m in masks)
{
//Get the items from array that correspond to the on bits in the mask
int[] incl = items.Where((c, i) => m[i] == '1').ToArray();
//Write out the mask, calculation and resulting sum
Console.WriteLine(
"[{0}] {1} = {2}",
m,
String.Join("+", incl.Select(c => c.ToString()).ToArray()),
incl.Sum()
);
}
Console.ReadKey();
}
Possible outputs:
[0001] 7 = 7
[0010] 5 = 5
[0011] 5 + 7 = 12
[0100] 2 = 2
This is not an answer to the question because it does not demonstrate the application of dynamic programming. Rather it notes that this problem involves multisets, for which facilities are available in Sympy.
>>> from sympy.utilities.iterables import multiset_combinations
>>> numbers = [2,2,5,7]
>>> sums = [ ]
>>> for n in range(2,1+len(numbers)):
... for item in multiset_combinations([2,2,5,7],n):
... item
... added = sum(item)
... if not added in sums:
... sums.append(added)
...
[2, 2]
[2, 5]
[2, 7]
[5, 7]
[2, 2, 5]
[2, 2, 7]
[2, 5, 7]
[2, 2, 5, 7]
>>> sums.sort()
>>> sums
[4, 7, 9, 11, 12, 14, 16]
I have a solution that can print a list of all possible subset sums.
Its not dynamic programming(DP) but this solution is faster than the DP approach.
void solve(){
ll i, j, n;
cin>>n;
vector<int> arr(n);
const int maxPossibleSum=1000000;
for(i=0;i<n;i++){
cin>>arr[i];
}
bitset<maxPossibleSum> b;
b[0]=1;
for(i=0;i<n;i++){
b|=b<<arr[i];
}
for(i=0;i<maxPossibleSum;i++){
if(b[i])
cout<<i<<endl;
}
}
Input:
First line has the number of elements N in the array.
The next line contains N space-separated array elements.
4
2 2 5 7
----------
Output:
0
2
4
5
7
9
11
12
14
16
The time complexity of this solution is O(N * maxPossibleSum/32)
The space complexity of this solution is O(maxPossibleSum/8)

Incomprehensible technical interview

This was a question asked in a recent programming interview.
Given a string "str" and pair of "N" swapping indices, generate a lexicographically largest string. Swapping indices can be reused any number times.
Eg:
String = "abdc"
Indices:
(1,4)
(3,4)
Answer:
cdba, cbad, dbac,dbca
You should print only "dbca" which is lexicographically largest.
This might sound naive, but I completely fail to follow the question. Can someone please help me understand what the question means?
I think it's saying that, given the string mystring = "abdc", you are instructed to switch characters at the specified index pairs such that you produce the lexicographically "largest" string (i.e. such that if you lex-sorted all possible strings, it would end up at the last index). So you have two valid operations: (1) switch mystring[1] with mystring[4] ("abdc" --> "cbda"), and (2) switch mystring[3] with mystring[4] ("abdc" --> "abcd"). Also, you can multiply chain operations: either operation (1) followed by (2) ("abdc" --> "cbda" --> "cbad"), or vice versa ("abdc" --> "abcd" --> "dbca"), and so on and so forth ("abdc" --> "cbda" --> "cbad" --> "dbac").
Then you (reverse) lex-sort these and pop off the top index:
>>> allPermutations = ['abcd', 'cbad', 'abdc', 'cbda', 'dbca', 'dbac']
>>> lexSorted = sorted(allPermutations, reverse=True) # ['dbca', 'dbac', 'cbda', 'cbad', 'abdc', 'abcd']
>>> lexSorted.pop(0)
'dbca'
Based on the clarification by #ncemami I came up with this solution.
public static String swap(String str, Pair<Integer, Integer> p1, Pair<Integer, Integer> p2){
TreeSet<String> set = new TreeSet<>();
String s1 = swap(str, p1.getKey(), p1.getValue());
set.add(s1);
String s2 = swap(s1, p2.getKey(), p2.getValue());
set.add(s2);
String s3 = swap(str, p2.getKey(), p2.getValue());
set.add(s3);
String s4 = swap(s3, p1.getKey(), p1.getValue());
set.add(s4);
return set.last();
}
private static String swap(String str, int a, int b){
StringBuilder sb = new StringBuilder(str);
char temp1 = str.charAt(a);
char temp2 = str.charAt(b);
sb.setCharAt(a, temp2);
sb.setCharAt(b, temp1);
return sb.toString();
}
Here my Java solution:
String swapLexOrder(String str, int[][] pairs) {
Map<Integer, Set<Integer>> neighbours = new HashMap<>();
for (int[] pair : pairs) {
// It contains all the positions that are reachable from the index present in the pairs
Set<Integer> reachablePositionsL = neighbours.get(pair[0]);
Set<Integer> temp = neighbours.get(pair[1]); // We use it just to merge the two sets if present
if (reachablePositionsL == null) {
reachablePositionsL = (temp == null ? new TreeSet<>() : temp);
} else if (temp != null) {
// Changing the reference so every addition to "reachablePositionsL" will reflect on both positions
for (Integer index: temp) {
neighbours.put(index, reachablePositionsL);
}
reachablePositionsL.addAll(temp);
}
reachablePositionsL.add(pair[0]);
reachablePositionsL.add(pair[1]);
neighbours.put(pair[0], reachablePositionsL);
neighbours.put(pair[1], reachablePositionsL);
}
StringBuilder result = new StringBuilder(str);
for (Set<Integer> set : neighbours.values()) {
Iterator<Character> orderedCharacters = set.stream()
.map(i -> str.charAt(i - 1))
.sorted(Comparator.reverseOrder())
.iterator();
set.forEach(i -> result.setCharAt(i - 1, orderedCharacters.next()));
}
return result.toString();
}
Here an article that explain my the problem.
String = "abcd"
co_ord = [(1,4),(3,4)]
def find_combinations(co_ord, String):
l1 = []
for tup_le in co_ord:
l1.extend(tup_le)
l1 = [x-1 for x in l1]
l1 = list(set(l1))
l2 = set(range(len(String)))-set(l1)
return l1,int(''.join(str(i) for i in l2))
def perm1(lst):
if len(lst) == 0:
return []
elif len(lst) == 1:
return [lst]
else:
l = []
for i in range(len(lst)):
x = lst[i]
xs = lst[:i] + lst[i+1:]
for p in perm1(xs):
l.append([x]+p)
return l
lx, ly = find_combinations(co_ord, String)
final = perm1(lx)
print(final)
temp = []
final_list=[]
for i in final:
for j in i:
temp.append(String[j])
final_list.append(''.join(temp))
temp=[]
final_list = [ i[:ly] + String[ly] + i[ly:] for i in final_list]
print(sorted(final_list,reverse=True)[0])

Change strings to make them equal

Referring to question HERE
We have two strings A and B with the same super set of characters. We
need to change these strings to obtain two equal strings. In each move
we can perform one of the following operations:
1- swap two consecutive characters of a string
2- swap the first and
the last characters of a string
A move can be performed on either string. What is the minimum number
of moves that we need in order to obtain two equal strings? Input
Format and Constraints: The first and the second line of the input
contains two strings A and B. It is guaranteed that the superset their
characters are equal. 1 <= length(A) = length(B) <= 2000 All the
input characters are between 'a' and 'z'
It looks like this will have to solved using dynamic programming. But I am not able to come up with equations. Some one has suggested them in answer - but it does not look all right.
dp[i][j] =
Min{
dp[i + 1][j - 1] + 1, if str1[i] = str2[j] && str1[j] = str2[i]
dp[i + 2][j] + 1, if str1[i] = str2[i + 1] && str1[i + 1] = str2[i]
dp[i][j - 2] + 1, if str1[j] = str2[j - 1] && str1[j - 1] = str2[j]
}
In short, it's
dp[i][j] = Min(dp[i + 1][j - 1], dp[i + 2][j], dp[i][j - 2]) + 1.
Here dp[i][j] means the number of minimum swaps needs to swap str1[i, j] to str2[i, j]. Here str1[i, j] means the substring of str1 starting from pos i to pos j :)
Here is an example like the one in the quesition,
str1 = "aab",
str2 = "baa"
dp[1][1] = 0 since str1[1] == str2[1];
dp[0][2] = str1[0 + 1][2 - 1] + 1 since str1[0] = str2[2] && str1[2] = str2[0].
You have two atomic operations:
swap consecutive with cost 1
swap first and last with cost 1
One interesting fact:
and 2. are the same if the strings end would be attached to the strings begin (circular string)
So we can derive a more generic operation
move a character with cost = |from - to| (across borders)
The problem rather seems not 2-dimensional to me, or yet I cannot determine the dimensions. Take this algorithm as naive approach:
private static int transform(String from, String to) {
int commonLength = to.length();
List<Solution> worklist = new ArrayList<>();
worklist.add(new Solution(0,from));
while (!worklist.isEmpty()) {
Solution item = worklist.remove(0);
if (item.remainder.length() == 0) {
return item.cost;
} else {
int toPosition = commonLength - item.remainder.length();
char expected = to.charAt(toPosition);
nextpos : for (int i = 0; i < item.remainder.length(); i++) {
if (item.remainder.charAt(i) == expected) {
Solution nextSolution = item.moveCharToBegin(i, commonLength);
for (Solution solution : worklist) {
if (solution.remainder.equals(nextSolution.remainder)) {
solution.cost = Math.min(solution.cost, nextSolution.cost);
continue nextpos;
}
}
worklist.add(nextSolution);
}
}
}
}
return Integer.MAX_VALUE;
}
private static class Solution {
public int cost;
public String remainder;
public Solution(int cost, String remainder) {
this.cost = cost;
this.remainder = remainder;
}
public Solution moveCharToBegin(int i, int length) {
int costOffset = Math.min(i, length - i); //minimum of forward and backward circular move
String newRemainder = remainder.substring(0, i) + remainder.substring(i + 1);
return new Solution(cost + costOffset, newRemainder);
}
}

combinatorics for programmers?

I started writing a C# Silverlight program to try and find brute force solutions to the travelling sales man problems. But got stuck on trying to figure out all the possible routes.
For my program I am generating random dots and trying to find the shortest line that can join them all, without visiting any twice.
so if I have three dots A,B, & C I would want to find all the different combinations of A,B, & C, where each is only used once and the set is not the same as another set already found when reversed.
eg:
ABC
ACB
BAC
But how can I compute all the combinations for any number of dots?
I was writing this program for fun and I am now more interested in finding a good resource for learning about how to solve combinatorial problems in programming. Everything I have found for learning combinatorics tells me how to find to number of possible combinations and is useless for actually enumerating all the possible combinations.
If you're getting intertested in this sort of thing, i recommend you try out some of the problems on project euler, e.g. http://projecteuler.net/problem=15
In pythons itertools module it has some examples with example code.
You could convert the sample code to the programming language of your choice.
http://docs.python.org/library/itertools.html
sample functions:
product('ABCD', repeat=2) AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
permutations('ABCD', 2) AB AC AD BA BC BD CA CB CD DA DB DC
combinations('ABCD', 2) AB AC AD BC BD CD
combinations_with_replacement('ABCD', 2) AA AB AC AD BB BC BD CC CD DD
sample code:
def combinations(iterable, r):
# combinations('ABCD', 2) --> AB AC AD BC BD CD
# combinations(range(4), 3) --> 012 013 023 123
pool = tuple(iterable)
n = len(pool)
if r > n:
return
indices = range(r)
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
if indices[i] != i + n - r:
break
else:
return
indices[i] += 1
for j in range(i+1, r):
indices[j] = indices[j-1] + 1
yield tuple(pool[i] for i in indices)
Note that in your above problem, if you are allowing one to go from point x1,y1 to point x2,y2 in straight line distance, then it isn't the same problem. (as you can sort the points and put them into a spatial datastructure). I Think in the traveling salesman problem, you're supposed to have "windy/hilly roads" so that even if two points are close together in terms of x and y, they may have a large weighted edge connecting them.
Here's my C# class to find permutations or combinations:
public static class IEnumerableExtensions
{
public static IEnumerable<IEnumerable<T>> Arrange<T>(this IEnumerable<T> elements,
int places, bool allowRepeats = true, bool orderMatters = true)
{
return orderMatters ?
Permutate(elements, places, allowRepeats) :
Combine(elements, places, allowRepeats);
}
public static IEnumerable<IEnumerable<T>> Permutate<T>(this IEnumerable<T> elements, int places, bool allowRepeats = false)
{
foreach (var cur in elements)
{
if (places == 1) yield return cur.Yield();
else
{
var sub = allowRepeats ? elements : elements.Where(v => !v.Equals(cur));
foreach (var res in sub.Permutate(places - 1, allowRepeats))
{
yield return res.Prepend(cur);
}
}
}
}
public static IEnumerable<IEnumerable<T>> Combine<T>(this IEnumerable<T> elements, int places, bool allowRepeats = false)
{
int i = 0;
foreach (var cur in elements)
{
if (places == 1) yield return cur.Yield();
else
{
var sub = allowRepeats ? elements.Skip(i++) : elements.Skip(i++ + 1);
foreach (var res in sub.Combine(places - 1, allowRepeats))
{
yield return res.Prepend(cur);
}
}
}
}
public static IEnumerable<T> Yield<T>(this T item)
{
yield return item;
}
static IEnumerable<T> Prepend<T>(this IEnumerable<T> rest, T first)
{
yield return first;
foreach (var item in rest)
yield return item;
}
}
Usage:
var places = new char[] { 'A', 'B', 'C' };
var routes = places.Permutate(3).ToArray();
//to remove reverse routes:
var noRev = (from r1 in routes
from r2 in routes
where r1.SequenceEqual(r2.Reverse())
select (r1.First() < r2.First() ? r1 : r2)).Distinct();
Here is a solution in Python. The first function is a recursive function that generates all permutations P(n,n) of the same length n as the input list. The second function runs the first one and filters out any permutation whose reverse already exists.
def all_perms(elements):
"""
Recursive function to generate all permutations
:param elements: a list
"""
if len(elements) <=1:
yield elements
else:
for perm in all_perms(elements[1:]):
for i in range(len(elements)):
yield perm[:i] + elements[0:1] + perm[i:]
def filtered_perms(elements):
"""
Filters out any permutation whose reverse already exists
:param elements: a list
"""
result = []
for perm in all_perms(elements):
if list(reversed(perm)) not in result:
result.append(perm)
print(result)
filtered_perms(["A", "B", "C"])
#[['A', 'B', 'C'], ['B', 'A', 'C'], ['B', 'C', 'A']]

Resources