在数组中重新编号元素的有效方法(Efficient way of re-numbering elements in an array)

我是python的新手,我正在尝试实现遗传算法,但需要一些操作代码的帮助。

我用这种方式制定了问题:

  • 每个个体I都用一串M整数表示
  • I每个元素e取0到N的值
  • 0 - N每个数字必须至少出现在I中一次
  • e的值并不重要,只要每个唯一值元素具有相同的唯一值(将它们视为类标签)
  • e小于或等于N
  • 每个I N可以不同

在应用交叉操作后,我可能会生成违反这些约束中的一个或多个的子项,因此我需要找到一种方法来重新对元素进行编号,以便它们保留其属性,但符合约束条件。

例如:

parent_1 (N=5): [1 3 5 4 2 1|0 0 5 2]
parent_2 (N=3): [2 0 1 3 0 1|0 2 1 3]

*** crossover applied at "|" ***

child_1: [1 3 5 4 2 1 0 2 1 3]
child_2: [2 0 1 3 0 1 0 0 5 2]

child_1显然仍然满足所有约束,因为N = 5并且所有值0-5在数组中至少出现一次。

问题在于子2 - 如果我们使用max(child_2)计算N的方法,我们得到值5,但如果我们计算唯一值的数量,那么N = 4,这是N的值应该是什么。 我所要求的(以非常漫长的方式,被授予)是一个好的,pythonic方式这样做:

child_2: [2 0 1 3 0 1 0 0 5 2]
*** some python magic ***
child_2':  [2 0 1 3 0 1 0 0 4 2]
*or*
child_2'': [0 1 2 3 1 2 1 1 4 0]

child_2''用于说明值本身并不重要,只要唯一值的每个元素映射到相同的值,就会满足约束。

这是我到目前为止所尝试的:

value_map = []
for el in child:
    if el not in value_map:
        value_map.append(el)

for ii in range(0,len(child)):
    child[ii] = value_map.index(child[ii])

这种方法可以工作并返回类似于child_2''的结果,但我无法想象它在字符串上迭代两次的方式非常有效,所以我想知道是否有人对如何使其更好有任何建议。

谢谢,对于这么简单的问题这么长的帖子感到抱歉!


I am reasonably new to python and am trying to implement a genetic algorithm, but need some assistance with the code for one of the operations.

I have formulated the problem this way:

  • each individual I is represented by a string of M integers
  • each element e in I takes a value from 0 to N
  • every number from 0 - N must appear in I at least once
  • the value of e is not important, so long as each uniquely valued element takes the same unique value (think of them as class labels)
  • e is less than or equal to N
  • N can be different for each I

after applying the crossover operation i can potentially generate children which violate one or more of these constraints, so i need to find a way to re-number the elements so that they retain their properties, but fit with the constraints.

for example:

parent_1 (N=5): [1 3 5 4 2 1|0 0 5 2]
parent_2 (N=3): [2 0 1 3 0 1|0 2 1 3]

*** crossover applied at "|" ***

child_1: [1 3 5 4 2 1 0 2 1 3]
child_2: [2 0 1 3 0 1 0 0 5 2]

child_1 obviously still satisfies all of the constraints, as N = 5 and all values 0-5 appear at least once in the array.

The problem lies with child 2 - if we use the max(child_2) way of calculating N we get a value of 5, but if we count the number of unique values then N = 4, which is what the value for N should be. What I am asking (in a very long winded way, granted) is what is a good, pythonic way of doing this:

child_2: [2 0 1 3 0 1 0 0 5 2]
*** some python magic ***
child_2':  [2 0 1 3 0 1 0 0 4 2]
*or*
child_2'': [0 1 2 3 1 2 1 1 4 0]

child_2'' is there to illustrate that the values themselves dont matter, so long as each element of a unique value maps to the same value, the constraints are satisfied.

here is what i have tried so far:

value_map = []
for el in child:
    if el not in value_map:
        value_map.append(el)

for ii in range(0,len(child)):
    child[ii] = value_map.index(child[ii])

this approach works and returns a result similar to child_2'', but i can't imagine that it is very efficient in the way it iterates over the string twice, so i was wondering if anyone has any suggestions of how to make it better.

thanks, and sorry for such a long post for such a simple question!

2023-03-27 21:03

满意答案

您需要多次迭代列表,我认为没有办法解决这个问题。 毕竟,在开始更改元素(第二遍)之前,首先必须确定不同元素的数量(第一遍)。 但是请注意,由于对index的重复调用而not in列表中具有O(n),因此可能具有最多O(n ^ 2)的不同元素的数量。

或者,您可以使用dict而不是value_maplist 。 字典比列表具有更快的查找速度,因此,复杂性应该确实在O(n)的数量级上。 您可以使用(1)字典理解来确定旧值到新值的映射,以及(2)用于创建更新子项的列表理解。

value_map = {el: i for i, el in enumerate(set(child))}
child2 = [value_map[el] for el in child]

或者使用for循环就地更改孩子。

for i, el in enumerate(child):
    child[i] = value_map[el]

You will need to iterates the list more than once, I don't think there's any way around this. After all, you first have to determine the number of different elements (first pass) before you can start changing elements (second pass). Note, however, that depending on the number of different elements you might have up to O(n^2) due to the repetitive calls to index and not in, which have O(n) on a list.

Alternatively, you could use a dict instead of a list for your value_map. A dictionary has much faster lookup than a list, so this way, the complexity should indeed be on the order of O(n). You can do this using (1) a dictionary comprehension to determine the mapping of old to new values, and (2) a list comprehension for creating the updated child.

value_map = {el: i for i, el in enumerate(set(child))}
child2 = [value_map[el] for el in child]

Or change the child in-place using a for loop.

for i, el in enumerate(child):
    child[i] = value_map[el]

相关问答

更多

消除大型数组中某些元素的有效方法(The efficient way to eliminate some elements in a large array)

使用Array.prototype.filter()函数: var arr = [2, "da", 3, "", 'dd', 4, -4], newArr = arr.filter(function (v) { return Number(v) && isFinite(v); }); console.log(newArr); Use Array.prototype.filter() function: var arr = [2, "da", 3, "",...

将数组中的元素插入现有Html元素的有效方法是什么?(What's the efficient way to insert elements from array to existing Html element?)

您也可以使用一次追加所有文档片段 var fragment = document.createDocumentFragment(); fragment.appendChild(...) fragment.appendChild(...) ... element.appendChild(fragment) You can also use document fragment which appends all at one moment var fragment = doc...

是否有一种有效且安全的方法来反转数组中的所有元素?(Is there an efficient and secure way to reverse all elements in an array?)

int Array[100]; unsigned int i, j; for (i=0, j=100-1; i<j; i++, j--) { int t; t = Array[j]; Array[j] = Array[i]; Array[i] = t; } int Array[100]; unsigned int i, j; for (i=0, j=100-1; i<j; i++, j--) { int t; t = Array[j]; Array[...

从阵列中删除元素的最有效方法,然后减小数组的大小(Most efficient way to remove an element from an array, then reduce the size of the array)

public NumberTile[] removeAndTrim(NumberTile[] a, int index){ NumberTile[] result = new NumberTile[a.length-1]; for (int i = 0; i < result.length; i++){ result[i] = a[((i < index) ? i : i + 1)]; } return result; } 最有效的方法是一个循环/遍...

编号数组元素 - Bash脚本(Numbering Array Elements - Bash Scripting)

从数组c开始,这里有三种方法: 用cat -n cat实用程序将编号输出行: $ cat -n < <(printf "%s\n" "${c[@]}") 1 aaa 2 filename2 3 bbb 4 asdf 使用bash 此方法使用shell算法对行进行编号: $ count=0; for f in "${c[@]}"; do echo "$((++count)). $f"; done 1. aaa 2. filename2 3. bbb...

检查数组中元素是否已更改的最有效方法(Most efficient way to check if elements in an array have changed)

如果您没有绑定到一个简单的数组,您可以创建一个“MRU”结构列表,其中结构可以包含一个标志,指示该项目自上次检查后是否已更改。 每次项目更改时,设置“已更改标志”并将其移动到列表的头部。 当您需要检查更改的项目时,您将从头部遍历列表并取消设置已更改的标志,并在第一个元素处停止并且未设置其更改标志。 对不起,我错过了关于阵列只有8个字节长的部分。 有了这些信息和编辑中的新信息,我认为以前的建议并不理想。 如果数组只有8个字节长,为什么不只是缓存前一个数组的副本并将其与接收到的新数组进行比较? 以下是...

使用numpy测试来自一个数组的每个元素是否存在于另一个数组中的最有效方法(Most efficient way to test whether each element from one array exists in a another array, using numpy)

也许是np.in1d : >>> xs = np.array([45982, 124, 12, 1092, 45982, 1, 985, 299, 10092]) >>> ys = np.array([1, 12, 299]) >>> np.in1d(xs, ys) array([False, False, True, False, False, True, False, True, False], dtype=bool) maybe np.in1d: >>> xs = np.array(...

在Perl中匹配数组元素最有效的过程?(Most efficient process of matching array elements in Perl?)

性能问题的主要来源是: foreach @Array1 { ++$matched_array_count if ($_ ~~ @Array2 ); } 根据smartmatch文档 ,行为 $string ~~ @array 就好像 grep { $string ~~ $_ } @array 和 $string1 ~~ $string2 就好像 $string1 eq $string2 将这些与原始代码段放在一起,我们得到...

在数组中重新编号元素的有效方法(Efficient way of re-numbering elements in an array)

您需要多次迭代列表,我认为没有办法解决这个问题。 毕竟,在开始更改元素(第二遍)之前,首先必须确定不同元素的数量(第一遍)。 但是请注意,由于对index的重复调用而not in列表中具有O(n),因此可能具有最多O(n ^ 2)的不同元素的数量。 或者,您可以使用dict而不是value_map的list 。 字典比列表具有更快的查找速度,因此,复杂性应该确实在O(n)的数量级上。 您可以使用(1)字典理解来确定旧值到新值的映射,以及(2)用于创建更新子项的列表理解。 value_map = {...

向量中的编号元素(Numbering elements in vector)

在我看来,最简单的方法是使用std::reference_wrapper 。 代码看起来简单明了。 这是演示该方法的程序。 请享用!:) #include <iostream> #include <vector> #include <algorithm> #include <functional> int main() { std::vector<int> v = { 23, 25, 38, 28, 26, 28 }; for ( int x : v ) std::cout...

相关文章

更多

报错说找不到abbrev这个方法,但Array有这个方法的吧?

以下是ruby-doc.org http://www.ruby-doc.org/core/class ...

scala数组操作

定长数组 最简单的数组创建如下,记住方括号在Scala中用做泛型,相当于<>在Java中作用。 定义1 ...

Java 数组

Java 数组 数组对于每一门编辑应语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处 ...

Guava处理java byte类型工具类-Bytes类

static int indexOf(byte[] array

动态拼接JSON数组的问题

比如说var level = [[&quot;ID&quot;,&quot;NAME&quot;]]; ...

怎么把2个数组里面相同的元素组合成一个新的数组

怎么把2个数组里面相同的元素组合成一个新的数组

2014最有效的微店推广方法

  随着移动用户的增加,移动电商就成了未来一部分。现在开微店非常简单,只需要下载一个金元宝微店软件就能 ...

Guava Chars类-char类型的实用工具类

static char min(char... array)返回出现在数组最小值

Guava 处理java short实用工具类-Shorts类

static short min(short... array)返回出现在数组的最小值

关于Ibatis中的resultMap元素的问题

最近刚学Ibatis,其中有个问题没搞明白,举个例子 &lt;resultMap id=&quot; ...

最新问答

更多

绝地求生、荒野行动、香肠派对 哪个更好玩???(都是吃鸡类游戏)

PC上的绝地求生,是最早也是最火的大逃杀游戏。 荒野行动是网易抄袭蓝洞绝地求生制作的手游。相似度90%,还有他一起出的终结折2,这2款正在被蓝洞告,打官司呢。 手游上的绝地求生有2部都是蓝洞授权(收钱)给腾讯开发的正版ID手游。所以跟PC上做的一模一样,蓝洞也没话说。 加上吃鸡国服也是腾讯独家代理,所以根本没有什么可说的。只要这个类型的 过于相似的,腾讯都可以借蓝洞之手起诉。打压同行是国内BAT最爱干的事嘛! 香肠派对画风虽然不一样,但核心玩法还是跟人家正版的一样的,同样也是没有被授权的。 98

如何在jQuery集合中选择第n个jQuery对象?(How to select the nth jQuery object in a jQuery collection?)

你可以使用eq : var rootElement = $('.grid').find('.box').eq(0); rootElement.find('.a'); /* Use chaining to do more work */ You can use eq: var rootElement = $('.grid').find('.box').eq(0); rootElement.find('.a'); /* Use chaining to do more work */

ASP NET使用jQuery和AJAX上传图像(ASP NET upload image with jQuery and AJAX)

您可以自己手动设置FormData键和值。 Upload 创建FormData并设置新的键/值 $("#btnUpload").on("click", function(e) { e.preventDefault(); var file = $("#imguploader").get(0).file

SQL Server XML查询中包含名称空间的位置(SQL Server XML query with namespaces in the where exist)

您可能希望使用#temp.identXml.query而不是#temp.identXml.query 。 您可以在这里阅读更多相关信息SQL Server XML exists() 我相信你也可以像这样使用它 Select #temp.identXml.value('(/*:PersonIdentity/*:MasterIndexes/*:PersonIndex/*:SourceIndex)[1]','varchar(100)') as Ident ,#temp.identXml.value(

宁夏银川永宁县望远镇哪里有修mp5的?

胜利街有家电维修,电脑城,银川商场多得很…

我想用更新的日期标记所有更新的行(I would like to mark all updated rows with the date that they have been updated)

您可以使用更新后触发的触发器来执行此操作。 给出如下表: create table your_table (id int primary key, val int, last_update datetime) 每当您更新表中的内容时,此触发器将设置last_update值。 CREATE TRIGGER trigger_name ON your_table AFTER UPDATE AS BEGIN UPDATE your_table SET your_ta

郑州会计培训班

招生的,至于时间吗,就看你自己的时间段了,你可以致电0371-63300220.他们会帮你选择一下的。离你最近,最专业的培训班。

如何定位数组中的负数,并得到所有正数的总和?(How to target e negative number from an array, and get the sum of all positive numbers?)

只需创建一个条件来检查它是正数还是负数,然后定义一个空的数组negatives ,如果数字是负数,则将其推到负数组中,如果是正数,则将其添加到sum变量中,请查看下面的工作示例。 function SummPositive( numbers ) { var negatives = []; var sum = 0; for(var i = 0; i < numbers.length; i++) { if(numbers[i] < 0) { negati

在响应图像上叠加网格(Overlay grid on responsive image)

使用两个linear-gradient s,我们可以创建两个简单的线条,然后每隔n%重复一次background-size 。 它看起来像这样: background: linear-gradient(to bottom, #000 2px, transparent 2px), linear-gradient(to right, #000 2px, transparent 2px); background-size: 10%; 两个渐变创建两条相交的线,长度为百分比,如下所示: 使用默认的b

无法让POST在Azure网站上运行(Could not get POST to work on Azure Website)

最后我找到了答案......我不得不删除尾随的斜线! 我使用了“ https://example.com/api/messages/ ”,这将自动产生GET,无论我使用PostAsync还是PostAsJsonAsync。 使用“ https://example.com/api/messages”,GET和POST似乎都运行良好! Finally I've found the answer.... I had to remove the trailing slash! I've used "ht